@naanlang/naan 1.4.4 → 1.5.0
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.md +2 -2
- package/README.md +4 -4
- package/bin/index.js +20 -2
- package/dist/env_web.js +2 -2
- package/dist/naan.min.js +4 -4
- package/frameworks/browser/browser.nlg +2 -2
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +14 -8
- package/frameworks/client/apiclient.nlg +31 -18
- package/frameworks/client/client.nlg +22 -2
- package/frameworks/client/psm_client.nlg +12 -3
- package/frameworks/node/filesystem.nlg +9 -7
- package/frameworks/node/gitter.nlg +9 -7
- package/frameworks/node/shell.nlg +4 -4
- package/frameworks/project/projects.nlg +2 -1
- package/frameworks/storage/dbt_pouch.nlg +26 -13
- package/frameworks/storage/psm.nlg +39 -5
- package/frameworks/storage/psm_dbtables.nlg +10 -2
- package/lib/browser/env_web.js +9 -9
- package/lib/browser/env_webworker.js +1 -2
- package/lib/core/naanlib.js +4 -4
- package/package.json +1 -1
- package/plugins/serviceAws/aws_cloudwatchlogs.nlg +2 -1
- package/plugins/serviceAws/aws_dynamo.nlg +1 -0
- package/plugins/serviceAws/aws_s3.nlg +3 -3
- package/plugins/serviceAws/aws_sqs.nlg +3 -1
- package/plugins/serviceAws/aws_utils.nlg +3 -1
- package/plugins/serviceAws/dbt_aws.nlg +22 -20
- package/plugins/serviceAws/psm_aws.nlg +2 -1
- package/test/test_03_jsinterop.nlg +32 -3
- package/plugins/serviceGC/russian_trusted_root_ca_pem.crt +0 -33
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2020-
|
|
9
|
+
* Copyright (c) 2020-2025 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -33,7 +33,7 @@ closure FileReader(file, progress, local pending, freader, result) {
|
|
|
33
33
|
freader.addEventListener("error", function(error) {
|
|
34
34
|
pending.signal(list(error))
|
|
35
35
|
})
|
|
36
|
-
freader.
|
|
36
|
+
freader.addEventListener("progress", function(event) {
|
|
37
37
|
if event.lengthComputable && event.total
|
|
38
38
|
progress(toint((event.loaded * 100) / event.total))
|
|
39
39
|
else
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
*
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
var CurrentCacheName = "Naanlang-1.
|
|
39
|
+
var CurrentCacheName = "Naanlang-1.5.0+1";
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
//
|
|
@@ -92,18 +92,18 @@ var terminated; // flag that this service worker
|
|
|
92
92
|
var pubVersion = event.data.hereIsMyVersion;
|
|
93
93
|
var sourceId = event.source.id; // client id of sender of message
|
|
94
94
|
msgPorts[sourceId] = msgport;
|
|
95
|
-
console.log("[1.
|
|
96
|
-
if (pubVersion != "1.
|
|
95
|
+
console.log("[1.5.0+1] received new msgport for", sourceId, pubID, "-", pubVersion);
|
|
96
|
+
if (pubVersion != "1.5.0+1") {
|
|
97
97
|
if (upgradeMsgPorts) { // if not activated
|
|
98
|
-
console.log("[1.
|
|
98
|
+
console.log("[1.5.0+1] update pending for", sourceId);
|
|
99
99
|
upgradeMsgPorts[sourceId] = msgport;
|
|
100
100
|
}
|
|
101
101
|
else {
|
|
102
102
|
msgport.postMessage({ // notify new version available
|
|
103
103
|
id: "upgrade",
|
|
104
|
-
version: "1.
|
|
104
|
+
version: "1.5.0+1"
|
|
105
105
|
});
|
|
106
|
-
console.log("[1.
|
|
106
|
+
console.log("[1.5.0+1] update sent for:", sourceId);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
Reaper(); // clean up obsolete info
|
|
@@ -134,10 +134,10 @@ var terminated; // flag that this service worker
|
|
|
134
134
|
msgport.onmessage = function(msg) {
|
|
135
135
|
msg = msg.data;
|
|
136
136
|
if (msg.id == "skipWaiting") { // try to activate this SW now
|
|
137
|
-
console.log("[1.
|
|
137
|
+
console.log("[1.5.0+1] attempting skipWaiting");
|
|
138
138
|
self.skipWaiting();
|
|
139
139
|
} else if (msg.id == "terminate") { // termiante this SW now
|
|
140
|
-
console.log("[1.
|
|
140
|
+
console.log("[1.5.0+1] terminated");
|
|
141
141
|
terminate();
|
|
142
142
|
} else if (msg.id == "abortURL") { // abort an I/O transaction
|
|
143
143
|
var href = new URL(msg.url).href;
|
|
@@ -150,7 +150,7 @@ var terminated; // flag that this service worker
|
|
|
150
150
|
} else if (msg.id == "response") // response from fetch request
|
|
151
151
|
processResponse(msg);
|
|
152
152
|
else if (msg.id == "text") // just log some text
|
|
153
|
-
console.log("[1.
|
|
153
|
+
console.log("[1.5.0+1] msg received:", msg.text);
|
|
154
154
|
};
|
|
155
155
|
|
|
156
156
|
// send text to IDE log
|
|
@@ -161,7 +161,7 @@ var terminated; // flag that this service worker
|
|
|
161
161
|
// don't clutter the log
|
|
162
162
|
msgport.postMessage({
|
|
163
163
|
id: "text",
|
|
164
|
-
text: "port received by 1.
|
|
164
|
+
text: "port received by 1.5.0+1",
|
|
165
165
|
});
|
|
166
166
|
*/
|
|
167
167
|
if (--pending === 0)
|
|
@@ -178,7 +178,7 @@ var terminated; // flag that this service worker
|
|
|
178
178
|
includeUncontrolled: true
|
|
179
179
|
}).then(function(clientList) {
|
|
180
180
|
clientList.every(function(client) {
|
|
181
|
-
console.log("[1.
|
|
181
|
+
console.log("[1.5.0+1] requesting new msgport for", client.id);
|
|
182
182
|
++pending;
|
|
183
183
|
client.postMessage({ // tell client(s) we need this fetch source
|
|
184
184
|
msg: "Naan_need_fetch_port",
|
|
@@ -224,12 +224,12 @@ function Reaper() {
|
|
|
224
224
|
clients[clientList[clidex].id] = clientList[clidex];
|
|
225
225
|
for (var sourceId in msgPorts)
|
|
226
226
|
if (!clients[sourceId]) {
|
|
227
|
-
console.log("[1.
|
|
227
|
+
console.log("[1.5.0+1] source gone:", sourceId);
|
|
228
228
|
delete msgPorts[sourceId]; // no longer a source
|
|
229
229
|
}
|
|
230
230
|
for (var clientId in fetchPorts)
|
|
231
231
|
if (!clients[clientId]) {
|
|
232
|
-
console.log("[1.
|
|
232
|
+
console.log("[1.5.0+1] client gone:", clientId);
|
|
233
233
|
delete fetchPorts[clientId]; // no longer a client
|
|
234
234
|
}
|
|
235
235
|
for (var fqdex = 0; fqdex < fetchQueue.length; ++fqdex) {
|
|
@@ -263,16 +263,16 @@ function ClearCaches() {
|
|
|
263
263
|
return (Promise.all(
|
|
264
264
|
cacheNames.map(function(cacheName) {
|
|
265
265
|
if (cacheName != CurrentCacheName) {
|
|
266
|
-
console.log('[1.
|
|
266
|
+
console.log('[1.5.0+1] deleting old cache:', cacheName);
|
|
267
267
|
return (caches.delete(cacheName));
|
|
268
268
|
}
|
|
269
269
|
})
|
|
270
270
|
));
|
|
271
271
|
}).then(function() { // claim all clients
|
|
272
|
-
console.log('[1.
|
|
272
|
+
console.log('[1.5.0+1] claiming clients');
|
|
273
273
|
return (self.clients.claim());
|
|
274
274
|
}).then(function() {
|
|
275
|
-
console.log('[1.
|
|
275
|
+
console.log('[1.5.0+1] clients claimed');
|
|
276
276
|
return (Promise.resolve(true));
|
|
277
277
|
});
|
|
278
278
|
return (promise);
|
|
@@ -315,7 +315,7 @@ function GetClientResponse(event, urlpath) {
|
|
|
315
315
|
msgport.postMessage({
|
|
316
316
|
id: "fetch",
|
|
317
317
|
seq: seqno,
|
|
318
|
-
version: "1.
|
|
318
|
+
version: "1.5.0+1",
|
|
319
319
|
request: {
|
|
320
320
|
method: event.request.method,
|
|
321
321
|
url: event.request.url
|
|
@@ -363,7 +363,7 @@ function GetClientResponse(event, urlpath) {
|
|
|
363
363
|
*/
|
|
364
364
|
|
|
365
365
|
self.addEventListener('install', function(event) {
|
|
366
|
-
console.log("[1.
|
|
366
|
+
console.log("[1.5.0+1] install");
|
|
367
367
|
self.skipWaiting();
|
|
368
368
|
});
|
|
369
369
|
|
|
@@ -376,20 +376,20 @@ self.addEventListener('install', function(event) {
|
|
|
376
376
|
*/
|
|
377
377
|
|
|
378
378
|
self.addEventListener('activate', function(event) {
|
|
379
|
-
console.log("[1.
|
|
379
|
+
console.log("[1.5.0+1] activate");
|
|
380
380
|
self.clients.matchAll({ // for debugging, list controlled clients
|
|
381
381
|
includeUncontrolled: true
|
|
382
382
|
}).then(function(clientList) {
|
|
383
383
|
var urls = clientList.map(function(client) {
|
|
384
384
|
return (client.url);
|
|
385
385
|
});
|
|
386
|
-
console.log('[1.
|
|
386
|
+
console.log('[1.5.0+1] matching clients:', urls.join(', '));
|
|
387
387
|
});
|
|
388
388
|
var promise = ClearCaches().then(function() {
|
|
389
389
|
for (var sourceId in upgradeMsgPorts) {
|
|
390
390
|
upgradeMsgPorts[sourceId].postMessage({ // notify new version available
|
|
391
391
|
id: "upgrade",
|
|
392
|
-
version: "1.
|
|
392
|
+
version: "1.5.0+1"
|
|
393
393
|
});
|
|
394
394
|
}
|
|
395
395
|
upgradeMsgPorts = false;
|
|
@@ -421,7 +421,7 @@ self.addEventListener('fetch', function(event) {
|
|
|
421
421
|
var promise;
|
|
422
422
|
var url = new URL(request.url);
|
|
423
423
|
var nocache = request.method != "GET"
|
|
424
|
-
|| url.search.length !== 0 && url.searchParams.get("naanver") !== "
|
|
424
|
+
|| url.search.length !== 0 && url.searchParams.get("naanver") !== "1df9163d801364d0cae89b149cc24ef5"
|
|
425
425
|
|| request.headers.get('range');
|
|
426
426
|
if (url.pathname.startsWith("/run/")) {
|
|
427
427
|
nocache = true;
|
|
@@ -455,7 +455,7 @@ self.addEventListener('fetch', function(event) {
|
|
|
455
455
|
statusText: "Request Cancelled"
|
|
456
456
|
}));
|
|
457
457
|
}
|
|
458
|
-
console.log("[1.
|
|
458
|
+
console.log("[1.5.0+1] fetch failed", request.url, e);
|
|
459
459
|
return (new Response(undefined, {
|
|
460
460
|
status: 404,
|
|
461
461
|
statusText: "Fetch Failed"
|
|
@@ -562,7 +562,7 @@ closure TermLocal(track, name, options, local target, nlregex, listener)
|
|
|
562
562
|
msg.data._guid = target.guid
|
|
563
563
|
js.t.DispatchMessage(msg.data)
|
|
564
564
|
}
|
|
565
|
-
|
|
565
|
+
}
|
|
566
566
|
|
|
567
567
|
//
|
|
568
568
|
// target.DebugCmd
|
|
@@ -764,14 +764,18 @@ closure WorkerToMain(local nideRunning, track) {
|
|
|
764
764
|
/*
|
|
765
765
|
* findIDEtarget
|
|
766
766
|
*
|
|
767
|
-
* Find a target for our IDE that matches the specified name, workerID, and naancont.
|
|
767
|
+
* Find a target for our IDE that matches the specified name, workerID, and naancont. Either the
|
|
768
|
+
* title or the naancont must match. The title will match but not the naancont if the window was
|
|
769
|
+
* closed/reloaded but we didn't get notified because browsers are annoying that way. Alternatively
|
|
770
|
+
* the naancont will match but not the title if we have updated the version.
|
|
768
771
|
*
|
|
769
772
|
*/
|
|
770
773
|
|
|
771
|
-
closure findIDEtarget(track, name, workerID, naancont, local target) {
|
|
774
|
+
closure findIDEtarget(track, name, workerID, title, naancont, local target) {
|
|
772
775
|
global()
|
|
773
776
|
for target in track.enumlist()
|
|
774
|
-
if target.name == name && target.workerID == workerID
|
|
777
|
+
if target.name == name && target.workerID == workerID
|
|
778
|
+
&& (target.title == title || !target.naancont || target.naancont === naancont)
|
|
775
779
|
return (target)
|
|
776
780
|
false
|
|
777
781
|
};
|
|
@@ -788,8 +792,10 @@ closure findIDEtarget(track, name, workerID, naancont, local target) {
|
|
|
788
792
|
|
|
789
793
|
closure termIDE(track, name, workerID, naancont, title, local target, connected) {
|
|
790
794
|
global(js, gWorkers)
|
|
791
|
-
target = findIDEtarget(track, name, workerID, naancont)
|
|
795
|
+
target = findIDEtarget(track, name, workerID, title, naancont)
|
|
792
796
|
if target { // new naancont on existing target
|
|
797
|
+
if target.naancont && naancont !== target.naancont
|
|
798
|
+
target.targetClose()
|
|
793
799
|
target.updateController(naancont)
|
|
794
800
|
target.title = title
|
|
795
801
|
track.update(target)
|
|
@@ -934,7 +940,7 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
|
|
|
934
940
|
//
|
|
935
941
|
// Mark the target window as closed.
|
|
936
942
|
//
|
|
937
|
-
function targetClose(local conn) {
|
|
943
|
+
target.targetClose = function targetClose(local conn) {
|
|
938
944
|
for conn in connected {
|
|
939
945
|
conn.db.detach(target)
|
|
940
946
|
conn.WriteLn("\x1b[90m\x1b[3m".concat("\ntarget closed", "\x1b[0m"))
|
|
@@ -1012,12 +1018,12 @@ closure termInstallVirtualWatcher(track, naancont) {
|
|
|
1012
1018
|
target.attention()
|
|
1013
1019
|
}
|
|
1014
1020
|
else if msg.op == "VsiteClose" {
|
|
1015
|
-
target = findIDEtarget(track, msg.name, "NaanVsite", msg.naancont)
|
|
1021
|
+
target = findIDEtarget(track, msg.name, "NaanVsite", msg.title, msg.naancont)
|
|
1016
1022
|
if target
|
|
1017
1023
|
target.updateController()
|
|
1018
1024
|
}
|
|
1019
1025
|
else if msg.op == "VsiteVisibilityChange" {
|
|
1020
|
-
target = findIDEtarget(track, msg.name, "NaanVsite", msg.naancont)
|
|
1026
|
+
target = findIDEtarget(track, msg.name, "NaanVsite", msg.title, msg.naancont)
|
|
1021
1027
|
if target
|
|
1022
1028
|
target.setCheckStatus(msg.hidden, msg.window)
|
|
1023
1029
|
}
|
|
@@ -2,41 +2,50 @@
|
|
|
2
2
|
* apiclient.nlg
|
|
3
3
|
* Naanlib/frameworks/client
|
|
4
4
|
*
|
|
5
|
-
* Access to Nide API with
|
|
5
|
+
* Access to Nide API with specified HTTP client.
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2017-
|
|
9
|
+
* Copyright (c) 2017-2025 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
/*
|
|
15
|
-
*
|
|
15
|
+
* APIClient
|
|
16
16
|
*
|
|
17
|
-
* Make an API client object
|
|
17
|
+
* Make an API client object.
|
|
18
|
+
*
|
|
19
|
+
* Options:
|
|
20
|
+
* {
|
|
21
|
+
* url: <string> // hostname or URL of the remote server
|
|
22
|
+
* guid: <string> // shared secret for access to remote server
|
|
23
|
+
* instanceID: <string> // optional UUID for our client; can be persisted by caller
|
|
24
|
+
* }
|
|
18
25
|
*
|
|
19
26
|
*/
|
|
20
27
|
|
|
21
|
-
closure
|
|
22
|
-
global()
|
|
28
|
+
closure APIClient(options, local client, url, guid) {
|
|
29
|
+
global(App)
|
|
23
30
|
client = new(object, this)
|
|
31
|
+
url = options.url
|
|
24
32
|
if !url.match(RegExp("^https?:\/\/", "i"))
|
|
25
33
|
url = "http://${url}" // a protocol is required
|
|
26
34
|
if url.slice(-1) != "/"
|
|
27
35
|
url = url.concat("/") // must end in "/"
|
|
28
36
|
client.url = url
|
|
29
|
-
client.guid = guid
|
|
37
|
+
client.guid = options.guid
|
|
38
|
+
client.instanceID = options.instanceID || UUID() // our client's unique ID
|
|
30
39
|
client.notifyAfter = 0
|
|
31
|
-
client.
|
|
40
|
+
client.requester = clirRequester()
|
|
32
41
|
|
|
33
42
|
// clientRequest() - append our guid to the headers
|
|
34
43
|
|
|
35
|
-
closure clientRequest(url,
|
|
36
|
-
|
|
37
|
-
if guid
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
closure clientRequest(url, reqops) {
|
|
45
|
+
reqops = merge(reqops)
|
|
46
|
+
if options.guid
|
|
47
|
+
reqops.headers = [list("x-naanlang-api-guid", options.guid)]
|
|
48
|
+
client.requester(url, reqops)
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
//
|
|
@@ -57,7 +66,7 @@ closure NideAPIclient(url, guid, apiRequester, local client) {
|
|
|
57
66
|
timeout: timeoutms
|
|
58
67
|
after: client.notifyAfter
|
|
59
68
|
})
|
|
60
|
-
`(error, content, extra) = clientRequest(url.concat(query))
|
|
69
|
+
`(error, content, extra) = clientRequest(url.concat(query), { retrier: false }) // don't retry inside
|
|
61
70
|
if (error || extra.status != 200)
|
|
62
71
|
cbStatus()
|
|
63
72
|
else if (length(content) == 0)
|
|
@@ -76,8 +85,12 @@ closure NideAPIclient(url, guid, apiRequester, local client) {
|
|
|
76
85
|
// get
|
|
77
86
|
//
|
|
78
87
|
|
|
79
|
-
client.get = closure get(path, options, local error, content, extra) {
|
|
80
|
-
|
|
88
|
+
client.get = closure get(path, options, local requrl, error, content, extra) {
|
|
89
|
+
if App.cache
|
|
90
|
+
requrl = url.concat(EncodeQuery(path.concat("?"), { naanver: App.cache }))
|
|
91
|
+
else
|
|
92
|
+
requrl = url.concat(path)
|
|
93
|
+
`(error, content, extra) = clientRequest(requrl)
|
|
81
94
|
if !error && extra.status != 200
|
|
82
95
|
error = Error("readFile failed: ".concat(extra.status), {
|
|
83
96
|
status: extra.status
|
|
@@ -153,12 +166,12 @@ closure NideAPIclient(url, guid, apiRequester, local client) {
|
|
|
153
166
|
|
|
154
167
|
function apicInit(local manifest) {
|
|
155
168
|
|
|
156
|
-
manifest = `(
|
|
169
|
+
manifest = `(APIClient, apicInit)
|
|
157
170
|
|
|
158
171
|
Naan.module.build(module.id, "apiclient", function(modobj, compobj) {
|
|
159
172
|
Naan.module.require("./client.nlg")
|
|
160
173
|
compobj.manifest = manifest
|
|
161
|
-
modobj.exports.
|
|
174
|
+
modobj.exports.APIClient = APIClient
|
|
162
175
|
})
|
|
163
176
|
|
|
164
177
|
} ();
|
|
@@ -6,11 +6,31 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2020-
|
|
9
|
+
* Copyright (c) 2020-2025 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
/*
|
|
15
|
+
* clirRequester
|
|
16
|
+
*
|
|
17
|
+
* Return an appropriate HttpsRequestApi client based on our environment.
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
clirRequestApi = false;
|
|
22
|
+
|
|
23
|
+
function clirRequester() {
|
|
24
|
+
if !clirRequestApi {
|
|
25
|
+
if js.w
|
|
26
|
+
clirRequestApi = require("naanlib:frameworks/browser/https_request.nlg").HttpsApiRequest
|
|
27
|
+
else
|
|
28
|
+
clirRequestApi = require("naanlib:frameworks/node/https_request.nlg").HttpsApiRequest
|
|
29
|
+
}
|
|
30
|
+
clirRequestApi
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
|
|
14
34
|
/*
|
|
15
35
|
* clirInit
|
|
16
36
|
*
|
|
@@ -20,7 +40,7 @@
|
|
|
20
40
|
*/
|
|
21
41
|
|
|
22
42
|
function clirInit(local manifest) {
|
|
23
|
-
manifest = `(clirInit)
|
|
43
|
+
manifest = `(clirRequester, clirInit)
|
|
24
44
|
|
|
25
45
|
Naan.module.build(module.id, "client", function(modobj, compobj) {
|
|
26
46
|
require("../common/").LiveImport()
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2019-
|
|
9
|
+
* Copyright (c) 2019-2025 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -633,8 +633,17 @@ closure psmcFsConnector(psm, api, local connClassID, connector, watch) {
|
|
|
633
633
|
api = connector.apis[creds]
|
|
634
634
|
else {
|
|
635
635
|
api = connector.apis[creds.urlName]
|
|
636
|
-
if !api
|
|
637
|
-
connector.apis[creds.urlName] = api =
|
|
636
|
+
if !api { // create API to remote server
|
|
637
|
+
connector.apis[creds.urlName] = api = APIClient({
|
|
638
|
+
url: creds.urlName
|
|
639
|
+
guid: creds.authSecret
|
|
640
|
+
instanceID: creds.instanceID
|
|
641
|
+
})
|
|
642
|
+
if creds.instanceID != api.instanceID { // update our client instanceID
|
|
643
|
+
creds.instanceID = api.instanceID
|
|
644
|
+
`(error) = connector.vault.updateResource(resID, creds)
|
|
645
|
+
}
|
|
646
|
+
}
|
|
638
647
|
}
|
|
639
648
|
}
|
|
640
649
|
if error
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2017-
|
|
9
|
+
* Copyright (c) 2017-2025 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -1041,6 +1041,8 @@ closure Filesystem(rootpath, local files, badCreatePathRegEx) {
|
|
|
1041
1041
|
cmdargs.push(options.pattern)
|
|
1042
1042
|
cmdargs.push(JSpath.resolve(rootpath, localpath))
|
|
1043
1043
|
execOptions = { cmdargs: cmdargs }
|
|
1044
|
+
if js.g.process.platform == "win32" // to make "-i" work on Windows
|
|
1045
|
+
execOptions.spawnops = { env: merge(js.g.process.env, { LC_ALL: 'en_US.UTF-8' }) }
|
|
1044
1046
|
result = []
|
|
1045
1047
|
lineRE = RegExp("([^:]*):([0-9]+):(.*)$") // <path>:<line-number>:<matching-text-line>
|
|
1046
1048
|
if integer(options.maxCount)
|
|
@@ -1075,7 +1077,7 @@ closure Filesystem(rootpath, local files, badCreatePathRegEx) {
|
|
|
1075
1077
|
// has completed. Options are:
|
|
1076
1078
|
// {
|
|
1077
1079
|
// cmdargs: -- array of string arguments to the command (see below)
|
|
1078
|
-
//
|
|
1080
|
+
// spawnops: -- optional spawn options like cwd
|
|
1079
1081
|
// errproc: -- callback for stderr output lines, or false
|
|
1080
1082
|
// errLE: -- string or RegExp for stderr line ending
|
|
1081
1083
|
// outproc: -- optional callback for stdout output lines
|
|
@@ -1100,7 +1102,7 @@ closure Filesystem(rootpath, local files, badCreatePathRegEx) {
|
|
|
1100
1102
|
//
|
|
1101
1103
|
|
|
1102
1104
|
files.execLines = closure execLines(cmdname, options, callback,
|
|
1103
|
-
local output,
|
|
1105
|
+
local output, spawnops, spawn, linerErr, linerOut) {
|
|
1104
1106
|
if !callback
|
|
1105
1107
|
return (syncAdapter(execLines, cmdname, options))
|
|
1106
1108
|
if !string(cmdname) || cmdname == ""
|
|
@@ -1109,11 +1111,11 @@ closure Filesystem(rootpath, local files, badCreatePathRegEx) {
|
|
|
1109
1111
|
output = options.output
|
|
1110
1112
|
else
|
|
1111
1113
|
output = {}
|
|
1112
|
-
if options.
|
|
1113
|
-
|
|
1114
|
+
if options.spawnops
|
|
1115
|
+
spawnops = options.spawnops
|
|
1114
1116
|
else
|
|
1115
|
-
|
|
1116
|
-
spawn = nodecp.spawn(cmdname, options.cmdargs,
|
|
1117
|
+
spawnops = { }
|
|
1118
|
+
spawn = nodecp.spawn(cmdname, options.cmdargs, spawnops)
|
|
1117
1119
|
|
|
1118
1120
|
// completed
|
|
1119
1121
|
// execute callback only once
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2020-
|
|
9
|
+
* Copyright (c) 2020-2025 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -56,7 +56,7 @@ closure Gitter(fs, local gitt) {
|
|
|
56
56
|
asyncResult(callback, false, gitt.roots[repopath])
|
|
57
57
|
execOptions = {
|
|
58
58
|
cmdargs: ["rev-parse", "--show-toplevel"]
|
|
59
|
-
|
|
59
|
+
spawnops: {
|
|
60
60
|
cwd: repopath
|
|
61
61
|
}
|
|
62
62
|
outLE: "\x00" // lines delimited by nulls
|
|
@@ -117,7 +117,7 @@ closure Gitter(fs, local gitt) {
|
|
|
117
117
|
repopath = fs.path.resolve(fs.rootpath, repopath)
|
|
118
118
|
execOptions = {
|
|
119
119
|
cmdargs: ["log", "-z", "--pretty=format:%H|%an|%ae|%aI|%B"]
|
|
120
|
-
|
|
120
|
+
spawnops: {
|
|
121
121
|
cwd: repopath
|
|
122
122
|
}
|
|
123
123
|
outLE: "\x00" // lines delimited by nulls
|
|
@@ -168,10 +168,12 @@ closure Gitter(fs, local gitt) {
|
|
|
168
168
|
if !string(repopath)
|
|
169
169
|
return (asyncResult(callback, Error("invalid path:", repopath)))
|
|
170
170
|
repopath = fs.path.resolve(fs.rootpath, repopath)
|
|
171
|
-
|
|
171
|
+
bridge = fs.path.normalize(bridgePath(repopath)) // ensure it works for our FS
|
|
172
|
+
if bridge == "."
|
|
173
|
+
bridge = "" // no bridge in this case
|
|
172
174
|
execOptions = {
|
|
173
175
|
cmdargs: ["status", "-z", "--porcelain"]
|
|
174
|
-
|
|
176
|
+
spawnops: {
|
|
175
177
|
cwd: repopath
|
|
176
178
|
}
|
|
177
179
|
outLE: "\x00" // lines delimited by nulls
|
|
@@ -219,13 +221,13 @@ closure Gitter(fs, local gitt) {
|
|
|
219
221
|
repopath = fs.path.resolve(fs.rootpath, repopath)
|
|
220
222
|
execOptions = {
|
|
221
223
|
cmdargs: ["show", options.hash.concat(":", bridgePath(repopath), gitPath(options.pathspec))]
|
|
222
|
-
|
|
224
|
+
spawnops: {
|
|
223
225
|
cwd: repopath
|
|
224
226
|
}
|
|
225
227
|
}
|
|
226
228
|
nodecp.execFile("git",
|
|
227
229
|
execOptions.cmdargs,
|
|
228
|
-
execOptions.
|
|
230
|
+
execOptions.spawnops,
|
|
229
231
|
function(err, stdout, stderr) {
|
|
230
232
|
if err
|
|
231
233
|
callback(Error("git failed", err, stderr))
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2024 by Richard C. Zulch
|
|
9
|
+
* Copyright (c) 2024-2025 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -68,9 +68,9 @@ closure ShellConnect(options, local shob, error, fs, xparser, shelly) {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
if cwd
|
|
71
|
-
xlparams.
|
|
71
|
+
xlparams.spawnops = { cwd: cwd }
|
|
72
72
|
else if options.cwd
|
|
73
|
-
xlparams.
|
|
73
|
+
xlparams.spawnops = { cwd: options.cwd }
|
|
74
74
|
fs.execLines(cmd, xlparams, function(error, result) {
|
|
75
75
|
evalactive(list(`assign, `(compress, "$$"), report)) // assign to $$ in active namespace
|
|
76
76
|
pending.signal(list(error, merge(result, report)))
|
|
@@ -80,7 +80,7 @@ closure ShellConnect(options, local shob, error, fs, xparser, shelly) {
|
|
|
80
80
|
|
|
81
81
|
// shellparser
|
|
82
82
|
// intercept command-line parsing and look for a !shell escape
|
|
83
|
-
function shellparser(source, grammar, operators, local token) {
|
|
83
|
+
function shellparser(source, grammar, operators, local token, text) {
|
|
84
84
|
token = source.tokenread()
|
|
85
85
|
if token.atom == `! {
|
|
86
86
|
source.tokenlast(true) // "consume" the ! token
|
|
@@ -296,7 +296,7 @@ closure projConnector(projman, projtype, local connector, watch) {
|
|
|
296
296
|
*
|
|
297
297
|
* Nide.proj/
|
|
298
298
|
* nide_cliser.cfg - JSON definition of the project (see below)
|
|
299
|
-
* NaanIDE_version.txt - [default] substitution file defining 1.
|
|
299
|
+
* NaanIDE_version.txt - [default] substitution file defining 1.5.0+1 etc.
|
|
300
300
|
* NaanIDE_version_builds.txt - [default] contains current build number as decimal string
|
|
301
301
|
* build/ - [optional] default build output location
|
|
302
302
|
* NaanIDE.lic - [optional] defines Zulch Laboratories, Inc. and other license info
|
|
@@ -692,6 +692,7 @@ closure projConfig(projman, where, projID, local procon, fs, configpath) {
|
|
|
692
692
|
erase: true
|
|
693
693
|
overwrite: true
|
|
694
694
|
follow: true
|
|
695
|
+
cacheControl: publish.cacheControlFiles
|
|
695
696
|
})
|
|
696
697
|
}
|
|
697
698
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* column positioning: // // !
|
|
9
9
|
*
|
|
10
|
-
* Copyright (c) 2017-
|
|
10
|
+
* Copyright (c) 2017-2025 by Richard C. Zulch
|
|
11
11
|
*
|
|
12
12
|
*/
|
|
13
13
|
|
|
@@ -76,21 +76,31 @@ closure dapoTable(database, rootpath, local table, prefix) {
|
|
|
76
76
|
|
|
77
77
|
// add
|
|
78
78
|
//
|
|
79
|
-
// Add a new record to the table with
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
// Add a new record to the table with options. This will fail if the key already exists. Optional
|
|
80
|
+
// metadata is stored with the record and cannot be changed without calling update. Metadata keys
|
|
81
|
+
// cannot begin with underscore ("_").
|
|
82
|
+
//
|
|
83
|
+
// The returned document, which can be used with update, has the following keys:
|
|
84
|
+
// key - the key name of the record
|
|
85
|
+
// content - the body content stored under in the record
|
|
86
|
+
// _md5 - the MD5 hash of the content
|
|
87
|
+
// _length - the length of the content
|
|
88
|
+
// _id - the PouchDB ID
|
|
89
|
+
// _rev - the PouchDB revision
|
|
90
|
+
// <...> - various metadata keys
|
|
91
|
+
|
|
92
|
+
table.add = closure add(key, content, options, callback, local id, doc) {
|
|
83
93
|
if !callback
|
|
84
|
-
return (syncAdapter(add, key, content,
|
|
94
|
+
return (syncAdapter(add, key, content, options))
|
|
85
95
|
id = makeID(key)
|
|
86
96
|
if !string(id)
|
|
87
97
|
return (asyncResult(callback, id)) // error from makeID
|
|
88
|
-
if
|
|
98
|
+
if options.metadata && !dictionary(options.metadata)
|
|
89
99
|
return (asyncResult(callback, Error("invalid arguments")))
|
|
90
100
|
if !database.pouch
|
|
91
101
|
return (asyncResult(callback, Error("database closed")))
|
|
92
|
-
if metadata {
|
|
93
|
-
doc = new(metadata)
|
|
102
|
+
if options.metadata {
|
|
103
|
+
doc = new(options.metadata) // start with metadata
|
|
94
104
|
doc._rev = undefined } // _rev not allowed in metadata
|
|
95
105
|
else
|
|
96
106
|
doc = { }
|
|
@@ -115,12 +125,13 @@ closure dapoTable(database, rootpath, local table, prefix) {
|
|
|
115
125
|
|
|
116
126
|
// update
|
|
117
127
|
//
|
|
118
|
-
// Update a record in the table using the document previously returned by add or get.
|
|
119
|
-
//
|
|
128
|
+
// Update a record in the table using the document previously returned by add or get. Specify
|
|
129
|
+
// options to update those values, otherwise existing/default values are used. This will fail
|
|
130
|
+
// if the record has been modified by someone else in the meantime.
|
|
120
131
|
|
|
121
|
-
table.update = closure update(doc, callback) {
|
|
132
|
+
table.update = closure update(doc, options, callback) {
|
|
122
133
|
if !callback
|
|
123
|
-
return (syncAdapter(update, doc))
|
|
134
|
+
return (syncAdapter(update, doc, options))
|
|
124
135
|
if !doc._id || !doc._id.startsWith(table.prefix) || !doc._rev
|
|
125
136
|
return (asyncResult(callback, Error("invalid argument")))
|
|
126
137
|
if makeID(doc.key) != doc._id
|
|
@@ -130,6 +141,8 @@ closure dapoTable(database, rootpath, local table, prefix) {
|
|
|
130
141
|
doc = new(doc)
|
|
131
142
|
doc._md5 = undefined
|
|
132
143
|
doc._length = undefined
|
|
144
|
+
if options.metadata
|
|
145
|
+
doc = merge(doc, options.metadata)
|
|
133
146
|
database.pouch.put(doc, function(error, resp) {
|
|
134
147
|
if error
|
|
135
148
|
error = Error("update failed", error)
|