node-red-contrib-couchdb-nodes 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +311 -0
- package/package.json +56 -0
- package/src/nodes/create-db/couchdb-create-db.html +87 -0
- package/src/nodes/create-db/couchdb-create-db.js +52 -0
- package/src/nodes/delete-db/couchdb-delete-db.html +108 -0
- package/src/nodes/delete-db/couchdb-delete-db.js +59 -0
- package/src/nodes/get/couchdb-get.html +78 -0
- package/src/nodes/get/couchdb-get.js +63 -0
- package/src/nodes/index.js +33 -0
- package/src/nodes/insert/couchdb-insert.html +83 -0
- package/src/nodes/insert/couchdb-insert.js +64 -0
- package/src/nodes/list-dbs/couchdb-list-dbs.html +77 -0
- package/src/nodes/list-dbs/couchdb-list-dbs.js +48 -0
- package/src/nodes/list-docs/couchdb-list-docs.html +175 -0
- package/src/nodes/list-docs/couchdb-list-docs.js +101 -0
- package/src/nodes/query/couchdb-query.html +107 -0
- package/src/nodes/query/couchdb-query.js +67 -0
- package/src/nodes/server/couchdb-server.html +82 -0
- package/src/nodes/server/couchdb-server.js +17 -0
- package/src/nodes/update/couchdb-update.html +90 -0
- package/src/nodes/update/couchdb-update.js +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kanr
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# node-red-contrib-couchdb-nodes
|
|
2
|
+
|
|
3
|
+
Node-RED nodes for performing CRUD operations on Apache CouchDB databases.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/node-red-contrib-couchdb-nodes)
|
|
6
|
+
[](https://github.com/kanr/node-red-contrib-couchdb-nodes/actions)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Server Configuration**: Centralized CouchDB connection management with authentication
|
|
11
|
+
- **Document Operations**: Query, insert, get, and update documents
|
|
12
|
+
- **Database Management**: Create, delete, and list databases
|
|
13
|
+
- **View Queries**: Execute CouchDB views with filtering and pagination
|
|
14
|
+
- **Optimistic Concurrency**: Built-in revision control for safe updates
|
|
15
|
+
- **Error Handling**: Dual-output pattern for success/error flow separation
|
|
16
|
+
- **Pagination**: Support for limit/skip in queries and document listing
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Install via Node-RED's palette manager or run:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install node-red-contrib-couchdb-nodes
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Requirements
|
|
27
|
+
|
|
28
|
+
- **Node.js**: 10.0.0 or higher
|
|
29
|
+
- **Node-RED**: 1.0.0 or higher
|
|
30
|
+
- **CouchDB**: 2.0 or higher
|
|
31
|
+
|
|
32
|
+
## Available Nodes
|
|
33
|
+
|
|
34
|
+
### CouchDB Server (Configuration)
|
|
35
|
+
|
|
36
|
+
Configuration node that stores CouchDB connection details. Used by all operational nodes.
|
|
37
|
+
|
|
38
|
+
**Properties:**
|
|
39
|
+
- `hostname`: CouchDB server hostname (default: localhost)
|
|
40
|
+
- `port`: CouchDB port (default: 5984)
|
|
41
|
+
- `username`: Optional authentication username
|
|
42
|
+
- `password`: Optional authentication password (stored securely)
|
|
43
|
+
|
|
44
|
+
### CouchDB Query
|
|
45
|
+
|
|
46
|
+
Execute CouchDB view queries with filtering and pagination options.
|
|
47
|
+
|
|
48
|
+
**Inputs:**
|
|
49
|
+
- `msg.database` (optional): Override configured database
|
|
50
|
+
- `msg.view` (optional): Override configured view
|
|
51
|
+
- `msg.key` (optional): Filter by specific key
|
|
52
|
+
- `msg.limit` (optional): Maximum documents to return
|
|
53
|
+
- `msg.skip` (optional): Number of documents to skip
|
|
54
|
+
- `msg.include_docs` (optional): Include full documents in results
|
|
55
|
+
|
|
56
|
+
**Outputs:**
|
|
57
|
+
- **Output 1 (Success)**: `msg.payload` contains query results
|
|
58
|
+
- **Output 2 (Error)**: Error information
|
|
59
|
+
|
|
60
|
+
**Example:**
|
|
61
|
+
```javascript
|
|
62
|
+
msg.database = "products";
|
|
63
|
+
msg.view = "catalog/by_category";
|
|
64
|
+
msg.key = "electronics";
|
|
65
|
+
msg.limit = 10;
|
|
66
|
+
return msg;
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### CouchDB Insert
|
|
70
|
+
|
|
71
|
+
Insert new documents into CouchDB.
|
|
72
|
+
|
|
73
|
+
**Inputs:**
|
|
74
|
+
- `msg.payload`: Object to insert (must be a valid object, not string/array/null)
|
|
75
|
+
- `msg.database` (optional): Override configured database
|
|
76
|
+
|
|
77
|
+
**Outputs:**
|
|
78
|
+
- **Output 1 (Success)**: `msg.payload` contains inserted document with `_id` and `_rev`
|
|
79
|
+
- **Output 2 (Error)**: Error information
|
|
80
|
+
|
|
81
|
+
**Example:**
|
|
82
|
+
```javascript
|
|
83
|
+
msg.payload = {
|
|
84
|
+
type: "product",
|
|
85
|
+
name: "Laptop",
|
|
86
|
+
price: 999.99
|
|
87
|
+
};
|
|
88
|
+
return msg;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### CouchDB Get
|
|
92
|
+
|
|
93
|
+
Retrieve a specific document by ID.
|
|
94
|
+
|
|
95
|
+
**Inputs:**
|
|
96
|
+
- `msg.docId`: Document ID to retrieve
|
|
97
|
+
- `msg.database` (optional): Override configured database
|
|
98
|
+
|
|
99
|
+
**Outputs:**
|
|
100
|
+
- **Output 1 (Success)**: `msg.payload` contains the document
|
|
101
|
+
- **Output 2 (Error)**: Error information (e.g., 404 if not found)
|
|
102
|
+
|
|
103
|
+
**Example:**
|
|
104
|
+
```javascript
|
|
105
|
+
msg.docId = "product-12345";
|
|
106
|
+
return msg;
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### CouchDB Update
|
|
110
|
+
|
|
111
|
+
Update existing documents with optimistic concurrency control.
|
|
112
|
+
|
|
113
|
+
**Inputs:**
|
|
114
|
+
- `msg.payload`: Document object with `_id` and `_rev` fields
|
|
115
|
+
- `msg.database` (optional): Override configured database
|
|
116
|
+
|
|
117
|
+
**Important:** The document must include both `_id` and `_rev`. Use the Get node first to retrieve the current version.
|
|
118
|
+
|
|
119
|
+
**Outputs:**
|
|
120
|
+
- **Output 1 (Success)**: `msg.payload` contains updated document info with new `_rev`
|
|
121
|
+
- **Output 2 (Error)**: Error information (e.g., 409 conflict if document was modified)
|
|
122
|
+
|
|
123
|
+
**Example:**
|
|
124
|
+
```javascript
|
|
125
|
+
// First, get the document
|
|
126
|
+
// Then update it:
|
|
127
|
+
msg.payload._rev = "2-abc123"; // Current revision from Get node
|
|
128
|
+
msg.payload.price = 899.99; // Update field
|
|
129
|
+
return msg;
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### CouchDB Create DB
|
|
133
|
+
|
|
134
|
+
Create a new CouchDB database.
|
|
135
|
+
|
|
136
|
+
**Inputs:**
|
|
137
|
+
- `msg.database`: Name of database to create
|
|
138
|
+
|
|
139
|
+
**Outputs:**
|
|
140
|
+
- **Output 1 (Success)**: Confirmation message
|
|
141
|
+
- **Output 2 (Error)**: Error information
|
|
142
|
+
|
|
143
|
+
### CouchDB Delete DB
|
|
144
|
+
|
|
145
|
+
Delete a CouchDB database.
|
|
146
|
+
|
|
147
|
+
**Inputs:**
|
|
148
|
+
- `msg.database`: Name of database to delete
|
|
149
|
+
|
|
150
|
+
**Outputs:**
|
|
151
|
+
- **Output 1 (Success)**: Confirmation message
|
|
152
|
+
- **Output 2 (Error)**: Error information
|
|
153
|
+
|
|
154
|
+
### CouchDB List DBs
|
|
155
|
+
|
|
156
|
+
List all databases on the CouchDB server.
|
|
157
|
+
|
|
158
|
+
**Outputs:**
|
|
159
|
+
- **Output 1 (Success)**: `msg.payload` contains array of database names
|
|
160
|
+
- **Output 2 (Error)**: Error information
|
|
161
|
+
|
|
162
|
+
### CouchDB List Docs
|
|
163
|
+
|
|
164
|
+
List documents in a database with pagination support.
|
|
165
|
+
|
|
166
|
+
**Inputs:**
|
|
167
|
+
- `msg.database` (optional): Override configured database
|
|
168
|
+
- `msg.limit` (optional): Maximum documents to return
|
|
169
|
+
- `msg.skip` (optional): Number of documents to skip
|
|
170
|
+
- `msg.include_docs` (optional): Include full document content
|
|
171
|
+
|
|
172
|
+
**Outputs:**
|
|
173
|
+
- **Output 1 (Success)**: `msg.payload` contains document list
|
|
174
|
+
- **Output 2 (Error)**: Error information
|
|
175
|
+
|
|
176
|
+
## Usage Patterns
|
|
177
|
+
|
|
178
|
+
### Basic Query Flow
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
[Inject] → [CouchDB Query] → [Debug]
|
|
182
|
+
→ [Error Handler]
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Insert with Error Handling
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
[Function] → [CouchDB Insert] → [Success Handler]
|
|
189
|
+
→ [Error Logger]
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Update with Get-Modify-Update Pattern
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
[Inject] → [CouchDB Get] → [Function: Modify] → [CouchDB Update] → [Debug]
|
|
196
|
+
→ [Error Handler] → [Error Handler]
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Pagination Example
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
// In a Function node before CouchDB Query
|
|
203
|
+
var pageSize = 20;
|
|
204
|
+
var pageNumber = msg.page || 0;
|
|
205
|
+
|
|
206
|
+
msg.limit = pageSize;
|
|
207
|
+
msg.skip = pageNumber * pageSize;
|
|
208
|
+
msg.include_docs = true;
|
|
209
|
+
|
|
210
|
+
return msg;
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Error Handling
|
|
214
|
+
|
|
215
|
+
All operational nodes use a dual-output pattern:
|
|
216
|
+
|
|
217
|
+
- **First output**: Successful operations
|
|
218
|
+
- **Second output**: Errors (with detailed error information)
|
|
219
|
+
|
|
220
|
+
This allows you to route errors to dedicated error handling flows without cluttering your success path.
|
|
221
|
+
|
|
222
|
+
**Example error message:**
|
|
223
|
+
```javascript
|
|
224
|
+
{
|
|
225
|
+
error: {
|
|
226
|
+
message: "Document update conflict",
|
|
227
|
+
status: 409,
|
|
228
|
+
reason: "Document update conflict"
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## CouchDB Concepts
|
|
234
|
+
|
|
235
|
+
### Document Revisions
|
|
236
|
+
|
|
237
|
+
CouchDB uses `_rev` fields for optimistic concurrency control. Every document has a revision that changes with each update. When updating a document, you must provide the current `_rev` to prevent conflicts.
|
|
238
|
+
|
|
239
|
+
**Workflow:**
|
|
240
|
+
1. **Get** the document (retrieves current `_rev`)
|
|
241
|
+
2. **Modify** the document fields
|
|
242
|
+
3. **Update** with the current `_rev`
|
|
243
|
+
|
|
244
|
+
If another process updates the document between steps 1 and 3, you'll receive a 409 conflict error.
|
|
245
|
+
|
|
246
|
+
### Views
|
|
247
|
+
|
|
248
|
+
CouchDB views are stored queries defined in design documents. Views are referenced as `design_doc_name/view_name`.
|
|
249
|
+
|
|
250
|
+
**Example:** `catalog/by_category` refers to the `by_category` view in the `catalog` design document.
|
|
251
|
+
|
|
252
|
+
## Development
|
|
253
|
+
|
|
254
|
+
### Running Tests
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
npm test
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The test suite includes 37+ tests covering all node types and error conditions.
|
|
261
|
+
|
|
262
|
+
### Project Structure
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
src/nodes/
|
|
266
|
+
├── server/ Configuration node
|
|
267
|
+
├── query/ View queries
|
|
268
|
+
├── insert/ Document insertion
|
|
269
|
+
├── get/ Document retrieval
|
|
270
|
+
├── update/ Document updates
|
|
271
|
+
├── create-db/ Database creation
|
|
272
|
+
├── delete-db/ Database deletion
|
|
273
|
+
├── list-dbs/ List databases
|
|
274
|
+
└── list-docs/ List documents
|
|
275
|
+
|
|
276
|
+
test/nodes/ Test suite
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Contributing
|
|
280
|
+
|
|
281
|
+
Contributions are welcome! Please:
|
|
282
|
+
|
|
283
|
+
1. Fork the repository
|
|
284
|
+
2. Create a feature branch
|
|
285
|
+
3. Add tests for new functionality
|
|
286
|
+
4. Ensure all tests pass (`npm test`)
|
|
287
|
+
5. Submit a pull request
|
|
288
|
+
|
|
289
|
+
## License
|
|
290
|
+
|
|
291
|
+
MIT © kanr
|
|
292
|
+
|
|
293
|
+
## Links
|
|
294
|
+
|
|
295
|
+
- [GitHub Repository](https://github.com/kanr/node-red-contrib-couchdb-nodes)
|
|
296
|
+
- [npm Package](https://www.npmjs.com/package/node-red-contrib-couchdb-nodes)
|
|
297
|
+
- [Issue Tracker](https://github.com/kanr/node-red-contrib-couchdb-nodes/issues)
|
|
298
|
+
- [Apache CouchDB](https://couchdb.apache.org/)
|
|
299
|
+
- [Node-RED](https://nodered.org/)
|
|
300
|
+
|
|
301
|
+
## Changelog
|
|
302
|
+
|
|
303
|
+
### 1.0.0 (2026-02-21)
|
|
304
|
+
|
|
305
|
+
- Initial release
|
|
306
|
+
- CouchDB server configuration node
|
|
307
|
+
- Document operations: query, insert, get, update
|
|
308
|
+
- Database management: create, delete, list
|
|
309
|
+
- Document listing with pagination
|
|
310
|
+
- Comprehensive test coverage
|
|
311
|
+
- GitHub Actions CI/CD
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "node-red-contrib-couchdb-nodes",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Node-RED nodes for CouchDB CRUD operations",
|
|
5
|
+
"main": "src/nodes/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "mocha test/**/*.test.js --timeout 10000 --recursive"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"node-red",
|
|
11
|
+
"couchdb",
|
|
12
|
+
"database",
|
|
13
|
+
"crud"
|
|
14
|
+
],
|
|
15
|
+
"author": "kanr",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"node-red": {
|
|
18
|
+
"nodes": {
|
|
19
|
+
"couchdb-server": "src/nodes/server/couchdb-server.js",
|
|
20
|
+
"couchdb-insert": "src/nodes/insert/couchdb-insert.js",
|
|
21
|
+
"couchdb-get": "src/nodes/get/couchdb-get.js",
|
|
22
|
+
"couchdb-query": "src/nodes/query/couchdb-query.js",
|
|
23
|
+
"couchdb-update": "src/nodes/update/couchdb-update.js",
|
|
24
|
+
"couchdb-create-db": "src/nodes/create-db/couchdb-create-db.js",
|
|
25
|
+
"couchdb-delete-db": "src/nodes/delete-db/couchdb-delete-db.js",
|
|
26
|
+
"couchdb-list-dbs": "src/nodes/list-dbs/couchdb-list-dbs.js",
|
|
27
|
+
"couchdb-list-docs": "src/nodes/list-docs/couchdb-list-docs.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/kanr/node-red-contrib-couchdb-nodes.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/kanr/node-red-contrib-couchdb-nodes/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/kanr/node-red-contrib-couchdb-nodes#readme",
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"mocha": "^8.4.0",
|
|
40
|
+
"should": "^13.2.3"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"nano": "^10.0.0"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"src/",
|
|
47
|
+
"README.md",
|
|
48
|
+
"LICENSE"
|
|
49
|
+
],
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=10.0.0"
|
|
52
|
+
},
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('couchdb-create-db', {
|
|
3
|
+
category: 'couchdb',
|
|
4
|
+
color: '#ff6b00',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: { value: '' },
|
|
7
|
+
server: { type: 'couchdb-server', required: true },
|
|
8
|
+
dbname: { value: '' }
|
|
9
|
+
},
|
|
10
|
+
inputs: 1,
|
|
11
|
+
outputs: 2,
|
|
12
|
+
icon: 'db.png',
|
|
13
|
+
label: function() {
|
|
14
|
+
return this.name || 'CouchDB Create DB';
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<script type="text/x-red" data-template-name="couchdb-create-db">
|
|
20
|
+
<div class="form-row">
|
|
21
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
22
|
+
<input type="text" id="node-input-name" placeholder="Create Database">
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="form-row">
|
|
26
|
+
<label for="node-input-server"><i class="fa fa-server"></i> Server</label>
|
|
27
|
+
<input type="text" id="node-input-server">
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div class="form-row">
|
|
31
|
+
<label for="node-input-dbname"><i class="fa fa-database"></i> Database Name</label>
|
|
32
|
+
<input type="text" id="node-input-dbname" placeholder="e.g. my-new-database">
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div class="form-tips">
|
|
36
|
+
<p><strong>Input:</strong> Database name from config or msg.dbname or msg.payload</p>
|
|
37
|
+
<p><strong>Output 1 (Success):</strong> msg with result and dbname</p>
|
|
38
|
+
<p><strong>Output 2 (Error):</strong> msg with error information</p>
|
|
39
|
+
</div>
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<script type="text/x-red" data-help-name="couchdb-create-db">
|
|
43
|
+
<p>Creates a new database in CouchDB.</p>
|
|
44
|
+
|
|
45
|
+
<h3>Inputs</h3>
|
|
46
|
+
<dl class="message-properties">
|
|
47
|
+
<dt class="optional">dbname <span class="property-type">string</span></dt>
|
|
48
|
+
<dd>Database name to create (overrides node config if provided)</dd>
|
|
49
|
+
<dt class="optional">payload <span class="property-type">string</span></dt>
|
|
50
|
+
<dd>Database name if dbname not specified</dd>
|
|
51
|
+
</dl>
|
|
52
|
+
|
|
53
|
+
<h3>Outputs</h3>
|
|
54
|
+
<ol class="node-ports">
|
|
55
|
+
<li>Success Output
|
|
56
|
+
<dl class="message-properties">
|
|
57
|
+
<dt>result <span class="property-type">object</span></dt>
|
|
58
|
+
<dd>Result containing <code>ok: true</code></dd>
|
|
59
|
+
<dt>dbname <span class="property-type">string</span></dt>
|
|
60
|
+
<dd>The created database name</dd>
|
|
61
|
+
</dl>
|
|
62
|
+
</li>
|
|
63
|
+
<li>Error Output
|
|
64
|
+
<dl class="message-properties">
|
|
65
|
+
<dt>error <span class="property-type">object</span></dt>
|
|
66
|
+
<dd>Error details if creation fails (e.g., database already exists)</dd>
|
|
67
|
+
</dl>
|
|
68
|
+
</li>
|
|
69
|
+
</ol>
|
|
70
|
+
|
|
71
|
+
<h3>Details</h3>
|
|
72
|
+
<p>Creates a new database with the specified name. If the database already exists,
|
|
73
|
+
an error will be returned on the second output.</p>
|
|
74
|
+
|
|
75
|
+
<h3>Database Naming Rules</h3>
|
|
76
|
+
<ul>
|
|
77
|
+
<li>Must begin with a lowercase letter</li>
|
|
78
|
+
<li>Can contain lowercase letters (a-z), digits (0-9), and special characters (_, $, (, ), +, -, /)</li>
|
|
79
|
+
<li>Cannot start with an underscore (_) unless it's a system database</li>
|
|
80
|
+
</ul>
|
|
81
|
+
|
|
82
|
+
<h3>Example</h3>
|
|
83
|
+
<pre>
|
|
84
|
+
msg.dbname = "my-application-db";
|
|
85
|
+
return msg;
|
|
86
|
+
</pre>
|
|
87
|
+
</script>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module.exports = function(RED) {
|
|
2
|
+
function CouchDBCreateDBNode(config) {
|
|
3
|
+
RED.nodes.createNode(this, config);
|
|
4
|
+
const node = this;
|
|
5
|
+
|
|
6
|
+
const serverConfig = RED.nodes.getNode(config.server);
|
|
7
|
+
if (!serverConfig) {
|
|
8
|
+
node.error("CouchDB server not configured");
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const nano = require('nano');
|
|
13
|
+
const url = `http://${serverConfig.username}:${serverConfig.password}@${serverConfig.hostname}:${serverConfig.port}`;
|
|
14
|
+
const couchdb = nano(url);
|
|
15
|
+
|
|
16
|
+
node.on("input", function(msg) {
|
|
17
|
+
const dbName = config.dbname || msg.dbname || msg.payload;
|
|
18
|
+
|
|
19
|
+
if (!dbName) {
|
|
20
|
+
node.error("Database name not specified", msg);
|
|
21
|
+
node.status({fill: "red", shape: "ring", text: "no database name"});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
node.status({fill: "blue", shape: "dot", text: "creating..."});
|
|
26
|
+
|
|
27
|
+
couchdb.db.create(dbName, (err, body) => {
|
|
28
|
+
if (err) {
|
|
29
|
+
node.error(`Create database failed: ${err.message}`, msg);
|
|
30
|
+
node.status({fill: "red", shape: "ring", text: "failed"});
|
|
31
|
+
msg.error = {
|
|
32
|
+
message: err.message,
|
|
33
|
+
statusCode: err.statusCode,
|
|
34
|
+
reason: err.reason
|
|
35
|
+
};
|
|
36
|
+
node.send([null, msg]);
|
|
37
|
+
} else {
|
|
38
|
+
node.status({fill: "green", shape: "dot", text: "created"});
|
|
39
|
+
msg.result = body;
|
|
40
|
+
msg.dbname = dbName;
|
|
41
|
+
node.send([msg, null]);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
node.on("close", function() {
|
|
47
|
+
node.status({});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
RED.nodes.registerType("couchdb-create-db", CouchDBCreateDBNode);
|
|
52
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('couchdb-delete-db', {
|
|
3
|
+
category: 'couchdb',
|
|
4
|
+
color: '#ff6b00',
|
|
5
|
+
defaults: {
|
|
6
|
+
name: { value: '' },
|
|
7
|
+
server: { type: 'couchdb-server', required: true },
|
|
8
|
+
dbname: { value: '' },
|
|
9
|
+
confirmDelete: { value: false }
|
|
10
|
+
},
|
|
11
|
+
inputs: 1,
|
|
12
|
+
outputs: 2,
|
|
13
|
+
icon: 'db.png',
|
|
14
|
+
label: function() {
|
|
15
|
+
return this.name || 'CouchDB Delete DB';
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<script type="text/x-red" data-template-name="couchdb-delete-db">
|
|
21
|
+
<div class="form-row">
|
|
22
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
23
|
+
<input type="text" id="node-input-name" placeholder="Delete Database">
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div class="form-row">
|
|
27
|
+
<label for="node-input-server"><i class="fa fa-server"></i> Server</label>
|
|
28
|
+
<input type="text" id="node-input-server">
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div class="form-row">
|
|
32
|
+
<label for="node-input-dbname"><i class="fa fa-database"></i> Database Name</label>
|
|
33
|
+
<input type="text" id="node-input-dbname" placeholder="e.g. database-to-delete">
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div class="form-row">
|
|
37
|
+
<label for="node-input-confirmDelete">
|
|
38
|
+
<input type="checkbox" id="node-input-confirmDelete" style="display:inline-block; width:auto; vertical-align:baseline;">
|
|
39
|
+
<span> Confirm Delete (Required)</span>
|
|
40
|
+
</label>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div class="form-tips" style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 10px;">
|
|
44
|
+
<p><strong>⚠️ WARNING:</strong> This will permanently delete the database and ALL its documents!</p>
|
|
45
|
+
<p><strong>Input:</strong> Database name from config or msg.dbname or msg.payload</p>
|
|
46
|
+
<p><strong>Output 1 (Success):</strong> msg with result and dbname</p>
|
|
47
|
+
<p><strong>Output 2 (Error):</strong> msg with error information</p>
|
|
48
|
+
</div>
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<script type="text/x-red" data-help-name="couchdb-delete-db">
|
|
52
|
+
<p>Deletes a database from CouchDB.</p>
|
|
53
|
+
|
|
54
|
+
<h3>⚠️ WARNING</h3>
|
|
55
|
+
<p style="background-color: #fff3cd; padding: 10px; border-left: 4px solid #ffc107;">
|
|
56
|
+
<strong>This is a destructive operation!</strong><br>
|
|
57
|
+
Deleting a database will permanently remove the database and ALL documents within it.
|
|
58
|
+
This action cannot be undone.
|
|
59
|
+
</p>
|
|
60
|
+
|
|
61
|
+
<h3>Inputs</h3>
|
|
62
|
+
<dl class="message-properties">
|
|
63
|
+
<dt class="optional">dbname <span class="property-type">string</span></dt>
|
|
64
|
+
<dd>Database name to delete (overrides node config if provided)</dd>
|
|
65
|
+
<dt class="optional">payload <span class="property-type">string</span></dt>
|
|
66
|
+
<dd>Database name if dbname not specified</dd>
|
|
67
|
+
<dt class="optional">confirmDelete <span class="property-type">boolean</span></dt>
|
|
68
|
+
<dd>Set to <code>true</code> to confirm deletion (alternative to node config)</dd>
|
|
69
|
+
</dl>
|
|
70
|
+
|
|
71
|
+
<h3>Outputs</h3>
|
|
72
|
+
<ol class="node-ports">
|
|
73
|
+
<li>Success Output
|
|
74
|
+
<dl class="message-properties">
|
|
75
|
+
<dt>result <span class="property-type">object</span></dt>
|
|
76
|
+
<dd>Result containing <code>ok: true</code></dd>
|
|
77
|
+
<dt>dbname <span class="property-type">string</span></dt>
|
|
78
|
+
<dd>The deleted database name</dd>
|
|
79
|
+
</dl>
|
|
80
|
+
</li>
|
|
81
|
+
<li>Error Output
|
|
82
|
+
<dl class="message-properties">
|
|
83
|
+
<dt>error <span class="property-type">object</span></dt>
|
|
84
|
+
<dd>Error details if deletion fails (e.g., database not found)</dd>
|
|
85
|
+
</dl>
|
|
86
|
+
</li>
|
|
87
|
+
</ol>
|
|
88
|
+
|
|
89
|
+
<h3>Details</h3>
|
|
90
|
+
<p>Deletes the specified database. You must either:</p>
|
|
91
|
+
<ul>
|
|
92
|
+
<li>Check the "Confirm Delete" checkbox in the node configuration, OR</li>
|
|
93
|
+
<li>Set <code>msg.confirmDelete = true</code> in the flow</li>
|
|
94
|
+
</ul>
|
|
95
|
+
|
|
96
|
+
<h3>Safety</h3>
|
|
97
|
+
<p>The confirmation requirement helps prevent accidental database deletion.
|
|
98
|
+
Consider using a switch or function node to add additional safety checks
|
|
99
|
+
before deleting production databases.</p>
|
|
100
|
+
|
|
101
|
+
<h3>Example Flow</h3>
|
|
102
|
+
<pre>
|
|
103
|
+
// Function node before delete
|
|
104
|
+
msg.dbname = "temp-database";
|
|
105
|
+
msg.confirmDelete = true; // Required for safety
|
|
106
|
+
return msg;
|
|
107
|
+
</pre>
|
|
108
|
+
</script>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module.exports = function(RED) {
|
|
2
|
+
function CouchDBDeleteDBNode(config) {
|
|
3
|
+
RED.nodes.createNode(this, config);
|
|
4
|
+
const node = this;
|
|
5
|
+
|
|
6
|
+
const serverConfig = RED.nodes.getNode(config.server);
|
|
7
|
+
if (!serverConfig) {
|
|
8
|
+
node.error("CouchDB server not configured");
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const nano = require('nano');
|
|
13
|
+
const url = `http://${serverConfig.username}:${serverConfig.password}@${serverConfig.hostname}:${serverConfig.port}`;
|
|
14
|
+
const couchdb = nano(url);
|
|
15
|
+
|
|
16
|
+
node.on("input", function(msg) {
|
|
17
|
+
const dbName = config.dbname || msg.dbname || msg.payload;
|
|
18
|
+
|
|
19
|
+
if (!dbName) {
|
|
20
|
+
node.error("Database name not specified", msg);
|
|
21
|
+
node.status({fill: "red", shape: "ring", text: "no database name"});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Warning: Destructive operation
|
|
26
|
+
if (config.confirmDelete === false && !msg.confirmDelete) {
|
|
27
|
+
node.error("Delete operation requires confirmation", msg);
|
|
28
|
+
node.status({fill: "yellow", shape: "ring", text: "not confirmed"});
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
node.status({fill: "blue", shape: "dot", text: "deleting..."});
|
|
33
|
+
|
|
34
|
+
couchdb.db.destroy(dbName, (err, body) => {
|
|
35
|
+
if (err) {
|
|
36
|
+
node.error(`Delete database failed: ${err.message}`, msg);
|
|
37
|
+
node.status({fill: "red", shape: "ring", text: "failed"});
|
|
38
|
+
msg.error = {
|
|
39
|
+
message: err.message,
|
|
40
|
+
statusCode: err.statusCode,
|
|
41
|
+
reason: err.reason
|
|
42
|
+
};
|
|
43
|
+
node.send([null, msg]);
|
|
44
|
+
} else {
|
|
45
|
+
node.status({fill: "green", shape: "dot", text: "deleted"});
|
|
46
|
+
msg.result = body;
|
|
47
|
+
msg.dbname = dbName;
|
|
48
|
+
node.send([msg, null]);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
node.on("close", function() {
|
|
54
|
+
node.status({});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
RED.nodes.registerType("couchdb-delete-db", CouchDBDeleteDBNode);
|
|
59
|
+
};
|