fable 3.1.72 → 3.1.73
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/docs/README.md +30 -6
- package/docs/_brand.json +18 -0
- package/docs/_playground.json +10 -0
- package/docs/_sidebar.md +2 -0
- package/docs/_version.json +3 -3
- package/docs/architecture.md +201 -39
- package/docs/index.html +6 -7
- package/docs/pict-docuserve.min.js +91 -0
- package/docs/pict-docuserve.min.js.map +1 -0
- package/docs/playground.md +38 -0
- package/docs/retold-catalog.json +1 -1
- package/docs/retold-keyword-index.json +8721 -8105
- package/docs/services/README.md +26 -9
- package/docs/services/anticipate.md +104 -40
- package/docs/services/csv-parser.md +63 -35
- package/docs/services/data-format.md +154 -49
- package/docs/services/data-generation.md +77 -16
- package/docs/services/dates.md +103 -36
- package/docs/services/environment-data.md +13 -2
- package/docs/services/expression-parser.md +280 -68
- package/docs/services/file-persistence.md +142 -150
- package/docs/services/logging.md +93 -37
- package/docs/services/logic.md +70 -22
- package/docs/services/manifest.md +114 -26
- package/docs/services/math.md +168 -63
- package/docs/services/meta-template.md +312 -158
- package/docs/services/object-cache.md +94 -11
- package/docs/services/operation.md +68 -6
- package/docs/services/progress-time.md +74 -13
- package/docs/services/progress-tracker-set.md +101 -3
- package/docs/services/rest-client.md +136 -104
- package/docs/services/settings-manager.md +133 -40
- package/docs/services/template.md +71 -22
- package/docs/services/utility.md +121 -29
- package/docs/services/uuid.md +58 -10
- package/package.json +2 -2
- package/.claude/settings.local.json +0 -8
|
@@ -5,8 +5,12 @@ The ProgressTrackerSet service manages named progress trackers for tracking the
|
|
|
5
5
|
## Access
|
|
6
6
|
|
|
7
7
|
```javascript
|
|
8
|
+
const libFable = require('fable');
|
|
9
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
10
|
+
|
|
8
11
|
// On-demand service - instantiate when needed
|
|
9
12
|
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
13
|
+
console.log('trackerSet:', typeof trackerSet);
|
|
10
14
|
```
|
|
11
15
|
|
|
12
16
|
## Basic Usage
|
|
@@ -14,6 +18,8 @@ const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
|
14
18
|
### Create and Start a Tracker
|
|
15
19
|
|
|
16
20
|
```javascript
|
|
21
|
+
const libFable = require('fable');
|
|
22
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
17
23
|
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
18
24
|
|
|
19
25
|
// Create a tracker with 100 total operations
|
|
@@ -21,38 +27,62 @@ trackerSet.createProgressTracker('download', 100);
|
|
|
21
27
|
|
|
22
28
|
// Start the tracker (begins timing)
|
|
23
29
|
trackerSet.startProgressTracker('download');
|
|
30
|
+
console.log('Started:', trackerSet.getProgressTrackerStatusString('download'));
|
|
24
31
|
```
|
|
25
32
|
|
|
26
33
|
### Increment Progress
|
|
27
34
|
|
|
28
35
|
```javascript
|
|
36
|
+
const libFable = require('fable');
|
|
37
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
38
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
39
|
+
trackerSet.createProgressTracker('download', 100);
|
|
40
|
+
trackerSet.startProgressTracker('download');
|
|
41
|
+
|
|
29
42
|
// Increment by 1
|
|
30
43
|
trackerSet.incrementProgressTracker('download');
|
|
31
44
|
|
|
32
45
|
// Increment by a specific amount
|
|
33
46
|
trackerSet.incrementProgressTracker('download', 10);
|
|
47
|
+
|
|
48
|
+
console.log('Completed:', trackerSet.getProgressTrackerCompletedOperationCountString('download'));
|
|
34
49
|
```
|
|
35
50
|
|
|
36
51
|
### End the Tracker
|
|
37
52
|
|
|
38
53
|
```javascript
|
|
54
|
+
const libFable = require('fable');
|
|
55
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
56
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
57
|
+
trackerSet.createProgressTracker('download', 100);
|
|
58
|
+
trackerSet.startProgressTracker('download');
|
|
59
|
+
trackerSet.incrementProgressTracker('download', 100);
|
|
60
|
+
|
|
39
61
|
trackerSet.endProgressTracker('download');
|
|
62
|
+
console.log('End status:', trackerSet.getProgressTrackerStatusString('download'));
|
|
40
63
|
```
|
|
41
64
|
|
|
42
65
|
### Get Status
|
|
43
66
|
|
|
44
67
|
```javascript
|
|
68
|
+
const libFable = require('fable');
|
|
69
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
70
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
71
|
+
trackerSet.createProgressTracker('download', 100);
|
|
72
|
+
trackerSet.startProgressTracker('download');
|
|
73
|
+
trackerSet.incrementProgressTracker('download', 45);
|
|
74
|
+
|
|
45
75
|
// Get a human-readable status string
|
|
46
76
|
const status = trackerSet.getProgressTrackerStatusString('download');
|
|
47
|
-
|
|
77
|
+
console.log('status:', status);
|
|
48
78
|
|
|
49
79
|
// Get just the percent complete
|
|
50
80
|
const percent = trackerSet.getProgressTrackerPercentCompleteString('download');
|
|
51
|
-
|
|
81
|
+
console.log('percent:', percent);
|
|
52
82
|
|
|
53
83
|
// Get completed count
|
|
54
84
|
const count = trackerSet.getProgressTrackerCompletedOperationCountString('download');
|
|
55
|
-
|
|
85
|
+
console.log('count:', count);
|
|
56
86
|
|
|
57
87
|
// Log status directly
|
|
58
88
|
trackerSet.logProgressTrackerStatus('download');
|
|
@@ -65,7 +95,12 @@ trackerSet.logProgressTrackerStatus('download');
|
|
|
65
95
|
Create a new progress tracker. Default hash is `'Default'`, default total is `100`.
|
|
66
96
|
|
|
67
97
|
```javascript
|
|
98
|
+
const libFable = require('fable');
|
|
99
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
100
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
101
|
+
|
|
68
102
|
const tracker = trackerSet.createProgressTracker('import-records', 500);
|
|
103
|
+
console.log('Tracker data:', tracker);
|
|
69
104
|
```
|
|
70
105
|
|
|
71
106
|
Returns the tracker data object.
|
|
@@ -75,7 +110,12 @@ Returns the tracker data object.
|
|
|
75
110
|
Start timing a progress tracker. Creates the tracker if it doesn't exist.
|
|
76
111
|
|
|
77
112
|
```javascript
|
|
113
|
+
const libFable = require('fable');
|
|
114
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
115
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
116
|
+
|
|
78
117
|
trackerSet.startProgressTracker('import-records');
|
|
118
|
+
console.log('Started import-records');
|
|
79
119
|
```
|
|
80
120
|
|
|
81
121
|
### `endProgressTracker(hash)`
|
|
@@ -83,7 +123,13 @@ trackerSet.startProgressTracker('import-records');
|
|
|
83
123
|
Mark the tracker as complete, recording the end timestamp.
|
|
84
124
|
|
|
85
125
|
```javascript
|
|
126
|
+
const libFable = require('fable');
|
|
127
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
128
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
129
|
+
trackerSet.startProgressTracker('import-records');
|
|
130
|
+
|
|
86
131
|
trackerSet.endProgressTracker('import-records');
|
|
132
|
+
console.log('Ended import-records');
|
|
87
133
|
```
|
|
88
134
|
|
|
89
135
|
### `incrementProgressTracker(hash, amount)`
|
|
@@ -91,8 +137,15 @@ trackerSet.endProgressTracker('import-records');
|
|
|
91
137
|
Increment the current operation count. Defaults to incrementing by 1. Auto-starts the tracker if not started.
|
|
92
138
|
|
|
93
139
|
```javascript
|
|
140
|
+
const libFable = require('fable');
|
|
141
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
142
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
143
|
+
trackerSet.createProgressTracker('import-records', 100);
|
|
144
|
+
trackerSet.startProgressTracker('import-records');
|
|
145
|
+
|
|
94
146
|
trackerSet.incrementProgressTracker('import-records');
|
|
95
147
|
trackerSet.incrementProgressTracker('import-records', 5);
|
|
148
|
+
console.log('Completed:', trackerSet.getProgressTrackerCompletedOperationCountString('import-records'));
|
|
96
149
|
```
|
|
97
150
|
|
|
98
151
|
### `updateProgressTracker(hash, currentOperations)`
|
|
@@ -100,7 +153,14 @@ trackerSet.incrementProgressTracker('import-records', 5);
|
|
|
100
153
|
Set the current operation count to an absolute value.
|
|
101
154
|
|
|
102
155
|
```javascript
|
|
156
|
+
const libFable = require('fable');
|
|
157
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
158
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
159
|
+
trackerSet.createProgressTracker('import-records', 500);
|
|
160
|
+
trackerSet.startProgressTracker('import-records');
|
|
161
|
+
|
|
103
162
|
trackerSet.updateProgressTracker('import-records', 250);
|
|
163
|
+
console.log('Status:', trackerSet.getProgressTrackerStatusString('import-records'));
|
|
104
164
|
```
|
|
105
165
|
|
|
106
166
|
### `setProgressTrackerTotalOperations(hash, total)`
|
|
@@ -108,7 +168,13 @@ trackerSet.updateProgressTracker('import-records', 250);
|
|
|
108
168
|
Change the total number of expected operations.
|
|
109
169
|
|
|
110
170
|
```javascript
|
|
171
|
+
const libFable = require('fable');
|
|
172
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
173
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
174
|
+
trackerSet.createProgressTracker('import-records', 500);
|
|
175
|
+
|
|
111
176
|
trackerSet.setProgressTrackerTotalOperations('import-records', 1000);
|
|
177
|
+
console.log('Total updated; data:', trackerSet.getProgressTrackerData('import-records').TotalCount);
|
|
112
178
|
```
|
|
113
179
|
|
|
114
180
|
### `getProgressTracker(hash)`
|
|
@@ -116,9 +182,16 @@ trackerSet.setProgressTrackerTotalOperations('import-records', 1000);
|
|
|
116
182
|
Get a ProgressTracker wrapper object for a given hash. This provides convenience methods for working with the tracker:
|
|
117
183
|
|
|
118
184
|
```javascript
|
|
185
|
+
const libFable = require('fable');
|
|
186
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
187
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
188
|
+
trackerSet.createProgressTracker('import-records', 100);
|
|
189
|
+
trackerSet.startProgressTracker('import-records');
|
|
190
|
+
|
|
119
191
|
const tracker = trackerSet.getProgressTracker('import-records');
|
|
120
192
|
tracker.incrementProgressTracker(1);
|
|
121
193
|
tracker.setProgressTrackerTotalOperations(500);
|
|
194
|
+
console.log('Tracker after wrapper ops:', trackerSet.getProgressTrackerData('import-records'));
|
|
122
195
|
```
|
|
123
196
|
|
|
124
197
|
### `getProgressTrackerData(hash)`
|
|
@@ -126,7 +199,15 @@ tracker.setProgressTrackerTotalOperations(500);
|
|
|
126
199
|
Get the raw tracker data object:
|
|
127
200
|
|
|
128
201
|
```javascript
|
|
202
|
+
const libFable = require('fable');
|
|
203
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
204
|
+
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
205
|
+
trackerSet.createProgressTracker('import-records', 100);
|
|
206
|
+
trackerSet.startProgressTracker('import-records');
|
|
207
|
+
trackerSet.incrementProgressTracker('import-records', 45);
|
|
208
|
+
|
|
129
209
|
const data = trackerSet.getProgressTrackerData('import-records');
|
|
210
|
+
console.log(data);
|
|
130
211
|
// {
|
|
131
212
|
// Hash: 'import-records',
|
|
132
213
|
// StartTimeStamp: 1700000000000,
|
|
@@ -162,6 +243,12 @@ Each tracker data object contains:
|
|
|
162
243
|
### Batch Processing with Progress
|
|
163
244
|
|
|
164
245
|
```javascript
|
|
246
|
+
const libFable = require('fable');
|
|
247
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
248
|
+
|
|
249
|
+
// Stubbed processItem for the playground demo
|
|
250
|
+
function processItem(item, cb) { console.log('processed:', item); cb(); }
|
|
251
|
+
|
|
165
252
|
function processBatch(fable, items, fCallback) {
|
|
166
253
|
const trackerSet = fable.instantiateServiceProvider('ProgressTrackerSet');
|
|
167
254
|
|
|
@@ -190,6 +277,8 @@ function processBatch(fable, items, fCallback) {
|
|
|
190
277
|
fCallback();
|
|
191
278
|
});
|
|
192
279
|
}
|
|
280
|
+
|
|
281
|
+
processBatch(fable, ['a', 'b', 'c', 'd'], () => console.log('Batch done.'));
|
|
193
282
|
```
|
|
194
283
|
|
|
195
284
|
### Integration with Operation Service
|
|
@@ -197,6 +286,13 @@ function processBatch(fable, items, fCallback) {
|
|
|
197
286
|
The Operation service uses ProgressTrackerSet internally. Each step gets its own progress tracker, and the overall operation has one too. Inside a step, use `this.ProgressTracker`:
|
|
198
287
|
|
|
199
288
|
```javascript
|
|
289
|
+
const libFable = require('fable');
|
|
290
|
+
const fable = new libFable({ Product: 'TrackerDemo', ProductVersion: '1.0.0' });
|
|
291
|
+
|
|
292
|
+
const operation = fable.instantiateServiceProvider('Operation', { Name: 'Items' }, 'ITEMS-OP');
|
|
293
|
+
const items = ['a', 'b', 'c'];
|
|
294
|
+
function processItem(item) { console.log('processed:', item); }
|
|
295
|
+
|
|
200
296
|
operation.addStep(
|
|
201
297
|
function (fStepComplete) {
|
|
202
298
|
this.ProgressTracker.setProgressTrackerTotalOperations(items.length);
|
|
@@ -211,6 +307,8 @@ operation.addStep(
|
|
|
211
307
|
},
|
|
212
308
|
{}, 'Process', 'Process all items', 'PROCESS'
|
|
213
309
|
);
|
|
310
|
+
|
|
311
|
+
operation.execute((pError) => console.log('Op done — pError:', pError));
|
|
214
312
|
```
|
|
215
313
|
|
|
216
314
|
## Notes
|
|
@@ -5,12 +5,17 @@ The RestClient service provides HTTP/REST client functionality with support for
|
|
|
5
5
|
## Access
|
|
6
6
|
|
|
7
7
|
```javascript
|
|
8
|
+
const libFable = require('fable');
|
|
9
|
+
const fable = new libFable({ Product: 'RestClientDemo', ProductVersion: '1.0.0' });
|
|
10
|
+
|
|
8
11
|
// On-demand service - must be instantiated
|
|
9
12
|
const restClient = fable.instantiateServiceProvider('RestClient');
|
|
13
|
+
console.log('restClient:', typeof restClient);
|
|
10
14
|
|
|
11
15
|
// Or create named instances for different purposes
|
|
12
|
-
const apiClient
|
|
16
|
+
const apiClient = fable.instantiateServiceProvider('RestClient', {}, 'api');
|
|
13
17
|
const authClient = fable.instantiateServiceProvider('RestClient', { TraceLog: true }, 'auth');
|
|
18
|
+
console.log('Named instances ready:', typeof apiClient, typeof authClient);
|
|
14
19
|
```
|
|
15
20
|
|
|
16
21
|
## Configuration
|
|
@@ -18,9 +23,13 @@ const authClient = fable.instantiateServiceProvider('RestClient', { TraceLog: tr
|
|
|
18
23
|
### Options
|
|
19
24
|
|
|
20
25
|
```javascript
|
|
26
|
+
const libFable = require('fable');
|
|
27
|
+
const fable = new libFable({ Product: 'RestClientDemo', ProductVersion: '1.0.0' });
|
|
28
|
+
|
|
21
29
|
const restClient = fable.instantiateServiceProvider('RestClient', {
|
|
22
30
|
TraceLog: true // Enable request/response logging
|
|
23
31
|
});
|
|
32
|
+
console.log('TraceLog enabled:', restClient.options.TraceLog);
|
|
24
33
|
```
|
|
25
34
|
|
|
26
35
|
### URL Prefix
|
|
@@ -28,12 +37,15 @@ const restClient = fable.instantiateServiceProvider('RestClient', {
|
|
|
28
37
|
Set a global URL prefix in Fable settings:
|
|
29
38
|
|
|
30
39
|
```javascript
|
|
31
|
-
const
|
|
40
|
+
const libFable = require('fable');
|
|
41
|
+
const fable = new libFable({
|
|
32
42
|
RestClientURLPrefix: 'https://api.example.com'
|
|
33
43
|
});
|
|
44
|
+
console.log('URL prefix:', fable.settings.RestClientURLPrefix);
|
|
34
45
|
|
|
35
|
-
//
|
|
36
|
-
restClient.getJSON('/users', callback); // Requests https://api.example.com/users
|
|
46
|
+
// In Node.js (network calls are skipped in the browser playground):
|
|
47
|
+
// restClient.getJSON('/users', callback); // -> Requests https://api.example.com/users
|
|
48
|
+
console.info(" restClient.getJSON('/users', callback); // -> https://api.example.com/users");
|
|
37
49
|
```
|
|
38
50
|
|
|
39
51
|
## JSON Requests
|
|
@@ -41,86 +53,73 @@ restClient.getJSON('/users', callback); // Requests https://api.example.com/use
|
|
|
41
53
|
### GET JSON
|
|
42
54
|
|
|
43
55
|
```javascript
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
headers: {
|
|
58
|
-
'Authorization': 'Bearer token123'
|
|
59
|
-
}
|
|
60
|
-
}, (error, response, data) => {
|
|
61
|
-
console.log(data);
|
|
62
|
-
});
|
|
56
|
+
// Node.js reference — real HTTP requests don't run in the browser playground (CORS).
|
|
57
|
+
console.info("In Node.js:");
|
|
58
|
+
console.info(" // Simple URL");
|
|
59
|
+
console.info(" restClient.getJSON('https://api.example.com/users', (error, response, data) => {");
|
|
60
|
+
console.info(" if (error) { console.error('Request failed:', error); return; }");
|
|
61
|
+
console.info(" console.log('Status:', response.statusCode);");
|
|
62
|
+
console.info(" console.log('Data:', data); // Parsed JSON");
|
|
63
|
+
console.info(" });");
|
|
64
|
+
console.info(" // With options");
|
|
65
|
+
console.info(" restClient.getJSON({");
|
|
66
|
+
console.info(" url: 'https://api.example.com/users',");
|
|
67
|
+
console.info(" headers: { Authorization: 'Bearer token123' }");
|
|
68
|
+
console.info(" }, (error, response, data) => { console.log(data); });");
|
|
63
69
|
```
|
|
64
70
|
|
|
65
71
|
### POST JSON
|
|
66
72
|
|
|
67
73
|
```javascript
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
email: 'john@example.com'
|
|
73
|
-
}
|
|
74
|
-
}, (error, response, data) => {
|
|
75
|
-
console.log('Created user:', data);
|
|
76
|
-
});
|
|
74
|
+
// Node.js reference — real HTTP requests don't run in the browser playground.
|
|
75
|
+
console.info("In Node.js:");
|
|
76
|
+
console.info(" restClient.postJSON({");
|
|
77
|
+
console.info(" url: 'https://api.example.com/users',");
|
|
78
|
+
console.info(" body: { name: 'John Doe', email: 'john@example.com' }");
|
|
79
|
+
console.info(" }, (error, response, data) => { console.log('Created user:', data); });");
|
|
77
80
|
```
|
|
78
81
|
|
|
79
82
|
### PUT JSON
|
|
80
83
|
|
|
81
84
|
```javascript
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}, (error, response, data) => {
|
|
88
|
-
console.log('Updated user:', data);
|
|
89
|
-
});
|
|
85
|
+
// Node.js reference — real HTTP requests don't run in the browser playground.
|
|
86
|
+
console.info("In Node.js:");
|
|
87
|
+
console.info(" restClient.putJSON({");
|
|
88
|
+
console.info(" url: 'https://api.example.com/users/123',");
|
|
89
|
+
console.info(" body: { name: 'John Smith' }");
|
|
90
|
+
console.info(" }, (error, response, data) => { console.log('Updated user:', data); });");
|
|
90
91
|
```
|
|
91
92
|
|
|
92
93
|
### PATCH JSON
|
|
93
94
|
|
|
94
95
|
```javascript
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}, (error, response, data) => {
|
|
101
|
-
console.log('Patched user:', data);
|
|
102
|
-
});
|
|
96
|
+
// Node.js reference — real HTTP requests don't run in the browser playground.
|
|
97
|
+
console.info("In Node.js:");
|
|
98
|
+
console.info(" restClient.patchJSON({");
|
|
99
|
+
console.info(" url: 'https://api.example.com/users/123',");
|
|
100
|
+
console.info(" body: { email: 'john.smith@example.com' }");
|
|
101
|
+
console.info(" }, (error, response, data) => { console.log('Patched user:', data); });");
|
|
103
102
|
```
|
|
104
103
|
|
|
105
104
|
### DELETE JSON
|
|
106
105
|
|
|
107
106
|
```javascript
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
107
|
+
// Node.js reference — real HTTP requests don't run in the browser playground.
|
|
108
|
+
console.info("In Node.js:");
|
|
109
|
+
console.info(" restClient.delJSON({");
|
|
110
|
+
console.info(" url: 'https://api.example.com/users/123'");
|
|
111
|
+
console.info(" }, (error, response, data) => { console.log('Deleted user'); });");
|
|
113
112
|
```
|
|
114
113
|
|
|
115
114
|
### HEAD JSON
|
|
116
115
|
|
|
117
116
|
```javascript
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
});
|
|
117
|
+
// Node.js reference — real HTTP requests don't run in the browser playground.
|
|
118
|
+
console.info("In Node.js:");
|
|
119
|
+
console.info(" restClient.headJSON({");
|
|
120
|
+
console.info(" url: 'https://api.example.com/users/123',");
|
|
121
|
+
console.info(" body: {} // Required but not sent");
|
|
122
|
+
console.info(" }, (error, response, data) => { console.log('Headers:', response.headers); });");
|
|
124
123
|
```
|
|
125
124
|
|
|
126
125
|
## Raw Text Requests
|
|
@@ -128,9 +127,11 @@ restClient.headJSON({
|
|
|
128
127
|
### GET Raw Text
|
|
129
128
|
|
|
130
129
|
```javascript
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
130
|
+
// Node.js reference — real HTTP requests don't run in the browser playground.
|
|
131
|
+
console.info("In Node.js:");
|
|
132
|
+
console.info(" restClient.getRawText('https://example.com/page.html', (error, response, text) => {");
|
|
133
|
+
console.info(" console.log('HTML:', text);");
|
|
134
|
+
console.info(" });");
|
|
134
135
|
```
|
|
135
136
|
|
|
136
137
|
## Chunked Requests
|
|
@@ -140,24 +141,26 @@ For streaming or large responses:
|
|
|
140
141
|
### Text Chunks
|
|
141
142
|
|
|
142
143
|
```javascript
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
});
|
|
144
|
+
// Node.js reference — real HTTP requests don't run in the browser playground.
|
|
145
|
+
console.info("In Node.js:");
|
|
146
|
+
console.info(" restClient.executeChunkedRequest({");
|
|
147
|
+
console.info(" method: 'GET',");
|
|
148
|
+
console.info(" url: 'https://example.com/large-file.txt'");
|
|
149
|
+
console.info(" }, (error, response, data) => { console.log('Complete data:', data); });");
|
|
149
150
|
```
|
|
150
151
|
|
|
151
152
|
### Binary Chunks
|
|
152
153
|
|
|
153
154
|
```javascript
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
155
|
+
// Node.js reference — real HTTP + fs don't run in the browser playground.
|
|
156
|
+
console.info("In Node.js:");
|
|
157
|
+
console.info(" restClient.executeChunkedRequestBinary({");
|
|
158
|
+
console.info(" method: 'GET',");
|
|
159
|
+
console.info(" url: 'https://example.com/image.png'");
|
|
160
|
+
console.info(" }, (error, response, buffer) => {");
|
|
161
|
+
console.info(" // buffer is a Node.js Buffer");
|
|
162
|
+
console.info(" require('fs').writeFileSync('image.png', buffer);");
|
|
163
|
+
console.info(" });");
|
|
161
164
|
```
|
|
162
165
|
|
|
163
166
|
## Cookie Management
|
|
@@ -165,10 +168,15 @@ restClient.executeChunkedRequestBinary({
|
|
|
165
168
|
### Set Cookies
|
|
166
169
|
|
|
167
170
|
```javascript
|
|
171
|
+
const libFable = require('fable');
|
|
172
|
+
const fable = new libFable({ Product: 'RestClientDemo', ProductVersion: '1.0.0' });
|
|
173
|
+
const restClient = fable.instantiateServiceProvider('RestClient');
|
|
174
|
+
|
|
168
175
|
restClient.cookie = {
|
|
169
176
|
'session_id': 'abc123',
|
|
170
177
|
'user_token': 'xyz789'
|
|
171
178
|
};
|
|
179
|
+
console.log('Cookies set:', restClient.cookie);
|
|
172
180
|
```
|
|
173
181
|
|
|
174
182
|
### Automatic Cookie Handling
|
|
@@ -176,10 +184,16 @@ restClient.cookie = {
|
|
|
176
184
|
Cookies are automatically included in subsequent requests:
|
|
177
185
|
|
|
178
186
|
```javascript
|
|
187
|
+
const libFable = require('fable');
|
|
188
|
+
const fable = new libFable({ Product: 'RestClientDemo', ProductVersion: '1.0.0' });
|
|
189
|
+
const restClient = fable.instantiateServiceProvider('RestClient');
|
|
190
|
+
|
|
179
191
|
restClient.cookie = { session: 'abc123' };
|
|
192
|
+
console.log('Cookie set:', restClient.cookie);
|
|
180
193
|
|
|
181
|
-
//
|
|
182
|
-
restClient.getJSON('/protected-resource', callback);
|
|
194
|
+
// In Node.js (browser playground skips real network):
|
|
195
|
+
// restClient.getJSON('/protected-resource', callback);
|
|
196
|
+
console.info(" // restClient.getJSON('/protected-resource', callback); // sends session cookie");
|
|
183
197
|
```
|
|
184
198
|
|
|
185
199
|
## Request Options
|
|
@@ -187,17 +201,18 @@ restClient.getJSON('/protected-resource', callback);
|
|
|
187
201
|
All request methods accept an options object:
|
|
188
202
|
|
|
189
203
|
```javascript
|
|
190
|
-
{
|
|
204
|
+
const requestOptionsShape = {
|
|
191
205
|
url: 'https://api.example.com/endpoint',
|
|
192
206
|
method: 'GET', // Usually set by the convenience method
|
|
193
207
|
headers: {
|
|
194
208
|
'Authorization': 'Bearer token',
|
|
195
|
-
'Content-Type':
|
|
196
|
-
'Accept':
|
|
209
|
+
'Content-Type': 'application/json',
|
|
210
|
+
'Accept': 'application/json'
|
|
197
211
|
},
|
|
198
212
|
body: { /* request body for POST/PUT/PATCH */ },
|
|
199
213
|
timeout: 30000 // Request timeout in milliseconds
|
|
200
|
-
}
|
|
214
|
+
};
|
|
215
|
+
console.log('requestOptionsShape:', requestOptionsShape);
|
|
201
216
|
```
|
|
202
217
|
|
|
203
218
|
## Custom Request Preparation
|
|
@@ -205,12 +220,21 @@ All request methods accept an options object:
|
|
|
205
220
|
Override the `prepareRequestOptions` function to modify all outgoing requests:
|
|
206
221
|
|
|
207
222
|
```javascript
|
|
223
|
+
const libFable = require('fable');
|
|
224
|
+
const fable = new libFable({ Product: 'RestClientDemo', ProductVersion: '1.0.0' });
|
|
225
|
+
const restClient = fable.instantiateServiceProvider('RestClient');
|
|
226
|
+
|
|
227
|
+
function getAccessToken() { return 'demo-token-abc123'; }
|
|
228
|
+
|
|
208
229
|
restClient.prepareRequestOptions = (options) => {
|
|
209
230
|
// Add authentication to all requests
|
|
210
231
|
if (!options.headers) options.headers = {};
|
|
211
232
|
options.headers['Authorization'] = 'Bearer ' + getAccessToken();
|
|
212
233
|
return options;
|
|
213
234
|
};
|
|
235
|
+
|
|
236
|
+
const sample = restClient.prepareRequestOptions({ url: '/users' });
|
|
237
|
+
console.log('Prepared options:', sample);
|
|
214
238
|
```
|
|
215
239
|
|
|
216
240
|
## Trace Logging
|
|
@@ -218,12 +242,17 @@ restClient.prepareRequestOptions = (options) => {
|
|
|
218
242
|
Enable detailed request logging:
|
|
219
243
|
|
|
220
244
|
```javascript
|
|
245
|
+
const libFable = require('fable');
|
|
246
|
+
const fable = new libFable({ Product: 'RestClientDemo', ProductVersion: '1.0.0' });
|
|
247
|
+
|
|
221
248
|
const restClient = fable.instantiateServiceProvider('RestClient', {
|
|
222
249
|
TraceLog: true
|
|
223
250
|
});
|
|
224
251
|
|
|
225
252
|
// Or enable globally
|
|
226
253
|
fable.TraceLog = true;
|
|
254
|
+
console.log('Per-instance TraceLog:', restClient.options.TraceLog);
|
|
255
|
+
console.log('Global fable.TraceLog:', fable.TraceLog);
|
|
227
256
|
|
|
228
257
|
// Logs include:
|
|
229
258
|
// - Request start time
|
|
@@ -246,33 +275,29 @@ Beginning GET request to https://api.example.com/users at 1704067200000
|
|
|
246
275
|
Access the underlying `simple-get` library directly:
|
|
247
276
|
|
|
248
277
|
```javascript
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
278
|
+
// Node.js reference — real HTTP requests don't run in the browser playground.
|
|
279
|
+
console.info("In Node.js:");
|
|
280
|
+
console.info(" restClient.simpleGet({");
|
|
281
|
+
console.info(" method: 'GET',");
|
|
282
|
+
console.info(" url: 'https://example.com',");
|
|
283
|
+
console.info(" // ... other simple-get options");
|
|
284
|
+
console.info(" }, callback);");
|
|
254
285
|
```
|
|
255
286
|
|
|
256
287
|
## Error Handling
|
|
257
288
|
|
|
258
289
|
```javascript
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
console.error('Network error:', error.message);
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
console.
|
|
269
|
-
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Success
|
|
274
|
-
console.log('Data:', data);
|
|
275
|
-
});
|
|
290
|
+
// Node.js reference — real HTTP requests don't run in the browser playground.
|
|
291
|
+
console.info("In Node.js:");
|
|
292
|
+
console.info(" restClient.getJSON('https://api.example.com/users', (error, response, data) => {");
|
|
293
|
+
console.info(" if (error) { console.error('Network error:', error.message); return; }");
|
|
294
|
+
console.info(" if (response.statusCode >= 400) {");
|
|
295
|
+
console.info(" console.error('HTTP error:', response.statusCode);");
|
|
296
|
+
console.info(" console.error('Error body:', data);");
|
|
297
|
+
console.info(" return;");
|
|
298
|
+
console.info(" }");
|
|
299
|
+
console.info(" console.log('Data:', data);");
|
|
300
|
+
console.info(" });");
|
|
276
301
|
```
|
|
277
302
|
|
|
278
303
|
## Multiple Instances
|
|
@@ -280,11 +305,14 @@ restClient.getJSON('https://api.example.com/users', (error, response, data) => {
|
|
|
280
305
|
Create separate clients for different APIs:
|
|
281
306
|
|
|
282
307
|
```javascript
|
|
308
|
+
const libFable = require('fable');
|
|
309
|
+
const fable = new libFable({ Product: 'RestClientDemo', ProductVersion: '1.0.0' });
|
|
310
|
+
|
|
283
311
|
const mainApi = fable.instantiateServiceProvider('RestClient', {}, 'main-api');
|
|
284
312
|
const authApi = fable.instantiateServiceProvider('RestClient', {}, 'auth-api');
|
|
285
313
|
|
|
286
314
|
// Set different cookies for each
|
|
287
|
-
mainApi.cookie = { api_session:
|
|
315
|
+
mainApi.cookie = { api_session: '...' };
|
|
288
316
|
authApi.cookie = { auth_session: '...' };
|
|
289
317
|
|
|
290
318
|
// Set different request preparation
|
|
@@ -293,4 +321,8 @@ authApi.prepareRequestOptions = (options) => {
|
|
|
293
321
|
options.headers['X-Auth-Service'] = 'true';
|
|
294
322
|
return options;
|
|
295
323
|
};
|
|
324
|
+
|
|
325
|
+
console.log('mainApi cookie keys:', Object.keys(mainApi.cookie));
|
|
326
|
+
console.log('authApi cookie keys:', Object.keys(authApi.cookie));
|
|
327
|
+
console.log('authApi prepared headers:', authApi.prepareRequestOptions({}).headers);
|
|
296
328
|
```
|