Merge pull request #1890 from node-red/repackage
Restructure Node-RED into multiple modules
4
.gitignore
vendored
@ -17,3 +17,7 @@ node_modules
|
|||||||
public
|
public
|
||||||
locales/zz-ZZ
|
locales/zz-ZZ
|
||||||
nodes/core/locales/zz-ZZ
|
nodes/core/locales/zz-ZZ
|
||||||
|
!packages/node_modules
|
||||||
|
packages/node_modules/@node-red/editor-client/public
|
||||||
|
!test/**/node_modules
|
||||||
|
docs
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
.settings
|
|
||||||
.jshintignore
|
|
||||||
.jshintrc
|
|
||||||
.project
|
|
||||||
.tern-project
|
|
||||||
.travis.yml
|
|
||||||
.git
|
|
@ -8,5 +8,3 @@ matrix:
|
|||||||
before_script:
|
before_script:
|
||||||
- npm install -g istanbul coveralls
|
- npm install -g istanbul coveralls
|
||||||
- node_js: "8"
|
- node_js: "8"
|
||||||
- node_js: "6"
|
|
||||||
- node_js: "4"
|
|
||||||
|
306
Gruntfile.js
@ -42,7 +42,7 @@ module.exports = function(grunt) {
|
|||||||
reporter: 'spec'
|
reporter: 'spec'
|
||||||
},
|
},
|
||||||
all: { src: ['test/**/*_spec.js'] },
|
all: { src: ['test/**/*_spec.js'] },
|
||||||
core: { src: ["test/_spec.js","test/red/**/*_spec.js"]},
|
core: { src: ["test/_spec.js","test/unit/**/*_spec.js"]},
|
||||||
nodes: { src: ["test/nodes/**/*_spec.js"]}
|
nodes: { src: ["test/nodes/**/*_spec.js"]}
|
||||||
},
|
},
|
||||||
webdriver: {
|
webdriver: {
|
||||||
@ -59,8 +59,8 @@ module.exports = function(grunt) {
|
|||||||
reportFormats: ['lcov','html'],
|
reportFormats: ['lcov','html'],
|
||||||
print: 'both'
|
print: 'both'
|
||||||
},
|
},
|
||||||
all: { src: ["test/_spec.js","test/red/**/*_spec.js","test/nodes/**/*_spec.js"] },
|
all: { src: ["test/unit/_spec.js","test/unit/**/*_spec.js","test/nodes/**/*_spec.js"] },
|
||||||
core: { src: ["test/_spec.js","test/red/**/*_spec.js"]},
|
core: { src: ["test/unit/_spec.js","test/unit/**/*_spec.js"]},
|
||||||
nodes: { src: ["test/nodes/**/*_spec.js"]}
|
nodes: { src: ["test/nodes/**/*_spec.js"]}
|
||||||
},
|
},
|
||||||
jshint: {
|
jshint: {
|
||||||
@ -80,16 +80,14 @@ module.exports = function(grunt) {
|
|||||||
all: [
|
all: [
|
||||||
'Gruntfile.js',
|
'Gruntfile.js',
|
||||||
'red.js',
|
'red.js',
|
||||||
'red/**/*.js',
|
'packages/**/*.js'
|
||||||
'nodes/core/*/*.js',
|
|
||||||
'editor/js/**/*.js'
|
|
||||||
],
|
],
|
||||||
core: {
|
core: {
|
||||||
files: {
|
files: {
|
||||||
src: [
|
src: [
|
||||||
'Gruntfile.js',
|
'Gruntfile.js',
|
||||||
'red.js',
|
'red.js',
|
||||||
'red/**/*.js'
|
'packages/**/*.js',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -120,81 +118,81 @@ module.exports = function(grunt) {
|
|||||||
src: [
|
src: [
|
||||||
// Ensure editor source files are concatenated in
|
// Ensure editor source files are concatenated in
|
||||||
// the right order
|
// the right order
|
||||||
"editor/js/red.js",
|
"packages/node_modules/@node-red/editor-client/src/js/red.js",
|
||||||
"editor/js/events.js",
|
"packages/node_modules/@node-red/editor-client/src/js/events.js",
|
||||||
"editor/js/i18n.js",
|
"packages/node_modules/@node-red/editor-client/src/js/i18n.js",
|
||||||
"editor/js/settings.js",
|
"packages/node_modules/@node-red/editor-client/src/js/settings.js",
|
||||||
"editor/js/user.js",
|
"packages/node_modules/@node-red/editor-client/src/js/user.js",
|
||||||
"editor/js/comms.js",
|
"packages/node_modules/@node-red/editor-client/src/js/comms.js",
|
||||||
"editor/js/text/bidi.js",
|
"packages/node_modules/@node-red/editor-client/src/js/text/bidi.js",
|
||||||
"editor/js/text/format.js",
|
"packages/node_modules/@node-red/editor-client/src/js/text/format.js",
|
||||||
"editor/js/ui/state.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/state.js",
|
||||||
"editor/js/nodes.js",
|
"packages/node_modules/@node-red/editor-client/src/js/nodes.js",
|
||||||
"editor/js/history.js",
|
"packages/node_modules/@node-red/editor-client/src/js/history.js",
|
||||||
"editor/js/validators.js",
|
"packages/node_modules/@node-red/editor-client/src/js/validators.js",
|
||||||
"editor/js/ui/utils.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/utils.js",
|
||||||
"editor/js/ui/common/editableList.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js",
|
||||||
"editor/js/ui/common/checkboxSet.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/checkboxSet.js",
|
||||||
"editor/js/ui/common/menu.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/menu.js",
|
||||||
"editor/js/ui/common/panels.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js",
|
||||||
"editor/js/ui/common/popover.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js",
|
||||||
"editor/js/ui/common/searchBox.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js",
|
||||||
"editor/js/ui/common/tabs.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js",
|
||||||
"editor/js/ui/common/stack.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js",
|
||||||
"editor/js/ui/common/typedInput.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js",
|
||||||
"editor/js/ui/actions.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/actions.js",
|
||||||
"editor/js/ui/deploy.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js",
|
||||||
"editor/js/ui/diff.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/diff.js",
|
||||||
"editor/js/ui/keyboard.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js",
|
||||||
"editor/js/ui/workspaces.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js",
|
||||||
"editor/js/ui/view.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/view.js",
|
||||||
"editor/js/ui/view-navigator.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js",
|
||||||
"editor/js/ui/sidebar.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js",
|
||||||
"editor/js/ui/palette.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/palette.js",
|
||||||
"editor/js/ui/tab-info.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js",
|
||||||
"editor/js/ui/tab-config.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js",
|
||||||
"editor/js/ui/tab-context.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js",
|
||||||
"editor/js/ui/palette-editor.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js",
|
||||||
"editor/js/ui/editor.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/editor.js",
|
||||||
"editor/js/ui/editors/*.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/editors/*.js",
|
||||||
"editor/js/ui/tray.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/tray.js",
|
||||||
"editor/js/ui/clipboard.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js",
|
||||||
"editor/js/ui/library.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/library.js",
|
||||||
"editor/js/ui/notifications.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/notifications.js",
|
||||||
"editor/js/ui/search.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/search.js",
|
||||||
"editor/js/ui/typeSearch.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js",
|
||||||
"editor/js/ui/subflow.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js",
|
||||||
"editor/js/ui/userSettings.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js",
|
||||||
"editor/js/ui/projects/projects.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js",
|
||||||
"editor/js/ui/projects/projectSettings.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js",
|
||||||
"editor/js/ui/projects/projectUserSettings.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectUserSettings.js",
|
||||||
"editor/js/ui/projects/tab-versionControl.js",
|
"packages/node_modules/@node-red/editor-client/src/js/ui/projects/tab-versionControl.js",
|
||||||
"editor/js/ui/touch/radialMenu.js"
|
"packages/node_modules/@node-red/editor-client/src/js/ui/touch/radialMenu.js"
|
||||||
],
|
],
|
||||||
dest: "public/red/red.js"
|
dest: "packages/node_modules/@node-red/editor-client/public/red/red.js"
|
||||||
},
|
},
|
||||||
vendor: {
|
vendor: {
|
||||||
files: {
|
files: {
|
||||||
"public/vendor/vendor.js": [
|
"packages/node_modules/@node-red/editor-client/public/vendor/vendor.js": [
|
||||||
"editor/vendor/jquery/js/jquery-1.11.3.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-1.11.3.min.js",
|
||||||
"editor/vendor/bootstrap/js/bootstrap.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/bootstrap/js/bootstrap.min.js",
|
||||||
"editor/vendor/jquery/js/jquery-ui-1.10.3.custom.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-ui-1.10.3.custom.min.js",
|
||||||
"editor/vendor/jquery/js/jquery.ui.touch-punch.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js",
|
||||||
"editor/vendor/marked/marked.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/marked/marked.min.js",
|
||||||
"editor/vendor/d3/d3.v3.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js",
|
||||||
"editor/vendor/i18next/i18next.min.js"
|
"packages/node_modules/@node-red/editor-client/src/vendor/i18next/i18next.min.js"
|
||||||
],
|
],
|
||||||
"public/vendor/vendor.css": [
|
"packages/node_modules/@node-red/editor-client/public/vendor/vendor.css": [
|
||||||
// TODO: resolve relative resource paths in
|
// TODO: resolve relative resource paths in
|
||||||
// bootstrap/FA/jquery
|
// bootstrap/FA/jquery
|
||||||
],
|
],
|
||||||
"public/vendor/jsonata/jsonata.min.js": [
|
"packages/node_modules/@node-red/editor-client/public/vendor/jsonata/jsonata.min.js": [
|
||||||
"node_modules/jsonata/jsonata-es5.min.js",
|
"node_modules/jsonata/jsonata-es5.min.js",
|
||||||
"editor/vendor/jsonata/formatter.js"
|
"packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js"
|
||||||
],
|
],
|
||||||
"public/vendor/ace/worker-jsonata.js": [
|
"packages/node_modules/@node-red/editor-client/public/vendor/ace/worker-jsonata.js": [
|
||||||
"node_modules/jsonata/jsonata-es5.min.js",
|
"node_modules/jsonata/jsonata-es5.min.js",
|
||||||
"editor/vendor/jsonata/worker-jsonata.js"
|
"packages/node_modules/@node-red/editor-client/src/vendor/jsonata/worker-jsonata.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,10 +200,10 @@ module.exports = function(grunt) {
|
|||||||
uglify: {
|
uglify: {
|
||||||
build: {
|
build: {
|
||||||
files: {
|
files: {
|
||||||
'public/red/red.min.js': 'public/red/red.js',
|
'packages/node_modules/@node-red/editor-client/public/red/red.min.js': 'packages/node_modules/@node-red/editor-client/public/red/red.js',
|
||||||
'public/red/main.min.js': 'public/red/main.js',
|
'packages/node_modules/@node-red/editor-client/public/red/main.min.js': 'packages/node_modules/@node-red/editor-client/public/red/main.js',
|
||||||
'public/vendor/ace/mode-jsonata.js': 'editor/vendor/jsonata/mode-jsonata.js',
|
'packages/node_modules/@node-red/editor-client/public/vendor/ace/mode-jsonata.js': 'packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js',
|
||||||
'public/vendor/ace/snippets/jsonata.js': 'editor/vendor/jsonata/snippets-jsonata.js'
|
'packages/node_modules/@node-red/editor-client/public/vendor/ace/snippets/jsonata.js': 'packages/node_modules/@node-red/editor-client/src/vendor/jsonata/snippets-jsonata.js'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -215,50 +213,50 @@ module.exports = function(grunt) {
|
|||||||
outputStyle: 'compressed'
|
outputStyle: 'compressed'
|
||||||
},
|
},
|
||||||
files: [{
|
files: [{
|
||||||
dest: 'public/red/style.min.css',
|
dest: 'packages/node_modules/@node-red/editor-client/public/red/style.min.css',
|
||||||
src: 'editor/sass/style.scss'
|
src: 'packages/node_modules/@node-red/editor-client/src/sass/style.scss'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dest: 'public/vendor/bootstrap/css/bootstrap.min.css',
|
dest: 'packages/node_modules/@node-red/editor-client/public/vendor/bootstrap/css/bootstrap.min.css',
|
||||||
src: 'editor/vendor/bootstrap/css/bootstrap.css'
|
src: 'packages/node_modules/@node-red/editor-client/src/vendor/bootstrap/css/bootstrap.css'
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
jsonlint: {
|
jsonlint: {
|
||||||
messages: {
|
messages: {
|
||||||
src: [
|
src: [
|
||||||
'nodes/core/locales/en-US/messages.json',
|
'packages/node_modules/@node-red/nodes/locales/**/*.json',
|
||||||
'red/api/locales/en-US/editor.json',
|
'packages/node_modules/@node-red/editor-api/lib/editor/locales/**/*.json',
|
||||||
'red/runtime/locales/en-US/runtime.json'
|
'packages/node_modules/@node-red/runtime/locales/**/*.json'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
keymaps: {
|
keymaps: {
|
||||||
src: [
|
src: [
|
||||||
'editor/js/keymap.json'
|
'packages/node_modules/@node-red/editor-client/src/js/keymap.json'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
attachCopyright: {
|
attachCopyright: {
|
||||||
js: {
|
js: {
|
||||||
src: [
|
src: [
|
||||||
'public/red/red.min.js',
|
'packages/node_modules/@node-red/editor-client/public/red/red.min.js',
|
||||||
'public/red/main.min.js'
|
'packages/node_modules/@node-red/editor-client/public/red/main.min.js'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
src: [
|
src: [
|
||||||
'public/red/style.min.css'
|
'packages/node_modules/@node-red/editor-client/public/red/style.min.css'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clean: {
|
clean: {
|
||||||
build: {
|
build: {
|
||||||
src: [
|
src: [
|
||||||
"public/red",
|
"packages/node_modules/@node-red/editor-client/public/red",
|
||||||
"public/index.html",
|
"packages/node_modules/@node-red/editor-client/public/index.html",
|
||||||
"public/favicon.ico",
|
"packages/node_modules/@node-red/editor-client/public/favicon.ico",
|
||||||
"public/icons",
|
"packages/node_modules/@node-red/editor-client/public/icons",
|
||||||
"public/vendor"
|
"packages/node_modules/@node-red/editor-client/public/vendor"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
release: {
|
release: {
|
||||||
@ -270,27 +268,27 @@ module.exports = function(grunt) {
|
|||||||
watch: {
|
watch: {
|
||||||
js: {
|
js: {
|
||||||
files: [
|
files: [
|
||||||
'editor/js/**/*.js'
|
'packages/node_modules/@node-red/editor-client/src/js/**/*.js'
|
||||||
],
|
],
|
||||||
tasks: ['copy:build','concat','uglify','attachCopyright:js']
|
tasks: ['copy:build','concat','uglify','attachCopyright:js']
|
||||||
},
|
},
|
||||||
sass: {
|
sass: {
|
||||||
files: [
|
files: [
|
||||||
'editor/sass/**/*.scss'
|
'packages/node_modules/@node-red/editor-client/src/sass/**/*.scss'
|
||||||
],
|
],
|
||||||
tasks: ['sass','attachCopyright:css']
|
tasks: ['sass','attachCopyright:css']
|
||||||
},
|
},
|
||||||
json: {
|
json: {
|
||||||
files: [
|
files: [
|
||||||
'nodes/core/locales/en-US/messages.json',
|
'packages/node_modules/@node-red/nodes/locales/**/*.json',
|
||||||
'red/api/locales/en-US/editor.json',
|
'packages/node_modules/@node-red/editor-api/lib/editor/locales/**/*.json',
|
||||||
'red/runtime/locales/en-US/runtime.json'
|
'packages/node_modules/@node-red/runtime/locales/**/*.json'
|
||||||
],
|
],
|
||||||
tasks: ['jsonlint:messages']
|
tasks: ['jsonlint:messages']
|
||||||
},
|
},
|
||||||
keymaps: {
|
keymaps: {
|
||||||
files: [
|
files: [
|
||||||
'editor/js/keymap.json'
|
'packages/node_modules/@node-red/editor-client/src/js/keymap.json'
|
||||||
],
|
],
|
||||||
tasks: ['jsonlint:keymaps','copy:build']
|
tasks: ['jsonlint:keymaps','copy:build']
|
||||||
},
|
},
|
||||||
@ -305,12 +303,13 @@ module.exports = function(grunt) {
|
|||||||
nodemon: {
|
nodemon: {
|
||||||
/* uses .nodemonignore */
|
/* uses .nodemonignore */
|
||||||
dev: {
|
dev: {
|
||||||
script: 'red.js',
|
script: 'packages/node_modules/node-red/red.js',
|
||||||
options: {
|
options: {
|
||||||
args: nodemonArgs,
|
args: nodemonArgs,
|
||||||
ext: 'js,html,json',
|
ext: 'js,html,json',
|
||||||
watch: [
|
watch: [
|
||||||
'red','nodes'
|
'packages/node_modules',
|
||||||
|
'!packages/node_modules/@node-red/editor-client'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,21 +328,21 @@ module.exports = function(grunt) {
|
|||||||
build: {
|
build: {
|
||||||
files:[
|
files:[
|
||||||
{
|
{
|
||||||
src: 'editor/js/main.js',
|
src: 'packages/node_modules/@node-red/editor-client/src/js/main.js',
|
||||||
dest: 'public/red/main.js'
|
dest: 'packages/node_modules/@node-red/editor-client/public/red/main.js'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
src: 'editor/js/keymap.json',
|
src: 'packages/node_modules/@node-red/editor-client/src/js/keymap.json',
|
||||||
dest: 'public/red/keymap.json'
|
dest: 'packages/node_modules/@node-red/editor-client/public/red/keymap.json'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cwd: 'editor/images',
|
cwd: 'packages/node_modules/@node-red/editor-client/src/images',
|
||||||
src: '**',
|
src: '**',
|
||||||
expand: true,
|
expand: true,
|
||||||
dest: 'public/red/images/'
|
dest: 'packages/node_modules/@node-red/editor-client/public/red/images/'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cwd: 'editor/vendor',
|
cwd: 'packages/node_modules/@node-red/editor-client/src/vendor',
|
||||||
src: [
|
src: [
|
||||||
'ace/**',
|
'ace/**',
|
||||||
//'bootstrap/css/**',
|
//'bootstrap/css/**',
|
||||||
@ -352,46 +351,25 @@ module.exports = function(grunt) {
|
|||||||
'font-awesome/**'
|
'font-awesome/**'
|
||||||
],
|
],
|
||||||
expand: true,
|
expand: true,
|
||||||
dest: 'public/vendor/'
|
dest: 'packages/node_modules/@node-red/editor-client/public/vendor/'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cwd: 'editor/icons',
|
cwd: 'packages/node_modules/@node-red/editor-client/src/icons',
|
||||||
src: '**',
|
src: '**',
|
||||||
expand: true,
|
expand: true,
|
||||||
dest: 'public/icons/'
|
dest: 'packages/node_modules/@node-red/editor-client/public/icons/'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
expand: true,
|
expand: true,
|
||||||
src: ['editor/index.html','editor/favicon.ico'],
|
src: ['packages/node_modules/@node-red/editor-client/src/index.html','packages/node_modules/@node-red/editor-client/src/favicon.ico'],
|
||||||
dest: 'public/',
|
dest: 'packages/node_modules/@node-red/editor-client/public/',
|
||||||
flatten: true
|
flatten: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
src: 'CHANGELOG.md',
|
src: 'CHANGELOG.md',
|
||||||
dest: 'public/red/about'
|
dest: 'packages/node_modules/@node-red/editor-client/public/red/about'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
release: {
|
|
||||||
files: [{
|
|
||||||
mode: true,
|
|
||||||
expand: true,
|
|
||||||
src: [
|
|
||||||
'*.md',
|
|
||||||
'LICENSE',
|
|
||||||
'package.json',
|
|
||||||
'settings.js',
|
|
||||||
'red.js',
|
|
||||||
'lib/.gitignore',
|
|
||||||
'nodes/*.demo',
|
|
||||||
'nodes/core/**',
|
|
||||||
'red/**',
|
|
||||||
'public/**',
|
|
||||||
'editor/templates/**',
|
|
||||||
'bin/**'
|
|
||||||
],
|
|
||||||
dest: path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>')
|
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
chmod: {
|
chmod: {
|
||||||
@ -400,8 +378,8 @@ module.exports = function(grunt) {
|
|||||||
},
|
},
|
||||||
release: {
|
release: {
|
||||||
src: [
|
src: [
|
||||||
path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/nodes/core/hardware/nrgpio*'),
|
"packages/node_modules/@node-red/nodes/core/hardware/nrgpio",
|
||||||
path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/red/runtime/storage/localfilesystem/projects/git/node-red-*sh')
|
"packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-*sh"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -411,8 +389,43 @@ module.exports = function(grunt) {
|
|||||||
archive: '<%= paths.dist %>/node-red-<%= pkg.version %>.zip'
|
archive: '<%= paths.dist %>/node-red-<%= pkg.version %>.zip'
|
||||||
},
|
},
|
||||||
expand: true,
|
expand: true,
|
||||||
cwd: '<%= paths.dist %>/',
|
cwd: 'packages/node_modules/',
|
||||||
src: ['node-red-<%= pkg.version %>/**']
|
src: [
|
||||||
|
'**',
|
||||||
|
'!@node-red/editor-client/src/**'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jsdoc : {
|
||||||
|
runtimeAPI: {
|
||||||
|
src: 'packages/node_modules/@node-red/runtime/lib/api/*.js',
|
||||||
|
options: {
|
||||||
|
destination: 'docs',
|
||||||
|
configure: './jsdoc.json'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nodeREDUtil: {
|
||||||
|
src: 'packages/node_modules/@node-red/util/**/*.js',
|
||||||
|
options: {
|
||||||
|
destination: 'packages/node_modules/@node-red/util/docs',
|
||||||
|
configure: './jsdoc.json'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jsdoc2md: {
|
||||||
|
runtimeAPI: {
|
||||||
|
options: {
|
||||||
|
separators: true
|
||||||
|
},
|
||||||
|
src: 'packages/node_modules/@node-red/runtime/lib/api/*.js',
|
||||||
|
dest: 'docs/runtime-api.md'
|
||||||
|
},
|
||||||
|
nodeREDUtil: {
|
||||||
|
options: {
|
||||||
|
separators: true
|
||||||
|
},
|
||||||
|
src: 'packages/node_modules/@node-red/util/**/*.js',
|
||||||
|
dest: 'packages/node_modules/@node-red/util/docs/api.md'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -432,6 +445,8 @@ module.exports = function(grunt) {
|
|||||||
grunt.loadNpmTasks('grunt-jsonlint');
|
grunt.loadNpmTasks('grunt-jsonlint');
|
||||||
grunt.loadNpmTasks('grunt-mocha-istanbul');
|
grunt.loadNpmTasks('grunt-mocha-istanbul');
|
||||||
grunt.loadNpmTasks('grunt-webdriver');
|
grunt.loadNpmTasks('grunt-webdriver');
|
||||||
|
grunt.loadNpmTasks('grunt-jsdoc');
|
||||||
|
grunt.loadNpmTasks('grunt-jsdoc-to-markdown');
|
||||||
|
|
||||||
grunt.registerMultiTask('attachCopyright', function() {
|
grunt.registerMultiTask('attachCopyright', function() {
|
||||||
var files = this.data.src;
|
var files = this.data.src;
|
||||||
@ -473,6 +488,15 @@ module.exports = function(grunt) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
grunt.registerTask('verifyPackageDependencies', function() {
|
||||||
|
var verifyDependencies = require("./scripts/verify-package-dependencies.js");
|
||||||
|
var failures = verifyDependencies();
|
||||||
|
if (failures.length > 0) {
|
||||||
|
failures.forEach(f => grunt.log.error(f));
|
||||||
|
grunt.fail.fatal("Failed to verify package dependencies");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
grunt.registerTask('setDevEnv',
|
grunt.registerTask('setDevEnv',
|
||||||
'Sets NODE_ENV=development so non-minified assets are used',
|
'Sets NODE_ENV=development so non-minified assets are used',
|
||||||
function () {
|
function () {
|
||||||
@ -481,7 +505,7 @@ module.exports = function(grunt) {
|
|||||||
|
|
||||||
grunt.registerTask('default',
|
grunt.registerTask('default',
|
||||||
'Builds editor content then runs code style checks and unit tests on all components',
|
'Builds editor content then runs code style checks and unit tests on all components',
|
||||||
['build','jshint:editor','mocha_istanbul:all']);
|
['build','verifyPackageDependencies','jshint:editor','mocha_istanbul:all']);
|
||||||
|
|
||||||
grunt.registerTask('test-core',
|
grunt.registerTask('test-core',
|
||||||
'Runs code style check and unit tests on core runtime code',
|
'Runs code style check and unit tests on core runtime code',
|
||||||
@ -509,9 +533,13 @@ module.exports = function(grunt) {
|
|||||||
|
|
||||||
grunt.registerTask('release',
|
grunt.registerTask('release',
|
||||||
'Create distribution zip file',
|
'Create distribution zip file',
|
||||||
['build','clean:release','copy:release','chmod:release','compress:release']);
|
['build','verifyPackageDependencies','clean:release','chmod:release','compress:release']);
|
||||||
|
|
||||||
grunt.registerTask('coverage',
|
grunt.registerTask('coverage',
|
||||||
'Run Istanbul code test coverage task',
|
'Run Istanbul code test coverage task',
|
||||||
['build','mocha_istanbul:all']);
|
['build','mocha_istanbul:all']);
|
||||||
|
|
||||||
|
grunt.registerTask('docs',
|
||||||
|
'Generates API documentation',
|
||||||
|
['jsdoc','jsdoc2md']);
|
||||||
};
|
};
|
||||||
|
@ -44,9 +44,6 @@ If you want to run the latest code from git, here's how to get started:
|
|||||||
4. Run
|
4. Run
|
||||||
|
|
||||||
npm start
|
npm start
|
||||||
or
|
|
||||||
|
|
||||||
node red.js
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
26
jsdoc.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"opts": {
|
||||||
|
"template": "./node_modules/jsdoc-nr-template",
|
||||||
|
"destination": "./docs",
|
||||||
|
"recurse": true
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"allowUnknownTags": false,
|
||||||
|
"dictionaries": ["jsdoc"]
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"_include": [
|
||||||
|
"./packages/node_modules/@node-red/runtime/lib/api"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"templates": {
|
||||||
|
"systemName": "Node-RED Runtime API",
|
||||||
|
"theme":"yeti",
|
||||||
|
"footer": "",
|
||||||
|
"copyright": "Released under the Apache License v2.0",
|
||||||
|
"default": {
|
||||||
|
"outputSourceFiles": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"plugins": ["plugins/markdown"]
|
||||||
|
}
|
1
lib/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
*
|
|
@ -1,159 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
**/
|
|
||||||
var util = require("util");
|
|
||||||
var mqtt = require("./mqtt");
|
|
||||||
var settings = require(process.env.NODE_RED_HOME+"/red/red").settings;
|
|
||||||
|
|
||||||
util.log("[warn] nodes/core/io/lib/mqttConnectionPool.js is deprecated and will be removed in a future release of Node-RED. Please report this usage to the Node-RED mailing list.");
|
|
||||||
|
|
||||||
var connections = {};
|
|
||||||
|
|
||||||
function matchTopic(ts,t) {
|
|
||||||
if (ts == "#") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
var re = new RegExp("^"+ts.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
|
|
||||||
return re.test(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
get: function(broker,port,clientid,username,password,will) {
|
|
||||||
var id = "["+(username||"")+":"+(password||"")+"]["+(clientid||"")+"]@"+broker+":"+port;
|
|
||||||
if (!connections[id]) {
|
|
||||||
connections[id] = function() {
|
|
||||||
var uid = (1+Math.random()*4294967295).toString(16);
|
|
||||||
var client = mqtt.createClient(port,broker);
|
|
||||||
client.uid = uid;
|
|
||||||
client.setMaxListeners(0);
|
|
||||||
var options = {keepalive:15};
|
|
||||||
options.clientId = clientid || 'mqtt_' + (1+Math.random()*4294967295).toString(16);
|
|
||||||
options.username = username;
|
|
||||||
options.password = password;
|
|
||||||
options.will = will;
|
|
||||||
var queue = [];
|
|
||||||
var subscriptions = {};
|
|
||||||
var connecting = false;
|
|
||||||
var obj = {
|
|
||||||
_instances: 0,
|
|
||||||
publish: function(msg) {
|
|
||||||
if (client.isConnected()) {
|
|
||||||
client.publish(msg.topic,msg.payload,msg.qos,msg.retain);
|
|
||||||
} else {
|
|
||||||
if (!connecting) {
|
|
||||||
connecting = true;
|
|
||||||
client.connect(options);
|
|
||||||
}
|
|
||||||
queue.push(msg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
subscribe: function(topic,qos,callback,ref) {
|
|
||||||
ref = ref||0;
|
|
||||||
subscriptions[topic] = subscriptions[topic]||{};
|
|
||||||
|
|
||||||
var sub = {
|
|
||||||
topic:topic,
|
|
||||||
qos:qos,
|
|
||||||
handler:function(mtopic,mpayload,mqos,mretain) {
|
|
||||||
if (matchTopic(topic,mtopic)) {
|
|
||||||
callback(mtopic,mpayload,mqos,mretain);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ref: ref
|
|
||||||
};
|
|
||||||
subscriptions[topic][ref] = sub;
|
|
||||||
client.on('message',sub.handler);
|
|
||||||
if (client.isConnected()) {
|
|
||||||
client.subscribe(topic,qos);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
unsubscribe: function(topic,ref) {
|
|
||||||
ref = ref||0;
|
|
||||||
var sub = subscriptions[topic];
|
|
||||||
if (sub) {
|
|
||||||
if (sub[ref]) {
|
|
||||||
client.removeListener('message',sub[ref].handler);
|
|
||||||
delete sub[ref];
|
|
||||||
}
|
|
||||||
if (Object.keys(sub).length == 0) {
|
|
||||||
delete subscriptions[topic];
|
|
||||||
client.unsubscribe(topic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
on: function(a,b){
|
|
||||||
client.on(a,b);
|
|
||||||
},
|
|
||||||
once: function(a,b){
|
|
||||||
client.once(a,b);
|
|
||||||
},
|
|
||||||
connect: function() {
|
|
||||||
if (client && !client.isConnected() && !connecting) {
|
|
||||||
connecting = true;
|
|
||||||
client.connect(options);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
disconnect: function(ref) {
|
|
||||||
|
|
||||||
this._instances -= 1;
|
|
||||||
if (this._instances == 0) {
|
|
||||||
client.disconnect();
|
|
||||||
client = null;
|
|
||||||
delete connections[id];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isConnected: function() {
|
|
||||||
return client.isConnected();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
client.on('connect',function() {
|
|
||||||
if (client) {
|
|
||||||
util.log('[mqtt] ['+uid+'] connected to broker tcp://'+broker+':'+port);
|
|
||||||
connecting = false;
|
|
||||||
for (var s in subscriptions) {
|
|
||||||
var topic = s;
|
|
||||||
var qos = 0;
|
|
||||||
for (var r in subscriptions[s]) {
|
|
||||||
qos = Math.max(qos,subscriptions[s][r].qos);
|
|
||||||
}
|
|
||||||
client.subscribe(topic,qos);
|
|
||||||
}
|
|
||||||
//console.log("connected - publishing",queue.length,"messages");
|
|
||||||
while(queue.length) {
|
|
||||||
var msg = queue.shift();
|
|
||||||
//console.log(msg);
|
|
||||||
client.publish(msg.topic,msg.payload,msg.qos,msg.retain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
client.on('connectionlost', function(err) {
|
|
||||||
util.log('[mqtt] ['+uid+'] connection lost to broker tcp://'+broker+':'+port);
|
|
||||||
connecting = false;
|
|
||||||
setTimeout(function() {
|
|
||||||
obj.connect();
|
|
||||||
}, settings.mqttReconnectTime||5000);
|
|
||||||
});
|
|
||||||
client.on('disconnect', function() {
|
|
||||||
connecting = false;
|
|
||||||
util.log('[mqtt] ['+uid+'] disconnected from broker tcp://'+broker+':'+port);
|
|
||||||
});
|
|
||||||
|
|
||||||
return obj
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
connections[id]._instances += 1;
|
|
||||||
return connections[id];
|
|
||||||
}
|
|
||||||
};
|
|
31
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "0.19.4",
|
"version": "0.20.0",
|
||||||
"description": "A visual tool for wiring the Internet of Things",
|
"description": "A visual tool for wiring the Internet of Things",
|
||||||
"homepage": "http://nodered.org",
|
"homepage": "http://nodered.org",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@ -8,15 +8,12 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/node-red/node-red.git"
|
"url": "https://github.com/node-red/node-red.git"
|
||||||
},
|
},
|
||||||
"main": "red/red.js",
|
"private": "true",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node red.js",
|
"start": "node packages/node_modules/node-red/red.js",
|
||||||
"test": "grunt",
|
"test": "grunt",
|
||||||
"build": "grunt build"
|
"build": "grunt build",
|
||||||
},
|
"docs": "grunt docs"
|
||||||
"bin": {
|
|
||||||
"node-red": "./red.js",
|
|
||||||
"node-red-pi": "bin/node-red-pi"
|
|
||||||
},
|
},
|
||||||
"contributors": [
|
"contributors": [
|
||||||
{
|
{
|
||||||
@ -26,12 +23,6 @@
|
|||||||
"name": "Dave Conway-Jones"
|
"name": "Dave Conway-Jones"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"keywords": [
|
|
||||||
"editor",
|
|
||||||
"messaging",
|
|
||||||
"iot",
|
|
||||||
"flow"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "6.5.3",
|
"ajv": "6.5.3",
|
||||||
"basic-auth": "2.0.0",
|
"basic-auth": "2.0.0",
|
||||||
@ -57,6 +48,7 @@
|
|||||||
"jsonata": "1.5.4",
|
"jsonata": "1.5.4",
|
||||||
"media-typer": "0.3.0",
|
"media-typer": "0.3.0",
|
||||||
"memorystore": "1.6.0",
|
"memorystore": "1.6.0",
|
||||||
|
"mime": "1.4.1",
|
||||||
"mqtt": "2.18.8",
|
"mqtt": "2.18.8",
|
||||||
"multer": "1.3.1",
|
"multer": "1.3.1",
|
||||||
"mustache": "2.3.2",
|
"mustache": "2.3.2",
|
||||||
@ -95,6 +87,8 @@
|
|||||||
"grunt-contrib-jshint": "~1.1.0",
|
"grunt-contrib-jshint": "~1.1.0",
|
||||||
"grunt-contrib-uglify": "~3.4.0",
|
"grunt-contrib-uglify": "~3.4.0",
|
||||||
"grunt-contrib-watch": "~1.1.0",
|
"grunt-contrib-watch": "~1.1.0",
|
||||||
|
"grunt-jsdoc": "^2.2.1",
|
||||||
|
"grunt-jsdoc-to-markdown": "^4.0.0",
|
||||||
"grunt-jsonlint": "~1.1.0",
|
"grunt-jsonlint": "~1.1.0",
|
||||||
"grunt-mocha-istanbul": "5.0.2",
|
"grunt-mocha-istanbul": "5.0.2",
|
||||||
"grunt-nodemon": "~0.4.2",
|
"grunt-nodemon": "~0.4.2",
|
||||||
@ -103,9 +97,8 @@
|
|||||||
"grunt-webdriver": "^2.0.3",
|
"grunt-webdriver": "^2.0.3",
|
||||||
"http-proxy": "^1.16.2",
|
"http-proxy": "^1.16.2",
|
||||||
"istanbul": "0.4.5",
|
"istanbul": "0.4.5",
|
||||||
|
"minami": "1.2.3",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"mosca": "^2.8.3",
|
|
||||||
"node-red-node-test-helper": "0.1.7",
|
|
||||||
"should": "^8.4.0",
|
"should": "^8.4.0",
|
||||||
"sinon": "1.17.7",
|
"sinon": "1.17.7",
|
||||||
"stoppable": "^1.0.6",
|
"stoppable": "^1.0.6",
|
||||||
@ -113,9 +106,11 @@
|
|||||||
"wdio-chromedriver-service": "^0.1.3",
|
"wdio-chromedriver-service": "^0.1.3",
|
||||||
"wdio-mocha-framework": "^0.6.2",
|
"wdio-mocha-framework": "^0.6.2",
|
||||||
"wdio-spec-reporter": "^0.1.5",
|
"wdio-spec-reporter": "^0.1.5",
|
||||||
"webdriverio": "^4.13.1"
|
"webdriverio": "^4.13.1",
|
||||||
|
"node-red-node-test-helper": "node-red/node-red-node-test-helper",
|
||||||
|
"jsdoc-nr-template": "node-red/jsdoc-nr-template"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
178
packages/node_modules/@node-red/editor-api/LICENSE
generated
vendored
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
12
packages/node_modules/@node-red/editor-api/README.md
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@node-red/editor-api
|
||||||
|
====================
|
||||||
|
|
||||||
|
Node-RED editor api module.
|
||||||
|
|
||||||
|
This provides an Express application that can be used to serve the Node-RED
|
||||||
|
editor.
|
||||||
|
|
||||||
|
|
||||||
|
### Source
|
||||||
|
|
||||||
|
The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red).
|
41
packages/node_modules/@node-red/editor-api/lib/admin/context.js
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
},
|
||||||
|
|
||||||
|
get: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
scope: req.params.scope,
|
||||||
|
id: req.params.id,
|
||||||
|
key: req.params[0],
|
||||||
|
store: req.query['store']
|
||||||
|
}
|
||||||
|
runtimeAPI.context.getValue(opts).then(function(result) {
|
||||||
|
res.json(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
69
packages/node_modules/@node-red/editor-api/lib/admin/flow.js
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
},
|
||||||
|
get: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.flows.getFlow(opts).then(function(result) {
|
||||||
|
return res.json(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
post: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
flow: req.body
|
||||||
|
}
|
||||||
|
runtimeAPI.flows.addFlow(opts).then(function(id) {
|
||||||
|
return res.json({id:id});
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
put: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
flow: req.body
|
||||||
|
}
|
||||||
|
runtimeAPI.flows.updateFlow(opts).then(function(id) {
|
||||||
|
return res.json({id:id});
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
delete: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.flows.deleteFlow(opts).then(function() {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
70
packages/node_modules/@node-red/editor-api/lib/admin/flows.js
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
},
|
||||||
|
get: function(req,res) {
|
||||||
|
var version = req.get("Node-RED-API-Version")||"v1";
|
||||||
|
if (!/^v[12]$/.test(version)) {
|
||||||
|
return res.status(400).json({code:"invalid_api_version", message:"Invalid API Version requested"});
|
||||||
|
}
|
||||||
|
var opts = {
|
||||||
|
user: req.user
|
||||||
|
}
|
||||||
|
runtimeAPI.flows.getFlows(opts).then(function(result) {
|
||||||
|
if (version === "v1") {
|
||||||
|
res.json(result.flows);
|
||||||
|
} else if (version === "v2") {
|
||||||
|
res.json(result);
|
||||||
|
}
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
post: function(req,res) {
|
||||||
|
var version = req.get("Node-RED-API-Version")||"v1";
|
||||||
|
if (!/^v[12]$/.test(version)) {
|
||||||
|
return res.status(400).json({code:"invalid_api_version", message:"Invalid API Version requested"});
|
||||||
|
}
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
deploymentType: req.get("Node-RED-Deployment-Type")||"full"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.deploymentType !== 'reload') {
|
||||||
|
if (version === "v1") {
|
||||||
|
opts.flows = {flows: req.body}
|
||||||
|
} else {
|
||||||
|
opts.flows = req.body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runtimeAPI.flows.setFlows(opts).then(function(result) {
|
||||||
|
if (version === "v1") {
|
||||||
|
res.status(204).end();
|
||||||
|
} else {
|
||||||
|
res.json(result);
|
||||||
|
}
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
12
red/api/admin/index.js → packages/node_modules/@node-red/editor-api/lib/admin/index.js
generated
vendored
@ -25,11 +25,11 @@ var auth = require("../auth");
|
|||||||
var apiUtil = require("../util");
|
var apiUtil = require("../util");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(runtime) {
|
init: function(runtimeAPI) {
|
||||||
flows.init(runtime);
|
flows.init(runtimeAPI);
|
||||||
flow.init(runtime);
|
flow.init(runtimeAPI);
|
||||||
nodes.init(runtime);
|
nodes.init(runtimeAPI);
|
||||||
context.init(runtime);
|
context.init(runtimeAPI);
|
||||||
|
|
||||||
var needsPermission = auth.needsPermission;
|
var needsPermission = auth.needsPermission;
|
||||||
|
|
||||||
@ -48,6 +48,8 @@ module.exports = {
|
|||||||
// Nodes
|
// Nodes
|
||||||
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll,apiUtil.errorHandler);
|
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll,apiUtil.errorHandler);
|
||||||
adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post,apiUtil.errorHandler);
|
adminApp.post("/nodes",needsPermission("nodes.write"),nodes.post,apiUtil.errorHandler);
|
||||||
|
adminApp.get(/\/nodes\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalogs,apiUtil.errorHandler);
|
||||||
|
adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+\/[^\/]+)\/messages/,needsPermission("nodes.read"),nodes.getModuleCatalog,apiUtil.errorHandler);
|
||||||
adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.read"),nodes.getModule,apiUtil.errorHandler);
|
adminApp.get(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.read"),nodes.getModule,apiUtil.errorHandler);
|
||||||
adminApp.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.putModule,apiUtil.errorHandler);
|
adminApp.put(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.putModule,apiUtil.errorHandler);
|
||||||
adminApp.delete(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.delete,apiUtil.errorHandler);
|
adminApp.delete(/\/nodes\/((@[^\/]+\/)?[^\/]+)$/,needsPermission("nodes.write"),nodes.delete,apiUtil.errorHandler);
|
173
packages/node_modules/@node-red/editor-api/lib/admin/nodes.js
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
},
|
||||||
|
getAll: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user
|
||||||
|
}
|
||||||
|
if (req.get("accept") == "application/json") {
|
||||||
|
runtimeAPI.nodes.getNodeList(opts).then(function(list) {
|
||||||
|
res.json(list);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages());
|
||||||
|
runtimeAPI.nodes.getNodeConfigs(opts).then(function(configs) {
|
||||||
|
res.send(configs);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
post: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
module: req.body.module,
|
||||||
|
version: req.body.version
|
||||||
|
}
|
||||||
|
runtimeAPI.nodes.addModule(opts).then(function(info) {
|
||||||
|
res.json(info);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
delete: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
module: req.params[0]
|
||||||
|
}
|
||||||
|
runtimeAPI.nodes.removeModule(opts).then(function() {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getSet: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params[0] + "/" + req.params[2]
|
||||||
|
}
|
||||||
|
if (req.get("accept") === "application/json") {
|
||||||
|
runtimeAPI.nodes.getNodeInfo(opts).then(function(result) {
|
||||||
|
res.send(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages());
|
||||||
|
runtimeAPI.nodes.getNodeConfig(opts).then(function(result) {
|
||||||
|
return res.send(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getModule: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
module: req.params[0]
|
||||||
|
}
|
||||||
|
runtimeAPI.nodes.getModuleInfo(opts).then(function(result) {
|
||||||
|
res.send(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
putSet: function(req,res) {
|
||||||
|
var body = req.body;
|
||||||
|
if (!body.hasOwnProperty("enabled")) {
|
||||||
|
// log.audit({event: "nodes.module.set",error:"invalid_request"},req);
|
||||||
|
res.status(400).json({code:"invalid_request", message:"Invalid request"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params[0] + "/" + req.params[2],
|
||||||
|
enabled: body.enabled
|
||||||
|
}
|
||||||
|
runtimeAPI.nodes.setNodeSetState(opts).then(function(result) {
|
||||||
|
res.send(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
putModule: function(req,res) {
|
||||||
|
var body = req.body;
|
||||||
|
if (!body.hasOwnProperty("enabled")) {
|
||||||
|
// log.audit({event: "nodes.module.set",error:"invalid_request"},req);
|
||||||
|
res.status(400).json({code:"invalid_request", message:"Invalid request"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
module: req.params[0],
|
||||||
|
enabled: body.enabled
|
||||||
|
}
|
||||||
|
runtimeAPI.nodes.setModuleState(opts).then(function(result) {
|
||||||
|
res.send(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getModuleCatalog: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
module: req.params[0],
|
||||||
|
lang: req.query.lng
|
||||||
|
}
|
||||||
|
runtimeAPI.nodes.getModuleCatalog(opts).then(function(result) {
|
||||||
|
res.json(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.log(err.stack);
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getModuleCatalogs: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
lang: req.query.lng
|
||||||
|
}
|
||||||
|
runtimeAPI.nodes.getModuleCatalogs(opts).then(function(result) {
|
||||||
|
res.json(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.log(err.stack);
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getIcons: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user
|
||||||
|
}
|
||||||
|
runtimeAPI.nodes.getIconList(opts).then(function(list) {
|
||||||
|
res.json(list);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
10
red/api/auth/index.js → packages/node_modules/@node-red/editor-api/lib/auth/index.js
generated
vendored
@ -25,7 +25,7 @@ var permissions = require("./permissions");
|
|||||||
var theme = require("../editor/theme");
|
var theme = require("../editor/theme");
|
||||||
|
|
||||||
var settings = null;
|
var settings = null;
|
||||||
var log = null
|
var log = require("@node-red/util").log; // TODO: separate module
|
||||||
|
|
||||||
|
|
||||||
passport.use(strategies.bearerStrategy.BearerStrategy);
|
passport.use(strategies.bearerStrategy.BearerStrategy);
|
||||||
@ -36,13 +36,11 @@ var server = oauth2orize.createServer();
|
|||||||
|
|
||||||
server.exchange(oauth2orize.exchange.password(strategies.passwordTokenExchange));
|
server.exchange(oauth2orize.exchange.password(strategies.passwordTokenExchange));
|
||||||
|
|
||||||
function init(runtime) {
|
function init(_settings,storage) {
|
||||||
settings = runtime.settings;
|
settings = _settings;
|
||||||
log = runtime.log;
|
|
||||||
if (settings.adminAuth) {
|
if (settings.adminAuth) {
|
||||||
Users.init(settings.adminAuth);
|
Users.init(settings.adminAuth);
|
||||||
Tokens.init(settings.adminAuth,runtime.storage);
|
Tokens.init(settings.adminAuth,storage);
|
||||||
strategies.init(runtime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ var Users = require("./users");
|
|||||||
var Clients = require("./clients");
|
var Clients = require("./clients");
|
||||||
var permissions = require("./permissions");
|
var permissions = require("./permissions");
|
||||||
|
|
||||||
var log;
|
var log = require("@node-red/util").log; // TODO: separate module
|
||||||
|
|
||||||
var bearerStrategy = function (accessToken, done) {
|
var bearerStrategy = function (accessToken, done) {
|
||||||
// is this a valid token?
|
// is this a valid token?
|
||||||
@ -124,9 +124,6 @@ AnonymousStrategy.prototype.authenticate = function(req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(runtime) {
|
|
||||||
log = runtime.log;
|
|
||||||
},
|
|
||||||
bearerStrategy: bearerStrategy,
|
bearerStrategy: bearerStrategy,
|
||||||
clientPasswordStrategy: clientPasswordStrategy,
|
clientPasswordStrategy: clientPasswordStrategy,
|
||||||
passwordTokenExchange: passwordTokenExchange,
|
passwordTokenExchange: passwordTokenExchange,
|
0
red/api/auth/users.js → packages/node_modules/@node-red/editor-api/lib/auth/users.js
generated
vendored
243
packages/node_modules/@node-red/editor-api/lib/editor/comms.js
generated
vendored
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var ws = require("ws");
|
||||||
|
|
||||||
|
var log = require("@node-red/util").log; // TODO: separate module
|
||||||
|
var Tokens;
|
||||||
|
var Users;
|
||||||
|
var Permissions;
|
||||||
|
|
||||||
|
var server;
|
||||||
|
var settings;
|
||||||
|
var runtimeAPI;
|
||||||
|
|
||||||
|
var wsServer;
|
||||||
|
var activeConnections = [];
|
||||||
|
|
||||||
|
var anonymousUser;
|
||||||
|
|
||||||
|
var retained = {};
|
||||||
|
|
||||||
|
var heartbeatTimer;
|
||||||
|
var lastSentTime;
|
||||||
|
|
||||||
|
function init(_server,_settings,_runtimeAPI) {
|
||||||
|
server = _server;
|
||||||
|
settings = _settings;
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
Tokens = require("../auth/tokens");
|
||||||
|
Users = require("../auth/users");
|
||||||
|
Permissions = require("../auth/permissions");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateSession(length) {
|
||||||
|
var c = "ABCDEFGHIJKLMNOPQRSTUZWXYZabcdefghijklmnopqrstuvwxyz1234567890";
|
||||||
|
var token = [];
|
||||||
|
for (var i=0;i<length;i++) {
|
||||||
|
token.push(c[Math.floor(Math.random()*c.length)]);
|
||||||
|
}
|
||||||
|
return token.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function CommsConnection(ws) {
|
||||||
|
this.session = generateSession(32);
|
||||||
|
this.ws = ws;
|
||||||
|
this.stack = [];
|
||||||
|
this.user = null;
|
||||||
|
this.lastSentTime = 0;
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
log.audit({event: "comms.open"});
|
||||||
|
log.trace("comms.open "+self.session);
|
||||||
|
var pendingAuth = (settings.adminAuth != null);
|
||||||
|
|
||||||
|
if (!pendingAuth) {
|
||||||
|
addActiveConnection(self);
|
||||||
|
}
|
||||||
|
ws.on('close',function() {
|
||||||
|
log.audit({event: "comms.close",user:self.user, session: self.session});
|
||||||
|
log.trace("comms.close "+self.session);
|
||||||
|
removeActiveConnection(self);
|
||||||
|
});
|
||||||
|
ws.on('message', function(data,flags) {
|
||||||
|
var msg = null;
|
||||||
|
try {
|
||||||
|
msg = JSON.parse(data);
|
||||||
|
} catch(err) {
|
||||||
|
log.trace("comms received malformed message : "+err.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!pendingAuth) {
|
||||||
|
if (msg.subscribe) {
|
||||||
|
self.subscribe(msg.subscribe);
|
||||||
|
// handleRemoteSubscription(ws,msg.subscribe);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var completeConnection = function(userScope,sendAck) {
|
||||||
|
try {
|
||||||
|
if (!userScope || !Permissions.hasPermission(userScope,"status.read")) {
|
||||||
|
ws.send(JSON.stringify({auth:"fail"}));
|
||||||
|
ws.close();
|
||||||
|
} else {
|
||||||
|
pendingAuth = false;
|
||||||
|
addActiveConnection(self);
|
||||||
|
if (sendAck) {
|
||||||
|
ws.send(JSON.stringify({auth:"ok"}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err.stack);
|
||||||
|
// Just in case the socket closes before we attempt
|
||||||
|
// to send anything.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (msg.auth) {
|
||||||
|
Tokens.get(msg.auth).then(function(client) {
|
||||||
|
if (client) {
|
||||||
|
Users.get(client.user).then(function(user) {
|
||||||
|
if (user) {
|
||||||
|
self.user = user;
|
||||||
|
log.audit({event: "comms.auth",user:self.user});
|
||||||
|
completeConnection(client.scope,true);
|
||||||
|
} else {
|
||||||
|
log.audit({event: "comms.auth.fail"});
|
||||||
|
completeConnection(null,false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
log.audit({event: "comms.auth.fail"});
|
||||||
|
completeConnection(null,false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (anonymousUser) {
|
||||||
|
log.audit({event: "comms.auth",user:anonymousUser});
|
||||||
|
self.user = anonymousUser;
|
||||||
|
completeConnection(anonymousUser.permissions,false);
|
||||||
|
//TODO: duplicated code - pull non-auth message handling out
|
||||||
|
if (msg.subscribe) {
|
||||||
|
self.subscribe(msg.subscribe);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.audit({event: "comms.auth.fail"});
|
||||||
|
completeConnection(null,false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ws.on('error', function(err) {
|
||||||
|
log.warn(log._("comms.error",{message:err.toString()}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CommsConnection.prototype.send = function(topic,data) {
|
||||||
|
var self = this;
|
||||||
|
if (topic && data) {
|
||||||
|
this.stack.push({topic:topic,data:data});
|
||||||
|
}
|
||||||
|
if (!this._xmitTimer) {
|
||||||
|
this._xmitTimer = setTimeout(function() {
|
||||||
|
try {
|
||||||
|
self.ws.send(JSON.stringify(self.stack));
|
||||||
|
self.lastSentTime = Date.now();
|
||||||
|
} catch(err) {
|
||||||
|
removeActiveConnection(self);
|
||||||
|
log.warn(log._("comms.error-send",{message:err.toString()}));
|
||||||
|
}
|
||||||
|
delete self._xmitTimer;
|
||||||
|
self.stack = [];
|
||||||
|
},50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CommsConnection.prototype.subscribe = function(topic) {
|
||||||
|
runtimeAPI.comms.subscribe({
|
||||||
|
user: this.user,
|
||||||
|
client: this,
|
||||||
|
topic: topic
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
if (!settings.disableEditor) {
|
||||||
|
Users.default().then(function(_anonymousUser) {
|
||||||
|
anonymousUser = _anonymousUser;
|
||||||
|
var webSocketKeepAliveTime = settings.webSocketKeepAliveTime || 15000;
|
||||||
|
var path = settings.httpAdminRoot || "/";
|
||||||
|
path = (path.slice(0,1) != "/" ? "/":"") + path + (path.slice(-1) == "/" ? "":"/") + "comms";
|
||||||
|
wsServer = new ws.Server({
|
||||||
|
server:server,
|
||||||
|
path:path,
|
||||||
|
// Disable the deflate option due to this issue
|
||||||
|
// https://github.com/websockets/ws/pull/632
|
||||||
|
// that is fixed in the 1.x release of the ws module
|
||||||
|
// that we cannot currently pickup as it drops node 0.10 support
|
||||||
|
//perMessageDeflate: false
|
||||||
|
});
|
||||||
|
|
||||||
|
wsServer.on('connection',function(ws) {
|
||||||
|
var commsConnection = new CommsConnection(ws);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
wsServer.on('error', function(err) {
|
||||||
|
log.warn(log._("comms.error-server",{message:err.toString()}));
|
||||||
|
});
|
||||||
|
|
||||||
|
lastSentTime = Date.now();
|
||||||
|
|
||||||
|
heartbeatTimer = setInterval(function() {
|
||||||
|
var now = Date.now();
|
||||||
|
if (now-lastSentTime > webSocketKeepAliveTime) {
|
||||||
|
activeConnections.forEach(connection => connection.send("hb",lastSentTime));
|
||||||
|
}
|
||||||
|
}, webSocketKeepAliveTime);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stop() {
|
||||||
|
if (heartbeatTimer) {
|
||||||
|
clearInterval(heartbeatTimer);
|
||||||
|
heartbeatTimer = null;
|
||||||
|
}
|
||||||
|
if (wsServer) {
|
||||||
|
wsServer.close();
|
||||||
|
wsServer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addActiveConnection(connection) {
|
||||||
|
activeConnections.push(connection);
|
||||||
|
runtimeAPI.comms.addConnection({client: connection});
|
||||||
|
}
|
||||||
|
function removeActiveConnection(connection) {
|
||||||
|
for (var i=0;i<activeConnections.length;i++) {
|
||||||
|
if (activeConnections[i] === connection) {
|
||||||
|
activeConnections.splice(i,1);
|
||||||
|
runtimeAPI.comms.removeConnection({client:connection})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init:init,
|
||||||
|
start:start,
|
||||||
|
stop:stop
|
||||||
|
}
|
36
packages/node_modules/@node-red/editor-api/lib/editor/credentials.js
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI
|
||||||
|
},
|
||||||
|
get: function (req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
type: req.params.type,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.flows.getNodeCredentials(opts).then(function(result) {
|
||||||
|
res.json(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
53
red/api/editor/index.js → packages/node_modules/@node-red/editor-api/lib/editor/index.js
generated
vendored
@ -24,31 +24,35 @@ var info = require("./settings");
|
|||||||
var auth = require("../auth");
|
var auth = require("../auth");
|
||||||
var nodes = require("../admin/nodes"); // TODO: move /icons into here
|
var nodes = require("../admin/nodes"); // TODO: move /icons into here
|
||||||
var needsPermission;
|
var needsPermission;
|
||||||
var runtime;
|
var runtimeAPI;
|
||||||
var log;
|
var log = require("@node-red/util").log; // TODO: separate module
|
||||||
|
var i18n = require("@node-red/util").i18n; // TODO: separate module
|
||||||
|
|
||||||
var apiUtil = require("../util");
|
var apiUtil = require("../util");
|
||||||
|
|
||||||
var ensureRuntimeStarted = function(req,res,next) {
|
var ensureRuntimeStarted = function(req,res,next) {
|
||||||
if (!runtime.isStarted()) {
|
runtimeAPI.isStarted().then( started => {
|
||||||
|
if (!started) {
|
||||||
log.error("Node-RED runtime not started");
|
log.error("Node-RED runtime not started");
|
||||||
res.status(503).send("Not started");
|
res.status(503).send("Not started");
|
||||||
} else {
|
} else {
|
||||||
next();
|
next()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(server, _runtime) {
|
init: function(server, settings, _runtimeAPI) {
|
||||||
runtime = _runtime;
|
runtimeAPI = _runtimeAPI;
|
||||||
log = runtime.log;
|
|
||||||
needsPermission = auth.needsPermission;
|
needsPermission = auth.needsPermission;
|
||||||
var settings = runtime.settings;
|
|
||||||
if (!settings.disableEditor) {
|
if (!settings.disableEditor) {
|
||||||
info.init(runtime);
|
info.init(runtimeAPI);
|
||||||
comms.init(server,runtime);
|
comms.init(server,settings,runtimeAPI);
|
||||||
|
|
||||||
var ui = require("./ui");
|
var ui = require("./ui");
|
||||||
ui.init(runtime);
|
|
||||||
|
ui.init(runtimeAPI);
|
||||||
|
|
||||||
var editorApp = express();
|
var editorApp = express();
|
||||||
if (settings.requireHttps === true) {
|
if (settings.requireHttps === true) {
|
||||||
editorApp.enable('trust proxy');
|
editorApp.enable('trust proxy');
|
||||||
@ -67,31 +71,31 @@ module.exports = {
|
|||||||
editorApp.get("/icons/:scope/:module/:icon",ui.icon);
|
editorApp.get("/icons/:scope/:module/:icon",ui.icon);
|
||||||
|
|
||||||
var theme = require("./theme");
|
var theme = require("./theme");
|
||||||
theme.init(runtime);
|
theme.init(settings);
|
||||||
editorApp.use("/theme",theme.app());
|
editorApp.use("/theme",theme.app());
|
||||||
editorApp.use("/",ui.editorResources);
|
editorApp.use("/",ui.editorResources);
|
||||||
|
|
||||||
//Projects
|
//Projects
|
||||||
var projects = require("./projects");
|
var projects = require("./projects");
|
||||||
projects.init(runtime);
|
projects.init(runtimeAPI);
|
||||||
editorApp.use("/projects",projects.app());
|
editorApp.use("/projects",projects.app());
|
||||||
|
|
||||||
// Locales
|
// Locales
|
||||||
var locales = require("./locales");
|
var locales = require("./locales");
|
||||||
locales.init(runtime);
|
locales.init(runtimeAPI);
|
||||||
editorApp.get('/locales/nodes',locales.getAllNodes,apiUtil.errorHandler);
|
|
||||||
editorApp.get(/locales\/(.+)\/?$/,locales.get,apiUtil.errorHandler);
|
editorApp.get(/locales\/(.+)\/?$/,locales.get,apiUtil.errorHandler);
|
||||||
|
|
||||||
// Library
|
// Library
|
||||||
var library = require("./library");
|
var library = require("./library");
|
||||||
library.init(editorApp,runtime);
|
library.init(runtimeAPI);
|
||||||
editorApp.post(new RegExp("/library/flows\/(.*)"),needsPermission("library.write"),library.post,apiUtil.errorHandler);
|
|
||||||
editorApp.get("/library/flows",needsPermission("library.read"),library.getAll,apiUtil.errorHandler);
|
editorApp.get("/library/flows",needsPermission("library.read"),library.getAll,apiUtil.errorHandler);
|
||||||
editorApp.get(new RegExp("/library/flows\/(.*)"),needsPermission("library.read"),library.get,apiUtil.errorHandler);
|
editorApp.get(/library\/([^\/]+)(?:$|\/(.*))/,needsPermission("library.read"),library.getEntry);
|
||||||
|
editorApp.post(/library\/([^\/]+)\/(.*)/,needsPermission("library.write"),library.saveEntry);
|
||||||
|
|
||||||
|
|
||||||
// Credentials
|
// Credentials
|
||||||
var credentials = require("./credentials");
|
var credentials = require("./credentials");
|
||||||
credentials.init(runtime);
|
credentials.init(runtimeAPI);
|
||||||
editorApp.get('/credentials/:type/:id', needsPermission("credentials.read"),credentials.get,apiUtil.errorHandler);
|
editorApp.get('/credentials/:type/:id', needsPermission("credentials.read"),credentials.get,apiUtil.errorHandler);
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
@ -100,18 +104,15 @@ module.exports = {
|
|||||||
editorApp.get("/settings/user",needsPermission("settings.read"),info.userSettings,apiUtil.errorHandler);
|
editorApp.get("/settings/user",needsPermission("settings.read"),info.userSettings,apiUtil.errorHandler);
|
||||||
// User Settings
|
// User Settings
|
||||||
editorApp.post("/settings/user",needsPermission("settings.write"),info.updateUserSettings,apiUtil.errorHandler);
|
editorApp.post("/settings/user",needsPermission("settings.write"),info.updateUserSettings,apiUtil.errorHandler);
|
||||||
|
|
||||||
// SSH keys
|
// SSH keys
|
||||||
var sshkeys = require("./sshkeys");
|
editorApp.use("/settings/user/keys",needsPermission("settings.write"),info.sshkeys());
|
||||||
sshkeys.init(runtime);
|
|
||||||
editorApp.use("/settings/user/keys",sshkeys.app());
|
|
||||||
|
|
||||||
return editorApp;
|
return editorApp;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
start: function() {
|
start: function() {
|
||||||
var catalogPath = path.resolve(path.join(__dirname,"locales"));
|
var catalogPath = path.resolve(path.join(__dirname,"locales"));
|
||||||
return runtime.i18n.registerMessageCatalogs([
|
return i18n.registerMessageCatalogs([
|
||||||
{namespace: "editor", dir: catalogPath, file:"editor.json"},
|
{namespace: "editor", dir: catalogPath, file:"editor.json"},
|
||||||
{namespace: "jsonata", dir: catalogPath, file:"jsonata.json"},
|
{namespace: "jsonata", dir: catalogPath, file:"jsonata.json"},
|
||||||
{namespace: "infotips", dir: catalogPath, file:"infotips.json"}
|
{namespace: "infotips", dir: catalogPath, file:"infotips.json"}
|
||||||
@ -119,7 +120,5 @@ module.exports = {
|
|||||||
comms.start();
|
comms.start();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
stop: comms.stop,
|
stop: comms.stop
|
||||||
publish: comms.publish,
|
|
||||||
registerLibrary: library.register
|
|
||||||
}
|
}
|
83
packages/node_modules/@node-red/editor-api/lib/editor/library.js
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
var fs = require('fs');
|
||||||
|
var fspath = require('path');
|
||||||
|
var when = require('when');
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
},
|
||||||
|
|
||||||
|
getAll: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
type: 'flows'
|
||||||
|
}
|
||||||
|
runtimeAPI.library.getEntries(opts).then(function(result) {
|
||||||
|
res.json(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getEntry: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
type: req.params[0],
|
||||||
|
path: req.params[1]||""
|
||||||
|
}
|
||||||
|
runtimeAPI.library.getEntry(opts).then(function(result) {
|
||||||
|
if (typeof result === "string") {
|
||||||
|
if (opts.type === 'flows') {
|
||||||
|
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||||
|
} else {
|
||||||
|
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||||
|
}
|
||||||
|
res.write(result);
|
||||||
|
res.end();
|
||||||
|
} else {
|
||||||
|
res.json(result);
|
||||||
|
}
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
saveEntry: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
type: req.params[0],
|
||||||
|
path: req.params[1]||""
|
||||||
|
}
|
||||||
|
// TODO: horrible inconsistencies between flows and all other types
|
||||||
|
if (opts.type === "flows") {
|
||||||
|
opts.meta = {};
|
||||||
|
opts.body = JSON.stringify(req.body);
|
||||||
|
} else {
|
||||||
|
opts.meta = req.body;
|
||||||
|
opts.body = opts.meta.text;
|
||||||
|
delete opts.meta.text;
|
||||||
|
}
|
||||||
|
runtimeAPI.library.saveEntry(opts).then(function(result) {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -16,13 +16,14 @@
|
|||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
//var apiUtil = require('../util');
|
//var apiUtil = require('../util');
|
||||||
var i18n;
|
|
||||||
var redNodes;
|
var i18n = require("@node-red/util").i18n; // TODO: separate module
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(runtime) {
|
init: function(_runtimeAPI) {
|
||||||
i18n = runtime.i18n;
|
runtimeAPI = _runtimeAPI;
|
||||||
redNodes = runtime.nodes;
|
|
||||||
},
|
},
|
||||||
get: function(req,res) {
|
get: function(req,res) {
|
||||||
var namespace = req.params[0];
|
var namespace = req.params[0];
|
||||||
@ -36,17 +37,5 @@ module.exports = {
|
|||||||
res.json(catalog||{});
|
res.json(catalog||{});
|
||||||
});
|
});
|
||||||
i18n.i.changeLanguage(prevLang);
|
i18n.i.changeLanguage(prevLang);
|
||||||
|
|
||||||
},
|
|
||||||
getAllNodes: function(req,res) {
|
|
||||||
var lngs = req.query.lng;
|
|
||||||
var nodeList = redNodes.getNodeList();
|
|
||||||
var result = {};
|
|
||||||
nodeList.forEach(function(n) {
|
|
||||||
if (n.module !== "node-red") {
|
|
||||||
result[n.id] = i18n.i.getResourceBundle(lngs, n.id)||{};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
res.json(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -172,7 +172,10 @@
|
|||||||
"modifiedFlowsDesc": "Only deploys flows that contain changed nodes",
|
"modifiedFlowsDesc": "Only deploys flows that contain changed nodes",
|
||||||
"modifiedNodes": "Modified Nodes",
|
"modifiedNodes": "Modified Nodes",
|
||||||
"modifiedNodesDesc": "Only deploys nodes that have changed",
|
"modifiedNodesDesc": "Only deploys nodes that have changed",
|
||||||
|
"restartFlows": "Restart Flows",
|
||||||
|
"restartFlowsDesc": "Restarts the current deployed flows",
|
||||||
"successfulDeploy": "Successfully deployed",
|
"successfulDeploy": "Successfully deployed",
|
||||||
|
"successfulRestart": "Successfully restarted flows",
|
||||||
"deployFailed": "Deploy failed: __message__",
|
"deployFailed": "Deploy failed: __message__",
|
||||||
"unusedConfigNodes":"You have some unused configuration nodes.",
|
"unusedConfigNodes":"You have some unused configuration nodes.",
|
||||||
"unusedConfigNodesLink":"Click here to see them",
|
"unusedConfigNodesLink":"Click here to see them",
|
507
packages/node_modules/@node-red/editor-api/lib/editor/projects.js
generated
vendored
Normal file
@ -0,0 +1,507 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var express = require("express");
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
|
||||||
|
var runtimeAPI;
|
||||||
|
var needsPermission = require("../auth").needsPermission;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
},
|
||||||
|
app: function() {
|
||||||
|
var app = express();
|
||||||
|
|
||||||
|
app.use(function(req,res,next) {
|
||||||
|
runtimeAPI.projects.available().then(function(available) {
|
||||||
|
if (!available) {
|
||||||
|
res.status(404).end();
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Projects
|
||||||
|
|
||||||
|
// List all projects
|
||||||
|
app.get("/", needsPermission("projects.read"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.listProjects(opts).then(function(result) {
|
||||||
|
res.json(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create project
|
||||||
|
app.post("/", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
project: req.body
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.createProject(opts).then(function(result) {
|
||||||
|
res.json(result);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update a project
|
||||||
|
app.put("/:id", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
project: req.body
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.body.active) {
|
||||||
|
runtimeAPI.projects.setActiveProject(opts).then(function() {
|
||||||
|
res.redirect(303,req.baseUrl + '/');
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
} else if (req.body.initialise) {
|
||||||
|
runtimeAPI.projects.initialiseProject(opts).then(function() {
|
||||||
|
res.redirect(303,req.baseUrl + '/'+ req.params.id);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
} else if (req.body.hasOwnProperty('credentialSecret') ||
|
||||||
|
req.body.hasOwnProperty('description') ||
|
||||||
|
req.body.hasOwnProperty('dependencies')||
|
||||||
|
req.body.hasOwnProperty('summary') ||
|
||||||
|
req.body.hasOwnProperty('files') ||
|
||||||
|
req.body.hasOwnProperty('git')) {
|
||||||
|
runtimeAPI.projects.updateProject(opts).then(function() {
|
||||||
|
res.redirect(303,req.baseUrl + '/'+ req.params.id);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
res.status(400).json({error:"unexpected_error", message:"invalid_request"});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get project metadata
|
||||||
|
app.get("/:id", needsPermission("projects.read"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getProject(opts).then(function(data) {
|
||||||
|
if (data) {
|
||||||
|
res.json(data);
|
||||||
|
} else {
|
||||||
|
res.status(404).end();
|
||||||
|
}
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete project
|
||||||
|
app.delete("/:id", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.deleteProject(opts).then(function() {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Get project status - files, commit counts, branch info
|
||||||
|
app.get("/:id/status", needsPermission("projects.read"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
remote: req.query.remote
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getStatus(opts).then(function(data){
|
||||||
|
if (data) {
|
||||||
|
res.json(data);
|
||||||
|
} else {
|
||||||
|
res.status(404).end();
|
||||||
|
}
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Project file listing
|
||||||
|
app.get("/:id/files", needsPermission("projects.read"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getFiles(opts).then(function(data) {
|
||||||
|
res.json(data);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Get file content in a given tree (index/stage)
|
||||||
|
app.get("/:id/files/:treeish/*", needsPermission("projects.read"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
path: req.params[0],
|
||||||
|
tree: req.params.treeish
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getFile(opts).then(function(data) {
|
||||||
|
res.json({content:data});
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Revert a file
|
||||||
|
app.delete("/:id/files/_/*", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
path: req.params[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
runtimeAPI.projects.revertFile(opts).then(function() {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Stage a file
|
||||||
|
app.post("/:id/stage/*", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
path: req.params[0]
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.stageFile(opts).then(function() {
|
||||||
|
res.redirect(303,req.baseUrl+"/"+opts.id+"/status");
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Stage multiple files
|
||||||
|
app.post("/:id/stage", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
path: req.body.files
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.stageFile(opts).then(function() {
|
||||||
|
res.redirect(303,req.baseUrl+"/"+opts.id+"/status");
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Commit changes
|
||||||
|
app.post("/:id/commit", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
message: req.body.message
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.commit(opts).then(function() {
|
||||||
|
res.redirect(303,req.baseUrl+"/"+opts.id+"/status");
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Unstage a file
|
||||||
|
app.delete("/:id/stage/*", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
path: req.params[0]
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.unstageFile(opts).then(function() {
|
||||||
|
res.redirect(303,req.baseUrl+"/"+opts.id+"/status");
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Unstage multiple files
|
||||||
|
app.delete("/:id/stage", needsPermission("projects.write"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.unstageFile(opts).then(function() {
|
||||||
|
res.redirect(303,req.baseUrl+"/"+opts.id+"/status");
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get a file diff
|
||||||
|
app.get("/:id/diff/:type/*", needsPermission("projects.read"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
path: req.params[0],
|
||||||
|
type: req.params.type
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getFileDiff(opts).then(function(data) {
|
||||||
|
res.json({
|
||||||
|
diff: data
|
||||||
|
})
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get a list of commits
|
||||||
|
app.get("/:id/commits", needsPermission("projects.read"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
limit: req.query.limit || 20,
|
||||||
|
before: req.query.before
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getCommits(opts).then(function(data) {
|
||||||
|
res.json(data);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get an individual commit details
|
||||||
|
app.get("/:id/commits/:sha", needsPermission("projects.read"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
sha: req.params.sha
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getCommit(opts).then(function(data) {
|
||||||
|
res.json({commit:data});
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Push local commits to remote
|
||||||
|
app.post("/:id/push/?*", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
remote: req.params[0],
|
||||||
|
track: req.query.u
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.push(opts).then(function(data) {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pull remote commits
|
||||||
|
app.post("/:id/pull/?*", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
remote: req.params[0],
|
||||||
|
track: req.query.setUpstream,
|
||||||
|
allowUnrelatedHistories: req.query.allowUnrelatedHistories
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.pull(opts).then(function(data) {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Abort an ongoing merge
|
||||||
|
app.delete("/:id/merge", needsPermission("projects.write"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.abortMerge(opts).then(function() {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Resolve a merge
|
||||||
|
app.post("/:id/resolve/*", needsPermission("projects.write"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
path: req.params[0],
|
||||||
|
resolution: req.body.resolutions
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.resolveMerge(opts).then(function() {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get a list of local branches
|
||||||
|
app.get("/:id/branches", needsPermission("projects.read"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
remote: false
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getBranches(opts).then(function(data) {
|
||||||
|
res.json(data);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete a local branch - ?force=true
|
||||||
|
app.delete("/:id/branches/:branchName", needsPermission("projects.write"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
branch: req.params.branchName,
|
||||||
|
force: !!req.query.force
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.deleteBranch(opts).then(function(data) {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get a list of remote branches
|
||||||
|
app.get("/:id/branches/remote", needsPermission("projects.read"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
remote: true
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getBranches(opts).then(function(data) {
|
||||||
|
res.json(data);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get branch status - commit counts/ahead/behind
|
||||||
|
app.get("/:id/branches/remote/*/status", needsPermission("projects.read"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
branch: req.params[0]
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getBranchStatus(opts).then(function(data) {
|
||||||
|
res.json(data);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set the active local branch
|
||||||
|
app.post("/:id/branches", needsPermission("projects.write"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
branch: req.body.name,
|
||||||
|
create: req.body.create
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.setBranch(opts).then(function(data) {
|
||||||
|
res.json(data);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get a list of remotes
|
||||||
|
app.get("/:id/remotes", needsPermission("projects.read"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.getRemotes(opts).then(function(data) {
|
||||||
|
res.json(data);
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add a remote
|
||||||
|
app.post("/:id/remotes", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
remote: req.body
|
||||||
|
}
|
||||||
|
if (/^https?:\/\/[^/]+@/i.test(req.body.url)) {
|
||||||
|
res.status(400).json({error:"unexpected_error", message:"Git http url must not include username/password"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.addRemote(opts).then(function(data) {
|
||||||
|
res.redirect(303,req.baseUrl+"/"+opts.id+"/remotes");
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete a remote
|
||||||
|
app.delete("/:id/remotes/:remoteName", needsPermission("projects.write"), function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
remote: req.params.remoteName
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.removeRemote(opts).then(function(data) {
|
||||||
|
res.redirect(303,req.baseUrl+"/"+opts.id+"/remotes");
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update a remote
|
||||||
|
app.put("/:id/remotes/:remoteName", needsPermission("projects.write"), function(req,res) {
|
||||||
|
var remote = req.body || {};
|
||||||
|
remote.name = req.params.remoteName;
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id,
|
||||||
|
remote: remote
|
||||||
|
}
|
||||||
|
runtimeAPI.projects.updateRemote(opts).then(function() {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
}
|
60
packages/node_modules/@node-red/editor-api/lib/editor/settings.js
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
var runtimeAPI;
|
||||||
|
var sshkeys = require("./sshkeys");
|
||||||
|
var theme = require("./theme");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
sshkeys.init(runtimeAPI);
|
||||||
|
},
|
||||||
|
runtimeSettings: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user
|
||||||
|
}
|
||||||
|
runtimeAPI.settings.getRuntimeSettings(opts).then(function(result) {
|
||||||
|
var themeSettings = theme.settings();
|
||||||
|
if (themeSettings) {
|
||||||
|
result.editorTheme = themeSettings;
|
||||||
|
}
|
||||||
|
res.json(result);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
userSettings: function(req, res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user
|
||||||
|
}
|
||||||
|
runtimeAPI.settings.getUserSettings(opts).then(function(result) {
|
||||||
|
res.json(result);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateUserSettings: function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
settings: req.body
|
||||||
|
}
|
||||||
|
runtimeAPI.settings.updateUserSettings(opts).then(function(result) {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
sshkeys: function() {
|
||||||
|
return sshkeys.app()
|
||||||
|
}
|
||||||
|
}
|
101
packages/node_modules/@node-red/editor-api/lib/editor/sshkeys.js
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
var express = require("express");
|
||||||
|
var runtimeAPI;
|
||||||
|
|
||||||
|
function getUsername(userObj) {
|
||||||
|
var username = '__default';
|
||||||
|
if ( userObj && userObj.name ) {
|
||||||
|
username = userObj.name;
|
||||||
|
}
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
init: function(_runtimeAPI) {
|
||||||
|
runtimeAPI = _runtimeAPI;
|
||||||
|
},
|
||||||
|
app: function() {
|
||||||
|
var app = express();
|
||||||
|
|
||||||
|
// List all SSH keys
|
||||||
|
app.get("/", function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user
|
||||||
|
}
|
||||||
|
runtimeAPI.settings.getUserKeys(opts).then(function(list) {
|
||||||
|
res.json({
|
||||||
|
keys: list
|
||||||
|
});
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get SSH key detail
|
||||||
|
app.get("/:id", function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.settings.getUserKey(opts).then(function(data) {
|
||||||
|
res.json({
|
||||||
|
publickey: data
|
||||||
|
});
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Generate a SSH key
|
||||||
|
app.post("/", function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
// TODO: validate params
|
||||||
|
opts.name = req.body.name;
|
||||||
|
opts.password = req.body.password;
|
||||||
|
opts.comment = req.body.comment;
|
||||||
|
opts.size = req.body.size;
|
||||||
|
|
||||||
|
runtimeAPI.settings.generateUserKey(opts).then(function(name) {
|
||||||
|
res.json({
|
||||||
|
name: name
|
||||||
|
});
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete a SSH key
|
||||||
|
app.delete("/:id", function(req,res) {
|
||||||
|
var opts = {
|
||||||
|
user: req.user,
|
||||||
|
id: req.params.id
|
||||||
|
}
|
||||||
|
runtimeAPI.settings.removeUserKey(opts).then(function(name) {
|
||||||
|
res.status(204).end();
|
||||||
|
}).catch(function(err) {
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,6 @@ var defaultContext = {
|
|||||||
var theme = null;
|
var theme = null;
|
||||||
var themeContext = clone(defaultContext);
|
var themeContext = clone(defaultContext);
|
||||||
var themeSettings = null;
|
var themeSettings = null;
|
||||||
var runtime = null;
|
|
||||||
|
|
||||||
var themeApp;
|
var themeApp;
|
||||||
|
|
||||||
@ -78,12 +77,8 @@ function serveFilesFromTheme(themeValue, themeApp, directory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(runtime) {
|
init: function(settings) {
|
||||||
var settings = runtime.settings;
|
|
||||||
themeContext = clone(defaultContext);
|
themeContext = clone(defaultContext);
|
||||||
if (runtime.version) {
|
|
||||||
themeContext.version = runtime.version();
|
|
||||||
}
|
|
||||||
themeSettings = null;
|
themeSettings = null;
|
||||||
theme = settings.editorTheme || {};
|
theme = settings.editorTheme || {};
|
||||||
},
|
},
|
37
red/api/editor/ui.js → packages/node_modules/@node-red/editor-api/lib/editor/ui.js
generated
vendored
@ -17,18 +17,22 @@ var express = require('express');
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var Mustache = require("mustache");
|
var Mustache = require("mustache");
|
||||||
|
var mime = require("mime");
|
||||||
|
|
||||||
|
var apiUtils = require("../util");
|
||||||
|
|
||||||
var theme = require("./theme");
|
var theme = require("./theme");
|
||||||
|
|
||||||
var redNodes;
|
var runtimeAPI;
|
||||||
|
var editorClientDir = path.dirname(require.resolve("@node-red/editor-client"));
|
||||||
var templateDir = path.resolve(__dirname+"/../../../editor/templates");
|
var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.png");
|
||||||
|
var editorTemplatePath = path.join(editorClientDir,"templates","index.mst");
|
||||||
var editorTemplate;
|
var editorTemplate;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(runtime) {
|
init: function(_runtimeAPI) {
|
||||||
redNodes = runtime.nodes;
|
runtimeAPI = _runtimeAPI;
|
||||||
editorTemplate = fs.readFileSync(path.join(templateDir,"index.mst"),"utf8");
|
editorTemplate = fs.readFileSync(editorTemplatePath,"utf8");
|
||||||
Mustache.parse(editorTemplate);
|
Mustache.parse(editorTemplate);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -46,11 +50,26 @@ module.exports = {
|
|||||||
var icon = req.params.icon;
|
var icon = req.params.icon;
|
||||||
var scope = req.params.scope;
|
var scope = req.params.scope;
|
||||||
var module = scope ? scope + '/' + req.params.module : req.params.module;
|
var module = scope ? scope + '/' + req.params.module : req.params.module;
|
||||||
var iconPath = redNodes.getNodeIconPath(module,icon);
|
var opts = {
|
||||||
res.sendFile(iconPath);
|
user: req.user,
|
||||||
|
module: module,
|
||||||
|
icon: icon
|
||||||
|
}
|
||||||
|
runtimeAPI.nodes.getIcon(opts).then(function(data) {
|
||||||
|
if (data) {
|
||||||
|
var contentType = mime.lookup(icon);
|
||||||
|
res.set("Content-Type", contentType);
|
||||||
|
res.send(data);
|
||||||
|
} else {
|
||||||
|
res.sendFile(defaultNodeIcon);
|
||||||
|
}
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.log(err.stack);
|
||||||
|
apiUtils.rejectHandler(req,res,err);
|
||||||
|
})
|
||||||
},
|
},
|
||||||
editor: function(req,res) {
|
editor: function(req,res) {
|
||||||
res.send(Mustache.render(editorTemplate,theme.context()));
|
res.send(Mustache.render(editorTemplate,theme.context()));
|
||||||
},
|
},
|
||||||
editorResources: express.static(__dirname + '/../../../public')
|
editorResources: express.static(path.join(editorClientDir,'public'))
|
||||||
};
|
};
|
34
red/api/index.js → packages/node_modules/@node-red/editor-api/lib/index.js
generated
vendored
@ -26,17 +26,21 @@ var apiUtil = require("./util");
|
|||||||
|
|
||||||
var adminApp;
|
var adminApp;
|
||||||
var server;
|
var server;
|
||||||
var runtime;
|
|
||||||
var editor;
|
var editor;
|
||||||
|
|
||||||
function init(_server,_runtime) {
|
function init(_server,settings,storage,runtimeAPI) {
|
||||||
server = _server;
|
server = _server;
|
||||||
runtime = _runtime;
|
|
||||||
var settings = runtime.settings;
|
|
||||||
if (settings.httpAdminRoot !== false) {
|
if (settings.httpAdminRoot !== false) {
|
||||||
apiUtil.init(runtime);
|
|
||||||
adminApp = express();
|
adminApp = express();
|
||||||
auth.init(runtime);
|
|
||||||
|
var cors = require('cors');
|
||||||
|
var corsHandler = cors({
|
||||||
|
origin: "*",
|
||||||
|
methods: "GET,PUT,POST,DELETE"
|
||||||
|
});
|
||||||
|
adminApp.use(corsHandler);
|
||||||
|
|
||||||
|
auth.init(settings,storage);
|
||||||
|
|
||||||
var maxApiRequestSize = settings.apiMaxLength || '5mb';
|
var maxApiRequestSize = settings.apiMaxLength || '5mb';
|
||||||
adminApp.use(bodyParser.json({limit:maxApiRequestSize}));
|
adminApp.use(bodyParser.json({limit:maxApiRequestSize}));
|
||||||
@ -61,7 +65,7 @@ function init(_server,_runtime) {
|
|||||||
// Editor
|
// Editor
|
||||||
if (!settings.disableEditor) {
|
if (!settings.disableEditor) {
|
||||||
editor = require("./editor");
|
editor = require("./editor");
|
||||||
var editorApp = editor.init(server, runtime);
|
var editorApp = editor.init(server, settings, runtimeAPI);
|
||||||
adminApp.use(editorApp);
|
adminApp.use(editorApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +74,7 @@ function init(_server,_runtime) {
|
|||||||
adminApp.use(corsHandler);
|
adminApp.use(corsHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
var adminApiApp = require("./admin").init(runtime);
|
var adminApiApp = require("./admin").init(runtimeAPI);
|
||||||
adminApp.use(adminApiApp);
|
adminApp.use(adminApiApp);
|
||||||
} else {
|
} else {
|
||||||
adminApp = null;
|
adminApp = null;
|
||||||
@ -93,23 +97,9 @@ module.exports = {
|
|||||||
init: init,
|
init: init,
|
||||||
start: start,
|
start: start,
|
||||||
stop: stop,
|
stop: stop,
|
||||||
library: {
|
|
||||||
register: function(type) {
|
|
||||||
if (editor) {
|
|
||||||
editor.registerLibrary(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
auth: {
|
auth: {
|
||||||
needsPermission: auth.needsPermission
|
needsPermission: auth.needsPermission
|
||||||
},
|
},
|
||||||
comms: {
|
|
||||||
publish: function(topic,data,retain) {
|
|
||||||
if (editor) {
|
|
||||||
editor.publish(topic,data,retain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
get adminApp() { return adminApp; },
|
get adminApp() { return adminApp; },
|
||||||
get server() { return server; }
|
get server() { return server; }
|
||||||
};
|
};
|
16
red/api/util.js → packages/node_modules/@node-red/editor-api/lib/util.js
generated
vendored
@ -15,16 +15,12 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
||||||
var i18n;
|
var log = require("@node-red/util").log; // TODO: separate module
|
||||||
var log;
|
var i18n = require("@node-red/util").i18n; // TODO: separate module
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function(_runtime) {
|
|
||||||
log = _runtime.log;
|
|
||||||
i18n = _runtime.i18n;
|
|
||||||
},
|
|
||||||
errorHandler: function(err,req,res,next) {
|
errorHandler: function(err,req,res,next) {
|
||||||
console.error(err.stack);
|
|
||||||
if (err.message === "request entity too large") {
|
if (err.message === "request entity too large") {
|
||||||
log.error(err);
|
log.error(err);
|
||||||
} else {
|
} else {
|
||||||
@ -41,5 +37,11 @@ module.exports = {
|
|||||||
lang = acceptedLanguages[0];
|
lang = acceptedLanguages[0];
|
||||||
}
|
}
|
||||||
return lang;
|
return lang;
|
||||||
|
},
|
||||||
|
rejectHandler: function(req,res,err) {
|
||||||
|
res.status(err.status||500).json({
|
||||||
|
code: err.code||"unexpected_error",
|
||||||
|
message: err.message||err.toString()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
33
packages/node_modules/@node-red/editor-api/package.json
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "@node-red/editor",
|
||||||
|
"version": "0.20.0",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"main": "./lib/index.js",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/node-red/node-red.git"
|
||||||
|
},
|
||||||
|
"contributors": [
|
||||||
|
{ "name": "Nick O'Leary" },
|
||||||
|
{ "name": "Dave Conway-Jones"}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"@node-red/util": "*",
|
||||||
|
"@node-red/editor-client": "*",
|
||||||
|
"bcryptjs": "2.4.3",
|
||||||
|
"body-parser": "1.18.3",
|
||||||
|
"clone": "2.1.2",
|
||||||
|
"cors": "2.8.4",
|
||||||
|
"express-session": "1.15.6",
|
||||||
|
"express": "4.16.3",
|
||||||
|
"memorystore": "1.6.0",
|
||||||
|
"mime": "1.4.1",
|
||||||
|
"mustache": "2.3.2",
|
||||||
|
"oauth2orize": "1.11.0",
|
||||||
|
"passport-http-bearer": "1.0.1",
|
||||||
|
"passport-oauth2-client-password": "0.1.2",
|
||||||
|
"passport": "0.4.0",
|
||||||
|
"when": "3.7.8",
|
||||||
|
"ws": "1.1.5"
|
||||||
|
}
|
||||||
|
}
|
1
packages/node_modules/@node-red/editor-client/.npmignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
src
|
178
packages/node_modules/@node-red/editor-client/LICENSE
generated
vendored
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
10
packages/node_modules/@node-red/editor-client/README.md
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@node-red/editor-client
|
||||||
|
====================
|
||||||
|
|
||||||
|
Node-RED editor resources module.
|
||||||
|
|
||||||
|
This provides all of the client-side resources of the Node-RED editor application.
|
||||||
|
|
||||||
|
### Source
|
||||||
|
|
||||||
|
The main Node-RED modules are maintained as a monorepo on [GitHub](https://github.com/node-red/node-red).
|
3
editor/js/red.js → packages/node_modules/@node-red/editor-client/index.js
generated
vendored
@ -13,4 +13,5 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
var RED = {};
|
|
||||||
|
module.exports = false
|
14
packages/node_modules/@node-red/editor-client/package.json
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "@node-red/editor-client",
|
||||||
|
"version": "0.20.0",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/node-red/node-red.git"
|
||||||
|
},
|
||||||
|
"contributors": [
|
||||||
|
{ "name": "Nick O'Leary" },
|
||||||
|
{ "name": "Dave Conway-Jones"}
|
||||||
|
],
|
||||||
|
"main": "./lib/index.js"
|
||||||
|
}
|
0
editor/favicon.ico → packages/node_modules/@node-red/editor-client/src/favicon.ico
generated
vendored
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 291 B After Width: | Height: | Size: 291 B |
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 368 B After Width: | Height: | Size: 368 B |
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 290 B |
Before Width: | Height: | Size: 392 B After Width: | Height: | Size: 392 B |
BIN
packages/node_modules/@node-red/editor-client/src/images/deploy-reload.png
generated
vendored
Normal file
After Width: | Height: | Size: 1015 B |
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 192 B |
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 393 B |
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 386 B |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 1019 B After Width: | Height: | Size: 1019 B |
Before Width: | Height: | Size: 600 B After Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 410 B After Width: | Height: | Size: 410 B |
Before Width: | Height: | Size: 638 B After Width: | Height: | Size: 638 B |
Before Width: | Height: | Size: 546 B After Width: | Height: | Size: 546 B |
Before Width: | Height: | Size: 638 B After Width: | Height: | Size: 638 B |
Before Width: | Height: | Size: 646 B After Width: | Height: | Size: 646 B |
Before Width: | Height: | Size: 809 B After Width: | Height: | Size: 809 B |
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 563 B |
Before Width: | Height: | Size: 588 B After Width: | Height: | Size: 588 B |
Before Width: | Height: | Size: 502 B After Width: | Height: | Size: 502 B |
14
editor/js/comms.js → packages/node_modules/@node-red/editor-client/src/js/comms.js
generated
vendored
@ -28,6 +28,15 @@ RED.comms = (function() {
|
|||||||
|
|
||||||
function connectWS() {
|
function connectWS() {
|
||||||
active = true;
|
active = true;
|
||||||
|
var wspath;
|
||||||
|
|
||||||
|
if (RED.settings.apiRootUrl) {
|
||||||
|
var m = /^(https?):\/\/(.*)$/.exec(RED.settings.apiRootUrl);
|
||||||
|
if (m) {
|
||||||
|
console.log(m);
|
||||||
|
wspath = "ws"+(m[1]==="https"?"s":"")+"://"+m[2]+"comms";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
var path = location.hostname;
|
var path = location.hostname;
|
||||||
var port = location.port;
|
var port = location.port;
|
||||||
if (port.length !== 0) {
|
if (port.length !== 0) {
|
||||||
@ -35,7 +44,8 @@ RED.comms = (function() {
|
|||||||
}
|
}
|
||||||
path = path+document.location.pathname;
|
path = path+document.location.pathname;
|
||||||
path = path+(path.slice(-1) == "/"?"":"/")+"comms";
|
path = path+(path.slice(-1) == "/"?"":"/")+"comms";
|
||||||
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path;
|
wspath = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path;
|
||||||
|
}
|
||||||
|
|
||||||
var auth_tokens = RED.settings.get("auth-tokens");
|
var auth_tokens = RED.settings.get("auth-tokens");
|
||||||
pendingAuth = (auth_tokens!=null);
|
pendingAuth = (auth_tokens!=null);
|
||||||
@ -48,7 +58,7 @@ RED.comms = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ws = new WebSocket(path);
|
ws = new WebSocket(wspath);
|
||||||
ws.onopen = function() {
|
ws.onopen = function() {
|
||||||
reconnectAttempts = 0;
|
reconnectAttempts = 0;
|
||||||
if (errornotification) {
|
if (errornotification) {
|
0
editor/js/events.js → packages/node_modules/@node-red/editor-client/src/js/events.js
generated
vendored
13
editor/js/i18n.js → packages/node_modules/@node-red/editor-client/src/js/i18n.js
generated
vendored
@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
RED.i18n = (function() {
|
RED.i18n = (function() {
|
||||||
|
|
||||||
|
var apiRootUrl;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: function(done) {
|
init: function(options, done) {
|
||||||
|
apiRootUrl = options.apiRootUrl||"";
|
||||||
i18n.init({
|
i18n.init({
|
||||||
resGetPath: 'locales/__ns__?lng=__lng__',
|
resGetPath: apiRootUrl+'locales/__ns__?lng=__lng__',
|
||||||
dynamicLoad: false,
|
dynamicLoad: false,
|
||||||
load:'current',
|
load:'current',
|
||||||
ns: {
|
ns: {
|
||||||
@ -36,7 +39,7 @@ RED.i18n = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
loadCatalog: function(namespace,done) {
|
loadNodeCatalog: function(namespace,done) {
|
||||||
var languageList = i18n.functions.toLanguages(i18n.detectLanguage());
|
var languageList = i18n.functions.toLanguages(i18n.detectLanguage());
|
||||||
var toLoad = languageList.length;
|
var toLoad = languageList.length;
|
||||||
languageList.forEach(function(lang) {
|
languageList.forEach(function(lang) {
|
||||||
@ -45,7 +48,7 @@ RED.i18n = (function() {
|
|||||||
"Accept":"application/json"
|
"Accept":"application/json"
|
||||||
},
|
},
|
||||||
cache: false,
|
cache: false,
|
||||||
url: 'locales/'+namespace+'?lng='+lang,
|
url: apiRootUrl+'nodes/'+namespace+'/messages?lng='+lang,
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
i18n.addResourceBundle(lang,namespace,data);
|
i18n.addResourceBundle(lang,namespace,data);
|
||||||
toLoad--;
|
toLoad--;
|
||||||
@ -68,7 +71,7 @@ RED.i18n = (function() {
|
|||||||
"Accept":"application/json"
|
"Accept":"application/json"
|
||||||
},
|
},
|
||||||
cache: false,
|
cache: false,
|
||||||
url: 'locales/nodes?lng='+lang,
|
url: apiRootUrl+'nodes/messages?lng='+lang,
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var namespaces = Object.keys(data);
|
var namespaces = Object.keys(data);
|
||||||
namespaces.forEach(function(ns) {
|
namespaces.forEach(function(ns) {
|
24
packages/node_modules/@node-red/editor-client/src/js/main.js
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
if ((window.location.hostname !== "localhost") && (window.location.hostname !== "127.0.0.1")) {
|
||||||
|
document.title = document.title+" : "+window.location.hostname;
|
||||||
|
}
|
||||||
|
RED.init({
|
||||||
|
apiRootUrl: ""
|
||||||
|
});
|
||||||
|
});
|
0
editor/js/nodes.js → packages/node_modules/@node-red/editor-client/src/js/nodes.js
generated
vendored
88
editor/js/main.js → packages/node_modules/@node-red/editor-client/src/js/red.js
generated
vendored
@ -13,9 +13,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
(function() {
|
var RED = (function() {
|
||||||
|
|
||||||
function appendNodeConfig(nodeConfig) {
|
function appendNodeConfig(nodeConfig,done) {
|
||||||
|
done = done || function(){};
|
||||||
var m = /<!-- --- \[red-module:(\S+)\] --- -->/.exec(nodeConfig.trim());
|
var m = /<!-- --- \[red-module:(\S+)\] --- -->/.exec(nodeConfig.trim());
|
||||||
var moduleId;
|
var moduleId;
|
||||||
if (m) {
|
if (m) {
|
||||||
@ -24,13 +25,31 @@
|
|||||||
moduleId = "unknown";
|
moduleId = "unknown";
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$("body").append(nodeConfig);
|
var hasDeferred = false;
|
||||||
|
|
||||||
|
var nodeConfigEls = $("<div>"+nodeConfig+"</div>");
|
||||||
|
nodeConfigEls.find("script").each(function(i,el) {
|
||||||
|
var srcUrl = $(el).attr('src');
|
||||||
|
if (srcUrl && !/^\s*(https?:|\/|\.)/.test(srcUrl)) {
|
||||||
|
$(el).remove();
|
||||||
|
var newScript = document.createElement("script");
|
||||||
|
newScript.onload = function() { $("body").append(nodeConfigEls); done() }
|
||||||
|
$('body').append(newScript);
|
||||||
|
newScript.src = RED.settings.apiRootUrl+srcUrl;
|
||||||
|
hasDeferred = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (!hasDeferred) {
|
||||||
|
$("body").append(nodeConfigEls);
|
||||||
|
done();
|
||||||
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
RED.notify(RED._("notification.errors.failedToAppendNode",{module:moduleId, error:err.toString()}),{
|
RED.notify(RED._("notification.errors.failedToAppendNode",{module:moduleId, error:err.toString()}),{
|
||||||
type: "error",
|
type: "error",
|
||||||
timeout: 10000
|
timeout: 10000
|
||||||
});
|
});
|
||||||
console.log("["+moduleId+"] "+err.toString());
|
console.log("["+moduleId+"] "+err.toString());
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,10 +94,8 @@
|
|||||||
url: 'nodes',
|
url: 'nodes',
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var configs = data.trim().split(/(?=<!-- --- \[red-module:\S+\] --- -->)/);
|
var configs = data.trim().split(/(?=<!-- --- \[red-module:\S+\] --- -->)/);
|
||||||
configs.forEach(function(data) {
|
var stepConfig = function() {
|
||||||
appendNodeConfig(data);
|
if (configs.length === 0) {
|
||||||
});
|
|
||||||
|
|
||||||
$("body").i18n();
|
$("body").i18n();
|
||||||
$("#palette > .palette-spinner").hide();
|
$("#palette > .palette-spinner").hide();
|
||||||
$(".palette-scroll").removeClass("hide");
|
$(".palette-scroll").removeClass("hide");
|
||||||
@ -105,6 +122,12 @@
|
|||||||
completeLoad();
|
completeLoad();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
var config = configs.shift();
|
||||||
|
appendNodeConfig(config,stepConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stepConfig();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -207,7 +230,7 @@
|
|||||||
if (RED.user.hasPermission("projects.write")) {
|
if (RED.user.hasPermission("projects.write")) {
|
||||||
options.buttons = [
|
options.buttons = [
|
||||||
{
|
{
|
||||||
text: RED._("notification.label.setup-cred"),
|
text: "Setup credentials",
|
||||||
click: function() {
|
click: function() {
|
||||||
persistentNotifications[notificationId].hideNotification();
|
persistentNotifications[notificationId].hideNotification();
|
||||||
RED.projects.showCredentialsPrompt();
|
RED.projects.showCredentialsPrompt();
|
||||||
@ -218,7 +241,7 @@
|
|||||||
} else {
|
} else {
|
||||||
options.buttons = [
|
options.buttons = [
|
||||||
{
|
{
|
||||||
text: RED._("common.label.close"),
|
text: "Close",
|
||||||
click: function() {
|
click: function() {
|
||||||
persistentNotifications[notificationId].hideNotification();
|
persistentNotifications[notificationId].hideNotification();
|
||||||
}
|
}
|
||||||
@ -229,7 +252,7 @@
|
|||||||
if (RED.user.hasPermission("projects.write")) {
|
if (RED.user.hasPermission("projects.write")) {
|
||||||
options.buttons = [
|
options.buttons = [
|
||||||
{
|
{
|
||||||
text: RED._("notification.label.setup-project"),
|
text: "Setup project files",
|
||||||
click: function() {
|
click: function() {
|
||||||
persistentNotifications[notificationId].hideNotification();
|
persistentNotifications[notificationId].hideNotification();
|
||||||
RED.projects.showFilesPrompt();
|
RED.projects.showFilesPrompt();
|
||||||
@ -241,7 +264,7 @@
|
|||||||
if (RED.user.hasPermission("projects.write")) {
|
if (RED.user.hasPermission("projects.write")) {
|
||||||
options.buttons = [
|
options.buttons = [
|
||||||
{
|
{
|
||||||
text: RED._("notification.label.create-default-package"),
|
text: "Create default package file",
|
||||||
click: function() {
|
click: function() {
|
||||||
persistentNotifications[notificationId].hideNotification();
|
persistentNotifications[notificationId].hideNotification();
|
||||||
RED.projects.createDefaultPackageFile();
|
RED.projects.createDefaultPackageFile();
|
||||||
@ -253,13 +276,13 @@
|
|||||||
if (RED.user.hasPermission("projects.write")) {
|
if (RED.user.hasPermission("projects.write")) {
|
||||||
options.buttons = [
|
options.buttons = [
|
||||||
{
|
{
|
||||||
text: RED._("notification.label.no-thanks"),
|
text: "No thanks",
|
||||||
click: function() {
|
click: function() {
|
||||||
persistentNotifications[notificationId].hideNotification();
|
persistentNotifications[notificationId].hideNotification();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: RED._("notification.label.create-default-project"),
|
text: "Create default project files",
|
||||||
click: function() {
|
click: function() {
|
||||||
persistentNotifications[notificationId].hideNotification();
|
persistentNotifications[notificationId].hideNotification();
|
||||||
RED.projects.createDefaultFileSet();
|
RED.projects.createDefaultFileSet();
|
||||||
@ -273,7 +296,7 @@
|
|||||||
if (RED.user.hasPermission("projects.write")) {
|
if (RED.user.hasPermission("projects.write")) {
|
||||||
options.buttons = [
|
options.buttons = [
|
||||||
{
|
{
|
||||||
text: RED._("notification.label.show-merge-conflicts"),
|
text: "Show merge conflicts",
|
||||||
click: function() {
|
click: function() {
|
||||||
persistentNotifications[notificationId].hideNotification();
|
persistentNotifications[notificationId].hideNotification();
|
||||||
RED.sidebar.versionControl.showLocalChanges();
|
RED.sidebar.versionControl.showLocalChanges();
|
||||||
@ -317,7 +340,7 @@
|
|||||||
var id = m.id;
|
var id = m.id;
|
||||||
RED.nodes.addNodeSet(m);
|
RED.nodes.addNodeSet(m);
|
||||||
addedTypes = addedTypes.concat(m.types);
|
addedTypes = addedTypes.concat(m.types);
|
||||||
RED.i18n.loadCatalog(id, function() {
|
RED.i18n.loadNodeCatalog(id, function() {
|
||||||
$.get('nodes/'+id, function(data) {
|
$.get('nodes/'+id, function(data) {
|
||||||
appendNodeConfig(data);
|
appendNodeConfig(data);
|
||||||
});
|
});
|
||||||
@ -382,10 +405,10 @@
|
|||||||
function loadEditor() {
|
function loadEditor() {
|
||||||
var menuOptions = [];
|
var menuOptions = [];
|
||||||
if (RED.settings.theme("projects.enabled",false)) {
|
if (RED.settings.theme("projects.enabled",false)) {
|
||||||
menuOptions.push({id:"menu-item-projects-menu",label:RED._("menu.label.projects"),options:[
|
menuOptions.push({id:"menu-item-projects-menu",label:"Projects",options:[
|
||||||
{id:"menu-item-projects-new",label:RED._("menu.label.projects-new"),disabled:false,onselect:"core:new-project"},
|
{id:"menu-item-projects-new",label:"New",disabled:false,onselect:"core:new-project"},
|
||||||
{id:"menu-item-projects-open",label:RED._("menu.label.projects-open"),disabled:false,onselect:"core:open-project"},
|
{id:"menu-item-projects-open",label:"Open",disabled:false,onselect:"core:open-project"},
|
||||||
{id:"menu-item-projects-settings",label:RED._("menu.label.projects-settings"),disabled:false,onselect:"core:show-project-settings"}
|
{id:"menu-item-projects-settings",label:"Project Settings",disabled:false,onselect:"core:show-project-settings"}
|
||||||
]});
|
]});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,16 +509,25 @@
|
|||||||
loadNodeList();
|
loadNodeList();
|
||||||
}
|
}
|
||||||
|
|
||||||
$(function() {
|
var initialised = false;
|
||||||
|
|
||||||
if ((window.location.hostname !== "localhost") && (window.location.hostname !== "127.0.0.1")) {
|
function init(options) {
|
||||||
document.title = document.title+" : "+window.location.hostname;
|
if (initialised) {
|
||||||
|
throw new Error("RED already initialised");
|
||||||
|
}
|
||||||
|
initialised = true;
|
||||||
|
ace.require("ace/ext/language_tools");
|
||||||
|
options = options || {};
|
||||||
|
options.apiRootUrl = options.apiRootUrl || "";
|
||||||
|
if (options.apiRootUrl && !/\/$/.test(options.apiRootUrl)) {
|
||||||
|
options.apiRootUrl = options.apiRootUrl+"/";
|
||||||
|
}
|
||||||
|
RED.i18n.init(options, function() {
|
||||||
|
RED.settings.init(options, loadEditor);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ace.require("ace/ext/language_tools");
|
return {
|
||||||
|
init: init
|
||||||
RED.i18n.init(function() {
|
}
|
||||||
RED.settings.init(loadEditor);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
})();
|
})();
|
@ -89,18 +89,22 @@ RED.settings = (function () {
|
|||||||
userSettings = data;
|
userSettings = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
var init = function (done) {
|
var init = function (options, done) {
|
||||||
var accessTokenMatch = /[?&]access_token=(.*?)(?:$|&)/.exec(window.location.search);
|
var accessTokenMatch = /[?&]access_token=(.*?)(?:$|&)/.exec(window.location.search);
|
||||||
if (accessTokenMatch) {
|
if (accessTokenMatch) {
|
||||||
var accessToken = accessTokenMatch[1];
|
var accessToken = accessTokenMatch[1];
|
||||||
RED.settings.set("auth-tokens",{access_token: accessToken});
|
RED.settings.set("auth-tokens",{access_token: accessToken});
|
||||||
window.location.search = "";
|
window.location.search = "";
|
||||||
}
|
}
|
||||||
|
RED.settings.apiRootUrl = options.apiRootUrl;
|
||||||
|
|
||||||
$.ajaxSetup({
|
$.ajaxSetup({
|
||||||
beforeSend: function(jqXHR,settings) {
|
beforeSend: function(jqXHR,settings) {
|
||||||
// Only attach auth header for requests to relative paths
|
// Only attach auth header for requests to relative paths
|
||||||
if (!/^\s*(https?:|\/|\.)/.test(settings.url)) {
|
if (!/^\s*(https?:|\/|\.)/.test(settings.url)) {
|
||||||
|
if (options.apiRootUrl) {
|
||||||
|
settings.url = options.apiRootUrl+settings.url;
|
||||||
|
}
|
||||||
var auth_tokens = RED.settings.get("auth-tokens");
|
var auth_tokens = RED.settings.get("auth-tokens");
|
||||||
if (auth_tokens) {
|
if (auth_tokens) {
|
||||||
jqXHR.setRequestHeader("Authorization","Bearer "+auth_tokens.access_token);
|
jqXHR.setRequestHeader("Authorization","Bearer "+auth_tokens.access_token);
|
@ -67,7 +67,10 @@ RED.deploy = (function() {
|
|||||||
options: [
|
options: [
|
||||||
{id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.png",label:RED._("deploy.full"),sublabel:RED._("deploy.fullDesc"),selected: true, onselect:function(s) { if(s){changeDeploymentType("full")}}},
|
{id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.png",label:RED._("deploy.full"),sublabel:RED._("deploy.fullDesc"),selected: true, onselect:function(s) { if(s){changeDeploymentType("full")}}},
|
||||||
{id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.png",label:RED._("deploy.modifiedFlows"),sublabel:RED._("deploy.modifiedFlowsDesc"), onselect:function(s) {if(s){changeDeploymentType("flows")}}},
|
{id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.png",label:RED._("deploy.modifiedFlows"),sublabel:RED._("deploy.modifiedFlowsDesc"), onselect:function(s) {if(s){changeDeploymentType("flows")}}},
|
||||||
{id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.png",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}}
|
{id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.png",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}},
|
||||||
|
null,
|
||||||
|
{id:"deploymenu-item-reload", icon:"red/images/deploy-reload.png",label:RED._("deploy.restartFlows"),sublabel:RED._("deploy.restartFlowsDesc"),onselect:"core:restart-flows"},
|
||||||
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
} else if (type == "simple") {
|
} else if (type == "simple") {
|
||||||
@ -96,6 +99,7 @@ RED.deploy = (function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
RED.actions.add("core:deploy-flows",save);
|
RED.actions.add("core:deploy-flows",save);
|
||||||
|
RED.actions.add("core:restart-flows",restart);
|
||||||
|
|
||||||
|
|
||||||
RED.events.on('nodes:change',function(state) {
|
RED.events.on('nodes:change',function(state) {
|
||||||
@ -257,6 +261,56 @@ RED.deploy = (function() {
|
|||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function restart() {
|
||||||
|
var startTime = Date.now();
|
||||||
|
$(".deploy-button-content").css('opacity',0);
|
||||||
|
$(".deploy-button-spinner").show();
|
||||||
|
var deployWasEnabled = !$("#btn-deploy").hasClass("disabled");
|
||||||
|
$("#btn-deploy").addClass("disabled");
|
||||||
|
deployInflight = true;
|
||||||
|
$("#header-shade").show();
|
||||||
|
$("#editor-shade").show();
|
||||||
|
$("#palette-shade").show();
|
||||||
|
$("#sidebar-shade").show();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url:"flows",
|
||||||
|
type: "POST",
|
||||||
|
headers: {
|
||||||
|
"Node-RED-Deployment-Type":"reload"
|
||||||
|
}
|
||||||
|
}).done(function(data,textStatus,xhr) {
|
||||||
|
if (deployWasEnabled) {
|
||||||
|
$("#btn-deploy").removeClass("disabled");
|
||||||
|
}
|
||||||
|
RED.notify('<p>'+RED._("deploy.successfulRestart")+'</p>',"success");
|
||||||
|
}).fail(function(xhr,textStatus,err) {
|
||||||
|
if (deployWasEnabled) {
|
||||||
|
$("#btn-deploy").removeClass("disabled");
|
||||||
|
}
|
||||||
|
if (xhr.status === 401) {
|
||||||
|
RED.notify(RED._("deploy.deployFailed",{message:RED._("user.notAuthorized")}),"error");
|
||||||
|
} else if (xhr.status === 409) {
|
||||||
|
resolveConflict(nns, true);
|
||||||
|
} else if (xhr.responseText) {
|
||||||
|
RED.notify(RED._("deploy.deployFailed",{message:xhr.responseText}),"error");
|
||||||
|
} else {
|
||||||
|
RED.notify(RED._("deploy.deployFailed",{message:RED._("deploy.errors.noResponse")}),"error");
|
||||||
|
}
|
||||||
|
}).always(function() {
|
||||||
|
deployInflight = false;
|
||||||
|
var delta = Math.max(0,300-(Date.now()-startTime));
|
||||||
|
setTimeout(function() {
|
||||||
|
$(".deploy-button-content").css('opacity',1);
|
||||||
|
$(".deploy-button-spinner").hide();
|
||||||
|
$("#header-shade").hide();
|
||||||
|
$("#editor-shade").hide();
|
||||||
|
$("#palette-shade").hide();
|
||||||
|
$("#sidebar-shade").hide();
|
||||||
|
},delta);
|
||||||
|
});
|
||||||
|
}
|
||||||
function save(skipValidation,force) {
|
function save(skipValidation,force) {
|
||||||
if (!$("#btn-deploy").hasClass("disabled")) {
|
if (!$("#btn-deploy").hasClass("disabled")) {
|
||||||
if (!RED.user.hasPermission("flows.write")) {
|
if (!RED.user.hasPermission("flows.write")) {
|