@naanlang/naan 1.0.5 → 1.0.7
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 +1 -1
- package/README.md +1 -1
- package/bin/index.js +2 -2
- package/dist/env_web.js +9 -2
- package/dist/naan.min.js +5 -5
- package/frameworks/browser/browser.nlg +67 -2
- package/frameworks/browser/https_request.nlg +2 -2
- package/frameworks/browser/sworker.js +17 -17
- package/frameworks/browser/terminals.nlg +14 -12
- package/frameworks/browser/workers.nlg +6 -6
- package/frameworks/client/apiclient.nlg +1 -1
- package/frameworks/client/psm_client.nlg +12 -4
- package/frameworks/common/common.nlg +18 -7
- package/frameworks/node/apiserver.nlg +2 -2
- package/frameworks/node/filesystem.nlg +32 -15
- package/frameworks/node/psm_server.nlg +11 -2
- package/frameworks/project/build.nlg +25 -15
- package/frameworks/project/projects.nlg +61 -21
- package/frameworks/running/executors.nlg +0 -1
- package/frameworks/running/running.nlg +1 -1
- package/frameworks/running/taskexec.nlg +1 -1
- package/frameworks/storage/file_manager.nlg +2 -1
- package/frameworks/storage/psm_dbtables.nlg +13 -3
- package/lib/browser/env_web.js +13 -6
- package/lib/browser/env_webworker.js +10 -0
- package/lib/core/naanlib.js +5 -5
- package/package.json +2 -1
- package/plugins/serviceAws/aws_dynamo.nlg +19 -7
- package/plugins/serviceAws/aws_dynextra.nlg +48 -28
- package/plugins/serviceAws/aws_s3.nlg +74 -28
- package/plugins/serviceAws/dbt_aws.nlg +73 -24
- package/plugins/serviceAws/psm_aws.nlg +30 -11
- package/plugins/serviceAws/serviceAws.nlg +2 -4
|
@@ -11,6 +11,64 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
/*
|
|
15
|
+
* FileReader
|
|
16
|
+
*
|
|
17
|
+
* Read file(s) from the browser's host machine. This is passed a File object and returns a
|
|
18
|
+
* nearly-standard (error, blob, size) tuple. If progress is specified then this function is called
|
|
19
|
+
* with a percentage of completion from zero to 100 if available, or true otherwise. The progress
|
|
20
|
+
* callback is called with "false" when completed, with or without success
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
closure FileReader(file, progress, local pending, freader, result) {
|
|
25
|
+
pending = new(nonce)
|
|
26
|
+
freader = xnew(window.FileReader)
|
|
27
|
+
freader.addEventListener("load", function(event, local blob) {
|
|
28
|
+
blob = xnew(window.Blob, [freader.result], {
|
|
29
|
+
type: file.type
|
|
30
|
+
})
|
|
31
|
+
pending.signal(list(false, blob, event.total))
|
|
32
|
+
})
|
|
33
|
+
freader.addEventListener("error", function(error) {
|
|
34
|
+
pending.signal(list(error))
|
|
35
|
+
})
|
|
36
|
+
freader.AddEventListener("progress", function(event) {
|
|
37
|
+
if event.lengthComputable && event.total
|
|
38
|
+
progress(toint((event.loaded * 100) / event.total))
|
|
39
|
+
else
|
|
40
|
+
progress(true)
|
|
41
|
+
})
|
|
42
|
+
freader.readAsArrayBuffer(file)
|
|
43
|
+
result = pending.wait()
|
|
44
|
+
progress(false)
|
|
45
|
+
result
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
* FileDownload
|
|
51
|
+
*
|
|
52
|
+
* Download a file from the browser, returning a standard error tuple.
|
|
53
|
+
*
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
closure FileDownload(file, progress, local error, blob, sizez, url, link) {
|
|
57
|
+
`(error, blob, size) = FileReader(file, progress)
|
|
58
|
+
if error
|
|
59
|
+
list(error)
|
|
60
|
+
else {
|
|
61
|
+
url = window.URL.createObjectURL(blob)
|
|
62
|
+
link = document.createElement("a")
|
|
63
|
+
link.href = url
|
|
64
|
+
link.download = file.name
|
|
65
|
+
link.click()
|
|
66
|
+
window.URL.revokeObjectURL(url)
|
|
67
|
+
list(false, file.name)
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
|
|
14
72
|
/*
|
|
15
73
|
* brorInit
|
|
16
74
|
*
|
|
@@ -20,11 +78,18 @@
|
|
|
20
78
|
*/
|
|
21
79
|
|
|
22
80
|
function brorInit(local manifest) {
|
|
23
|
-
manifest = `(brorInit)
|
|
81
|
+
manifest = `(FileReader, FileDownload, brorInit)
|
|
24
82
|
|
|
25
83
|
Naan.module.build(module.id, "browser", function(modobj, compobj) {
|
|
26
84
|
require("../common").LiveImport()
|
|
27
85
|
compobj.manifest = manifest
|
|
28
|
-
|
|
86
|
+
modobj.exports.FileReader = FileReader
|
|
87
|
+
modobj.exports.FileDownload = FileDownload
|
|
88
|
+
|
|
89
|
+
function brorReload() {
|
|
90
|
+
window = js.w
|
|
91
|
+
document = window.document
|
|
92
|
+
}()
|
|
93
|
+
module.reload = brorReload
|
|
29
94
|
})
|
|
30
95
|
} ();
|
|
@@ -72,7 +72,7 @@ closure HttpsApiRequest(url, options,
|
|
|
72
72
|
//
|
|
73
73
|
// perform the fetch and return when complete
|
|
74
74
|
//
|
|
75
|
-
`(error, response) = await(
|
|
75
|
+
`(error, response) = await(window.fetch(urlq, fetchOptions))
|
|
76
76
|
if error
|
|
77
77
|
return (list(Error("HttpsApiRequest fetch failed:", error, url)))
|
|
78
78
|
contentType = response.headers.get("content-type")
|
|
@@ -113,7 +113,7 @@ function https_browserInit(local manifest) {
|
|
|
113
113
|
manifest = `(HttpsApiRequest, https_browserInit)
|
|
114
114
|
|
|
115
115
|
Naan.module.build(module.id, "https_request", function(modobj, compobj) {
|
|
116
|
-
require("
|
|
116
|
+
require("browser.nlg")
|
|
117
117
|
compobj.manifest = manifest
|
|
118
118
|
modobj.exports.HttpsApiRequest = HttpsApiRequest
|
|
119
119
|
})
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
*
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
var CurrentCacheName = "Naanlang-1.0.
|
|
39
|
+
var CurrentCacheName = "Naanlang-1.0.7+2";
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
//
|
|
@@ -89,11 +89,11 @@ var waitingForInit = []; // initialization functions, or
|
|
|
89
89
|
var pubVersion = event.data.hereIsMyVersion;
|
|
90
90
|
var sourceId = event.source.id; // client id of sender of message
|
|
91
91
|
msgPorts[sourceId] = msgport;
|
|
92
|
-
console.log("[1.0.
|
|
93
|
-
if (pubVersion != "1.0.
|
|
92
|
+
console.log("[1.0.7+2] received new msgport for", sourceId, pubID, "-", pubVersion);
|
|
93
|
+
if (pubVersion != "1.0.7+2")
|
|
94
94
|
msgport.postMessage({ // notify new version available
|
|
95
95
|
id: "upgrade",
|
|
96
|
-
version: "1.0.
|
|
96
|
+
version: "1.0.7+2"
|
|
97
97
|
});
|
|
98
98
|
Reaper(); // clean up obsolete info
|
|
99
99
|
|
|
@@ -107,7 +107,7 @@ var waitingForInit = []; // initialization functions, or
|
|
|
107
107
|
if (msg.id == "response")
|
|
108
108
|
processResponse(msg);
|
|
109
109
|
else if (msg.id == "text")
|
|
110
|
-
console.log("[1.0.
|
|
110
|
+
console.log("[1.0.7+2] msg received:", msg.text);
|
|
111
111
|
};
|
|
112
112
|
|
|
113
113
|
// send text to IDE log
|
|
@@ -118,7 +118,7 @@ var waitingForInit = []; // initialization functions, or
|
|
|
118
118
|
// don't clutter the log
|
|
119
119
|
msgport.postMessage({
|
|
120
120
|
id: "text",
|
|
121
|
-
text: "port received by 1.0.
|
|
121
|
+
text: "port received by 1.0.7+2",
|
|
122
122
|
});
|
|
123
123
|
*/
|
|
124
124
|
if (--pending === 0)
|
|
@@ -135,7 +135,7 @@ var waitingForInit = []; // initialization functions, or
|
|
|
135
135
|
includeUncontrolled: true
|
|
136
136
|
}).then(function(clientList) {
|
|
137
137
|
clientList.every(function(client) {
|
|
138
|
-
console.log("[1.0.
|
|
138
|
+
console.log("[1.0.7+2] requesting new msgport for", client.id);
|
|
139
139
|
++pending;
|
|
140
140
|
client.postMessage({ // tell client(s) we need this fetch source
|
|
141
141
|
msg: "Naan_need_fetch_port",
|
|
@@ -181,12 +181,12 @@ function Reaper() {
|
|
|
181
181
|
clients[clientList[clidex].id] = clientList[clidex];
|
|
182
182
|
for (var sourceId in msgPorts)
|
|
183
183
|
if (!clients[sourceId]) {
|
|
184
|
-
console.log("[1.0.
|
|
184
|
+
console.log("[1.0.7+2] source gone:", sourceId);
|
|
185
185
|
delete msgPorts[sourceId]; // no longer a source
|
|
186
186
|
}
|
|
187
187
|
for (var clientId in fetchPorts)
|
|
188
188
|
if (!clients[clientId]) {
|
|
189
|
-
console.log("[1.0.
|
|
189
|
+
console.log("[1.0.7+2] client gone:", clientId);
|
|
190
190
|
delete fetchPorts[clientId]; // no longer a client
|
|
191
191
|
}
|
|
192
192
|
for (var fqdex = 0; fqdex < fetchQueue.length; ++fqdex) {
|
|
@@ -220,13 +220,13 @@ function ClearCaches() {
|
|
|
220
220
|
return (Promise.all(
|
|
221
221
|
cacheNames.map(function(cacheName) {
|
|
222
222
|
if (cacheName != CurrentCacheName) {
|
|
223
|
-
console.log('[1.0.
|
|
223
|
+
console.log('[1.0.7+2] deleting old cache:', cacheName);
|
|
224
224
|
return (caches.delete(cacheName));
|
|
225
225
|
}
|
|
226
226
|
})
|
|
227
227
|
));
|
|
228
228
|
}).then(function() { // claim all clients
|
|
229
|
-
console.log('[1.0.
|
|
229
|
+
console.log('[1.0.7+2] claiming clients');
|
|
230
230
|
return (self.clients.claim());
|
|
231
231
|
});
|
|
232
232
|
return (promise);
|
|
@@ -269,7 +269,7 @@ function GetClientResponse(event, urlpath) {
|
|
|
269
269
|
msgport.postMessage({
|
|
270
270
|
id: "fetch",
|
|
271
271
|
seq: seqno,
|
|
272
|
-
version: "1.0.
|
|
272
|
+
version: "1.0.7+2",
|
|
273
273
|
request: {
|
|
274
274
|
method: event.request.method,
|
|
275
275
|
url: event.request.url
|
|
@@ -317,7 +317,7 @@ function GetClientResponse(event, urlpath) {
|
|
|
317
317
|
*/
|
|
318
318
|
|
|
319
319
|
self.addEventListener('install', function(event) {
|
|
320
|
-
console.log("[1.0.
|
|
320
|
+
console.log("[1.0.7+2] install");
|
|
321
321
|
self.skipWaiting();
|
|
322
322
|
});
|
|
323
323
|
|
|
@@ -339,7 +339,7 @@ self.addEventListener('fetch', function(event) {
|
|
|
339
339
|
var promise;
|
|
340
340
|
var url = new URL(event.request.url);
|
|
341
341
|
var nocache = event.request.method != "GET"
|
|
342
|
-
|| url.search.length !== 0
|
|
342
|
+
|| url.search.length !== 0 && url.searchParams.get("naanver") !== "cb-1.0.7+2"
|
|
343
343
|
|| event.request.headers.get('range');
|
|
344
344
|
if (url.pathname.startsWith("/run/")) {
|
|
345
345
|
nocache = true;
|
|
@@ -356,7 +356,7 @@ self.addEventListener('fetch', function(event) {
|
|
|
356
356
|
}
|
|
357
357
|
else
|
|
358
358
|
promise = fetch(event.request).catch(function (e) {
|
|
359
|
-
console.log("[1.0.
|
|
359
|
+
console.log("[1.0.7+2] fetch failed", e);
|
|
360
360
|
return (new Response(undefined, {
|
|
361
361
|
status: 404,
|
|
362
362
|
statusText: "Fetch Failed"
|
|
@@ -385,14 +385,14 @@ self.addEventListener('fetch', function(event) {
|
|
|
385
385
|
*/
|
|
386
386
|
|
|
387
387
|
self.addEventListener('activate', function(event) {
|
|
388
|
-
console.log("[1.0.
|
|
388
|
+
console.log("[1.0.7+2] activate");
|
|
389
389
|
self.clients.matchAll({ // for debugging, list controlled clients
|
|
390
390
|
includeUncontrolled: true
|
|
391
391
|
}).then(function(clientList) {
|
|
392
392
|
var urls = clientList.map(function(client) {
|
|
393
393
|
return (client.url);
|
|
394
394
|
});
|
|
395
|
-
console.log('[1.0.
|
|
395
|
+
console.log('[1.0.7+2] matching clients:', urls.join(', '));
|
|
396
396
|
});
|
|
397
397
|
var promise = ClearCaches();
|
|
398
398
|
if (event.waitUntil)
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
closure TermHost(track, api, name, workerID, options,
|
|
22
22
|
local target, nlregex, clientID, serverID)
|
|
23
23
|
{
|
|
24
|
-
target =
|
|
24
|
+
target = require("../running/executors.nlg").ExecutorBase(track, "Host", name)
|
|
25
25
|
clientID = "DebugWorkers"
|
|
26
26
|
serverID = "Workers"
|
|
27
27
|
nlregex = RegExp("\\n", "g")
|
|
@@ -35,7 +35,7 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
35
35
|
closure connect(local pending) {
|
|
36
36
|
if target.ws
|
|
37
37
|
return
|
|
38
|
-
target.ws = xnew(
|
|
38
|
+
target.ws = xnew(window.WebSocket,"ws://".concat(window.location.host)) // ### use api parameter
|
|
39
39
|
pending = new(nonce)
|
|
40
40
|
|
|
41
41
|
// onopen
|
|
@@ -52,7 +52,7 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
52
52
|
|
|
53
53
|
target.ws.onmessage = function onmessage(e, message, local msg) {
|
|
54
54
|
try {
|
|
55
|
-
message = new(
|
|
55
|
+
message = new(window.JSON.parse(e.data))
|
|
56
56
|
} catch {
|
|
57
57
|
if true {
|
|
58
58
|
debuglog("can't decode incoming ws message:", exception)
|
|
@@ -169,7 +169,7 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
169
169
|
// Send a message to the worker controller.
|
|
170
170
|
|
|
171
171
|
target.sendControl = function sendControl(workerOp, payload) {
|
|
172
|
-
target.ws.send(
|
|
172
|
+
target.ws.send(window.JSON.stringify({
|
|
173
173
|
guid: api.guid
|
|
174
174
|
clientID: clientID
|
|
175
175
|
serverID: serverID
|
|
@@ -368,23 +368,23 @@ closure TermLocal(track, name, workerID, options,
|
|
|
368
368
|
options = new(options)
|
|
369
369
|
else
|
|
370
370
|
options = { }
|
|
371
|
-
target =
|
|
371
|
+
target = require("../running/executors.nlg").ExecutorBase(track, "Local", name)
|
|
372
372
|
nlregex = RegExp("\\n", "g")
|
|
373
373
|
target.workerID = workerID
|
|
374
374
|
target.msgQueue = []
|
|
375
375
|
if workerID == "NaanIDE-Debug" {
|
|
376
|
-
target.worker =
|
|
376
|
+
target.worker = window.open(window.location.href, "_blank")
|
|
377
377
|
target.worker.addEventListener("beforeunload", function(e) { // our target is closing
|
|
378
378
|
destroy()
|
|
379
379
|
})
|
|
380
|
-
|
|
380
|
+
window.addEventListener("beforeunload", function(e) { // we are closing
|
|
381
381
|
// ### tell target we are closing (if needed)
|
|
382
382
|
})
|
|
383
|
-
listener =
|
|
383
|
+
listener = window
|
|
384
384
|
} else {
|
|
385
|
-
if not
|
|
385
|
+
if not window.Worker
|
|
386
386
|
return (list(Error("Local environment does not support workers")))
|
|
387
|
-
target.worker = xnew(
|
|
387
|
+
target.worker = xnew(window.Worker, "env_webworker.js")
|
|
388
388
|
listener = target.worker
|
|
389
389
|
}
|
|
390
390
|
|
|
@@ -460,6 +460,8 @@ closure TermLocal(track, name, workerID, options,
|
|
|
460
460
|
target.statusCB(target, msg.status)
|
|
461
461
|
else if msg.id == "debugout"
|
|
462
462
|
target.debugger.debugData(target, msg.data)
|
|
463
|
+
else if msg.id == "download"
|
|
464
|
+
FileDownload(xnew(window.File, msg.bits, msg.name, msg.options))
|
|
463
465
|
else if msg.id == "loaded" {
|
|
464
466
|
if !target.started
|
|
465
467
|
target.worker.postMessage({
|
|
@@ -610,7 +612,7 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
|
|
|
610
612
|
track.update(target)
|
|
611
613
|
return (target)
|
|
612
614
|
}
|
|
613
|
-
target =
|
|
615
|
+
target = require("../running/executors.nlg").ExecutorBase(track, "Local", name)
|
|
614
616
|
target.name = name
|
|
615
617
|
target.title = title
|
|
616
618
|
target.workerID = workerID
|
|
@@ -778,7 +780,7 @@ closure termInstallVirtualWatcher(track, naancont) {
|
|
|
778
780
|
}
|
|
779
781
|
}
|
|
780
782
|
|
|
781
|
-
|
|
783
|
+
require("../running/executors.nlg").TaskOnMessageHook(watchVsites)
|
|
782
784
|
};
|
|
783
785
|
|
|
784
786
|
|
|
@@ -29,7 +29,7 @@ closure ServiceWorker(pubID, pubVersion, local serv, callback) {
|
|
|
29
29
|
closure updateReg(local mchan) {
|
|
30
30
|
if !serv.sw
|
|
31
31
|
return
|
|
32
|
-
mchan = xnew(
|
|
32
|
+
mchan = xnew(window.MessageChannel)
|
|
33
33
|
serv.msgport = mchan.port2
|
|
34
34
|
serv.msgport.onmessage = workerMsg.proc
|
|
35
35
|
serv.sw.postMessage({
|
|
@@ -112,13 +112,13 @@ closure ServiceWorker(pubID, pubVersion, local serv, callback) {
|
|
|
112
112
|
serv.scope = scope
|
|
113
113
|
if !scope
|
|
114
114
|
return (makeResult(Error("service worker scope required")))
|
|
115
|
-
if !
|
|
115
|
+
if !window.navigator.serviceWorker
|
|
116
116
|
return (makeResult(Error("service workers not supported")))
|
|
117
|
-
|
|
117
|
+
window.navigator.serviceWorker.addEventListener("message", function(event) {
|
|
118
118
|
if event.data.msg == "Naan_need_fetch_port"
|
|
119
119
|
updateReg()
|
|
120
120
|
})
|
|
121
|
-
await(
|
|
121
|
+
await(window.navigator.serviceWorker.register("sworker.js", { scope: scope }).then(function (reg) {
|
|
122
122
|
return (reg.update())
|
|
123
123
|
}).then(function (reg) {
|
|
124
124
|
serv.reg = reg
|
|
@@ -211,7 +211,7 @@ closure ScopedServiceWorker(pubID, pubVersion, callback, local scoper, result) {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
// read resource
|
|
214
|
-
filepath = xnew(
|
|
214
|
+
filepath = xnew(window.URL, data.request.url).pathname
|
|
215
215
|
filepath = DecodeURIComponent(filepath) // "/run/<scope>/path..."
|
|
216
216
|
filepath = filepath.slice(4) // "/<scope>/path..."
|
|
217
217
|
error = true // stays true iff not in scope
|
|
@@ -308,7 +308,7 @@ closure TrackedScope(track, scope, fs, rootpath, local trope, result) {
|
|
|
308
308
|
trope = findTrackedScope(track, scope)
|
|
309
309
|
if trope
|
|
310
310
|
return (list(false, trope))
|
|
311
|
-
trope =
|
|
311
|
+
trope = require("../running/executors.nlg").ExecutorBase(track, "ServiceWorkers", scope)
|
|
312
312
|
serviceWorker.register(scope, closure(filepath, scope, init,
|
|
313
313
|
local options, mimeType, error, data) {
|
|
314
314
|
mimeType = {
|
|
@@ -37,7 +37,7 @@ closure MakeNideAPIclient(url, guid, local client) {
|
|
|
37
37
|
request.addEventListener("error", function reqFailed(event, local errtext) {
|
|
38
38
|
if request.status == 0
|
|
39
39
|
errtext = "connectivity"
|
|
40
|
-
|
|
40
|
+
else
|
|
41
41
|
errtext = "request failed"
|
|
42
42
|
error = Error(errtext, {
|
|
43
43
|
status: request.status
|
|
@@ -136,10 +136,10 @@ closure psmcFsView(api, rootpath, local view, pathmod) {
|
|
|
136
136
|
// readLines
|
|
137
137
|
//
|
|
138
138
|
// Read a lines of a file at the specified path with options:
|
|
139
|
-
// matchRE:
|
|
140
|
-
// ignoreCase:
|
|
141
|
-
// invert:
|
|
142
|
-
// returnText:
|
|
139
|
+
// matchRE: -- JavaScript regex
|
|
140
|
+
// ignoreCase: -- ignore case during match
|
|
141
|
+
// invert: -- return lines that DO NOT match the regex
|
|
142
|
+
// returnText: -- return text of matched lines
|
|
143
143
|
// When using a matchRE, the return value is an array of [ lineNumber, text ] pairs if
|
|
144
144
|
// returnText is specified, or just an array of one-based line numbers otherwise.
|
|
145
145
|
//
|
|
@@ -288,6 +288,10 @@ closure psmcFsView(api, rootpath, local view, pathmod) {
|
|
|
288
288
|
// Search the specified file or recursive directory.
|
|
289
289
|
|
|
290
290
|
view.dirSearch = function dirSearch(path, options, callback) {
|
|
291
|
+
if options.excludeDirs {
|
|
292
|
+
options = new(options)
|
|
293
|
+
options.excludeDirs = JSONstringify(options.excludeDirs)
|
|
294
|
+
}
|
|
291
295
|
psmRemote(path, "dirSearch", options, false, callback)
|
|
292
296
|
}
|
|
293
297
|
|
|
@@ -357,6 +361,10 @@ closure psmcFsView(api, rootpath, local view, pathmod) {
|
|
|
357
361
|
// Grep the specified file or recursive directory.
|
|
358
362
|
|
|
359
363
|
view.grepLines = function grepLines(path, options, callback) {
|
|
364
|
+
if options.excludeDirs {
|
|
365
|
+
options = new(options)
|
|
366
|
+
options.excludeDirs = JSONstringify(options.excludeDirs)
|
|
367
|
+
}
|
|
360
368
|
psmRemote(path, "grepLines", options, false, callback)
|
|
361
369
|
}
|
|
362
370
|
|
|
@@ -143,7 +143,7 @@ function JsonStringify(data) {
|
|
|
143
143
|
jsScripts = { }; // script values become false on reload
|
|
144
144
|
|
|
145
145
|
function JsLoadScript(libpath, globalID, local scriptTag, fpath) {
|
|
146
|
-
if jsScripts[
|
|
146
|
+
if jsScripts[libpath]
|
|
147
147
|
return // already loaded
|
|
148
148
|
if libpath.startsWith("/")
|
|
149
149
|
fpath = libpath
|
|
@@ -155,10 +155,10 @@ function JsLoadScript(libpath, globalID, local scriptTag, fpath) {
|
|
|
155
155
|
} else if js.w { // load in browser context
|
|
156
156
|
pending = new(nonce)
|
|
157
157
|
scriptTag = js.w.document.createElement("script")
|
|
158
|
-
scriptTag.src = js.w.location.origin.concat(fpath)
|
|
158
|
+
scriptTag.src = js.w.location.origin.concat(fpath, requireQuery())
|
|
159
159
|
scriptTag.onload = function (event) {
|
|
160
160
|
jsScripts[libpath] = js.w[globalID]
|
|
161
|
-
pending.signal(
|
|
161
|
+
pending.signal(js.w[globalID])
|
|
162
162
|
true
|
|
163
163
|
}
|
|
164
164
|
scriptTag.onerror = function (event) {
|
|
@@ -303,7 +303,8 @@ JSONparse = false;
|
|
|
303
303
|
Uint8ArrayFromString = false;
|
|
304
304
|
|
|
305
305
|
function comrInit(local manifest) {
|
|
306
|
-
manifest = `(EncodeQuery, ContentTypeFromFileExt, UUID,
|
|
306
|
+
manifest = `(EncodeQuery, ContentTypeFromFileExt, UUID, JsonParse, JsonStringify, JsLoadScript,
|
|
307
|
+
LoadComponentOnDemand, LiveExport, comrInit)
|
|
307
308
|
|
|
308
309
|
Naan.module.build(module.id, "common", closure(modobj, compobj) {
|
|
309
310
|
compobj.manifest = manifest
|
|
@@ -373,10 +374,17 @@ function comrInit(local manifest) {
|
|
|
373
374
|
result
|
|
374
375
|
}
|
|
375
376
|
//
|
|
376
|
-
//
|
|
377
|
+
// EncodeBase64url - decode base64url to original string
|
|
377
378
|
// See https://en.wikipedia.org/wiki/Base64 for details on variants
|
|
378
379
|
//
|
|
379
|
-
|
|
380
|
+
EncodeBase64url = function encodeBase64url(data) {
|
|
381
|
+
data = EncodeBase64(data)
|
|
382
|
+
data.replace(RegExp("[+]", "g"), '-').replace(RegExp("/", "g"), '_')
|
|
383
|
+
}
|
|
384
|
+
//
|
|
385
|
+
// DecodeBase64url - decode base64url to original string
|
|
386
|
+
//
|
|
387
|
+
DecodeBase64url = function decodeBase64url(base64url) {
|
|
380
388
|
base64url = base64url.replace(RegExp("-", "g"), '+').replace(RegExp("_", "g"), '/')
|
|
381
389
|
DecodeBase64(base64url)
|
|
382
390
|
}
|
|
@@ -411,7 +419,9 @@ function comrInit(local manifest) {
|
|
|
411
419
|
}
|
|
412
420
|
//
|
|
413
421
|
// MD5 functions
|
|
414
|
-
|
|
422
|
+
if symbol(NideBuild) { // execute if we are not building
|
|
423
|
+
JsLoadScript("frameworks/browser/spark-md5/spark-md5.min.js", "SparkMD5")
|
|
424
|
+
}
|
|
415
425
|
//
|
|
416
426
|
// hasMD5 in hex
|
|
417
427
|
HashMD5 = function browserMD5(data, raw) {
|
|
@@ -526,6 +536,7 @@ function comrInit(local manifest) {
|
|
|
526
536
|
modobj.exports.JsonStringify = JsonStringify
|
|
527
537
|
modobj.exports.JsonParse = JsonParse
|
|
528
538
|
modobj.exports.Uint8ArrayFromString = Uint8ArrayFromString
|
|
539
|
+
modobj.exports.EncodeBase64url = EncodeBase64url
|
|
529
540
|
modobj.exports.DecodeBase64url = DecodeBase64url
|
|
530
541
|
modobj.exports.HashMD5 = HashMD5
|
|
531
542
|
modobj.exports.HashMD5_base64 = HashMD5_base64
|
|
@@ -171,8 +171,8 @@ closure MakeAPI(port, options, callback, local chroot, server) {
|
|
|
171
171
|
res.status(403).send("unauthorized")
|
|
172
172
|
timeoutms = toint(req.query.timeout)
|
|
173
173
|
after = toint(req.query.after)
|
|
174
|
-
if not integer(timeoutms) or timeoutms >
|
|
175
|
-
res.status(400).send("timeout is integer milliseconds no greater than
|
|
174
|
+
if not integer(timeoutms) or timeoutms > 7200000
|
|
175
|
+
res.status(400).send("timeout is integer milliseconds no greater than 7200000")
|
|
176
176
|
else if not integer(after)
|
|
177
177
|
res.status(400).send("after must be an integer")
|
|
178
178
|
else {
|
|
@@ -181,11 +181,11 @@ closure Filesystem(rootpath, local files, badCreatePathRegEx) {
|
|
|
181
181
|
// readLines
|
|
182
182
|
//
|
|
183
183
|
// Read the contents of a file into an array of lines with the following options:
|
|
184
|
-
// pattern:
|
|
185
|
-
// fixed
|
|
186
|
-
// ignoreCase:
|
|
187
|
-
// invert:
|
|
188
|
-
// returnText:
|
|
184
|
+
// pattern: -- only return lines matching pattern
|
|
185
|
+
// fixed -- pattern is a fixed string, not a regular expression
|
|
186
|
+
// ignoreCase: -- ignore case during match
|
|
187
|
+
// invert: -- return lines that DO NOT match the regex
|
|
188
|
+
// returnText: -- return text of matched lines
|
|
189
189
|
//
|
|
190
190
|
|
|
191
191
|
files.readLines = closure readLines(path, options, callback,
|
|
@@ -748,21 +748,31 @@ closure Filesystem(rootpath, local files, badCreatePathRegEx) {
|
|
|
748
748
|
// dirSearch
|
|
749
749
|
//
|
|
750
750
|
// Search the files in a directory for a pattern.
|
|
751
|
-
|
|
751
|
+
//
|
|
752
|
+
// Most options are handled by readLines, but the following is done here:
|
|
753
|
+
// excludeDirs: [dirnames] -- exclude the specified directory names
|
|
754
|
+
|
|
752
755
|
files.dirSearch = closure dirSearch(path, options, callback,
|
|
753
|
-
local error, localpaths, output) {
|
|
756
|
+
local error, localpaths, dexmatch, item, output) {
|
|
754
757
|
if !callback
|
|
755
758
|
return (syncAdapter(dirSearch, path, options))
|
|
756
759
|
`(error, localpath) = localPath(path)
|
|
757
760
|
if error
|
|
758
761
|
return (asyncResult(callback, error))
|
|
762
|
+
if options.excludeDirs.0 { // match all provided paths
|
|
763
|
+
dexmatch = []
|
|
764
|
+
for item in options.excludeDirs // escape all special characters
|
|
765
|
+
dexmatch.push(item.replace(RegExp("[^A-Za-z0-9-_\n]","g"), "\\$&"))
|
|
766
|
+
dexmatch = RegExp(dexmatch.join("|"))
|
|
767
|
+
}
|
|
759
768
|
output = []
|
|
760
769
|
debuglog("dirSearch begins", localpath)
|
|
761
770
|
asyncArray(localpaths, 10, closure(localpath, index, elements, local error, direnum, node, lines, line) {
|
|
762
771
|
`(error, direnum) = dirList(localpath, { })
|
|
763
772
|
if direnum.children
|
|
764
773
|
for node in direnum.children
|
|
765
|
-
|
|
774
|
+
if !dexmatch || !node.name.match(dexmatch)
|
|
775
|
+
localpaths.push(JSpath.join(localpath, node.name)) // more files or directories to examine
|
|
766
776
|
else {
|
|
767
777
|
`(error, lines) = readLines(localpath, options)
|
|
768
778
|
if error && localpaths.length == 1 {
|
|
@@ -986,22 +996,29 @@ closure Filesystem(rootpath, local files, badCreatePathRegEx) {
|
|
|
986
996
|
//
|
|
987
997
|
// Return an array of text matches in a file or recursive directory of files with the following
|
|
988
998
|
// options:
|
|
989
|
-
// pattern:
|
|
990
|
-
// ignoreCase:
|
|
991
|
-
// invert:
|
|
992
|
-
// returnText:
|
|
993
|
-
//
|
|
999
|
+
// pattern: -- pattern to find
|
|
1000
|
+
// ignoreCase: -- ignore case during match
|
|
1001
|
+
// invert: -- return lines that DO NOT match the regex
|
|
1002
|
+
// returnText: -- return text of matched lines
|
|
1003
|
+
// excludeDirs: [dirnames] -- exclude the specified directory names
|
|
1004
|
+
// maxCount: -- integer maximum number of results (default 10,000)
|
|
994
1005
|
// grep-specific options:
|
|
995
|
-
// ignoreBinary:
|
|
1006
|
+
// ignoreBinary: -- ignore binary files
|
|
996
1007
|
//
|
|
997
1008
|
files.grepLines = closure grepLines(path, options, callback,
|
|
998
|
-
local error, localpath, cmdargs, execOptions, grep, result, lineRE, maxcount) {
|
|
1009
|
+
local error, localpath, cmdargs, item, execOptions, grep, result, lineRE, maxcount) {
|
|
999
1010
|
if !callback
|
|
1000
1011
|
return (syncAdapter(grepLines, path, options))
|
|
1001
1012
|
`(error, localpath) = localPath(path)
|
|
1002
1013
|
if error
|
|
1003
1014
|
return (asyncResult(callback, error))
|
|
1004
1015
|
cmdargs = ["-rn"] // recursively search directories for files; report line numbers
|
|
1016
|
+
if options.excludeDirs.0 { // exclude a directory
|
|
1017
|
+
for item in options.excludeDirs {
|
|
1018
|
+
cmdargs.push("--exclude-dir")
|
|
1019
|
+
cmdargs.push(item)
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1005
1022
|
if options.ignoreCase
|
|
1006
1023
|
cmdargs.push("-i")
|
|
1007
1024
|
if options.invert
|
|
@@ -204,6 +204,7 @@ closure psmsFsView(rootpath, local view, gitter) {
|
|
|
204
204
|
|
|
205
205
|
// op: dirSearch
|
|
206
206
|
function dirSearchApi() {
|
|
207
|
+
req.query.excludeDirs = JSONparse(req.query.excludeDirs)
|
|
207
208
|
res.send(new(array, view.dirSearch(path, req.query)))
|
|
208
209
|
}
|
|
209
210
|
|
|
@@ -239,6 +240,7 @@ closure psmsFsView(rootpath, local view, gitter) {
|
|
|
239
240
|
|
|
240
241
|
// op: grepLines
|
|
241
242
|
function grepLinesApi() {
|
|
243
|
+
req.query.excludeDirs = JSONparse(req.query.excludeDirs)
|
|
242
244
|
res.send(new(array, view.grepLines(path, req.query)))
|
|
243
245
|
}
|
|
244
246
|
|
|
@@ -289,8 +291,15 @@ closure psmsFsView(rootpath, local view, gitter) {
|
|
|
289
291
|
gitLog: gitLogApi
|
|
290
292
|
gitShowFile: gitShowFileApi
|
|
291
293
|
}[req.query.op]
|
|
292
|
-
if proc
|
|
293
|
-
|
|
294
|
+
if proc {
|
|
295
|
+
try {
|
|
296
|
+
proc()
|
|
297
|
+
} catch {
|
|
298
|
+
if true {
|
|
299
|
+
res.status(400).send("psm op failed: ".concat(req.query.op, ": ", exception))
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
294
303
|
else
|
|
295
304
|
res.status(400).send("invalid psm op: ".concat(req.query.op))
|
|
296
305
|
}
|