@naanlang/naan 1.0.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.
Files changed (98) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +46 -0
  3. package/dist/env_web.js +431 -0
  4. package/dist/naan.min.js +73 -0
  5. package/frameworks/browser/browser.nlg +30 -0
  6. package/frameworks/browser/pouchdb/pouchdb.min.js +7 -0
  7. package/frameworks/browser/spark-md5/spark-md5.min.js +1 -0
  8. package/frameworks/browser/sworker.js +192 -0
  9. package/frameworks/browser/terminals.nlg +787 -0
  10. package/frameworks/browser/workers.nlg +386 -0
  11. package/frameworks/client/apiclient.nlg +183 -0
  12. package/frameworks/client/client.nlg +29 -0
  13. package/frameworks/client/psm_client.nlg +572 -0
  14. package/frameworks/common/common.nlg +464 -0
  15. package/frameworks/common/preferences.nlg +131 -0
  16. package/frameworks/common/repltools.nlg +100 -0
  17. package/frameworks/common/watching.nlg +97 -0
  18. package/frameworks/node/apiserver.nlg +399 -0
  19. package/frameworks/node/filesystem.nlg +1012 -0
  20. package/frameworks/node/gitter.nlg +234 -0
  21. package/frameworks/node/node.nlg +81 -0
  22. package/frameworks/node/psm_server.nlg +465 -0
  23. package/frameworks/node/worker.nlg +560 -0
  24. package/frameworks/project/build.nlg +1229 -0
  25. package/frameworks/project/jszip.js +30 -0
  26. package/frameworks/project/jszip.nlg +87 -0
  27. package/frameworks/project/proj_cliser.nlg +139 -0
  28. package/frameworks/project/proj_console.nlg +137 -0
  29. package/frameworks/project/proj_folder.nlg +143 -0
  30. package/frameworks/project/proj_lambda.nlg +137 -0
  31. package/frameworks/project/proj_static.nlg +138 -0
  32. package/frameworks/project/project.nlg +29 -0
  33. package/frameworks/project/projects.nlg +587 -0
  34. package/frameworks/project/uglifyjs.js +1 -0
  35. package/frameworks/project/uglifyjs.nlg +79 -0
  36. package/frameworks/running/debugcom.nlg +163 -0
  37. package/frameworks/running/debugnub.nlg +565 -0
  38. package/frameworks/running/debugutil.nlg +510 -0
  39. package/frameworks/running/executors.nlg +767 -0
  40. package/frameworks/running/running.nlg +151 -0
  41. package/frameworks/running/sourcecode.nlg +346 -0
  42. package/frameworks/running/taskexec.nlg +196 -0
  43. package/frameworks/storage/dbt_pouch.nlg +773 -0
  44. package/frameworks/storage/file_manager.nlg +772 -0
  45. package/frameworks/storage/psm.nlg +326 -0
  46. package/frameworks/storage/psm_dbtables.nlg +814 -0
  47. package/frameworks/storage/resources.nlg +445 -0
  48. package/frameworks/storage/storage.nlg +52 -0
  49. package/lib/browser/env_web.js +431 -0
  50. package/lib/browser/env_webworker.js +146 -0
  51. package/lib/browser/require.js +1653 -0
  52. package/lib/core/naanlib.js +73 -0
  53. package/lib/env_node.js +282 -0
  54. package/lib/env_nodeworker.js +165 -0
  55. package/lib/node_repl.js +25 -0
  56. package/lib/node_repl_init.nlg +52 -0
  57. package/package.json +13 -0
  58. package/plugins/gitClient/clientops.nlg +317 -0
  59. package/plugins/gitClient/gitClient.nlg +63 -0
  60. package/plugins/gitClient/gitutils.nlg +1331 -0
  61. package/plugins/gitClient/minimatch.js +945 -0
  62. package/plugins/gitClient/minimatch_license.txt +15 -0
  63. package/plugins/gitClient/minimatch_readme.md +208 -0
  64. package/plugins/nodeLib/nodeLib.nlg +26 -0
  65. package/plugins/nodeLib/node_cp.nlg +65 -0
  66. package/plugins/nodeLib/node_fs.nlg +137 -0
  67. package/plugins/nodeLib/node_https.nlg +172 -0
  68. package/plugins/nodeLib/node_util.nlg +180 -0
  69. package/plugins/serviceAws/aws/aws-sdk.min.js +88 -0
  70. package/plugins/serviceAws/aws/lambda_rest_index.js +122 -0
  71. package/plugins/serviceAws/aws/lambda_rest_init.nlg +58 -0
  72. package/plugins/serviceAws/aws/lambda_ws_index.js +498 -0
  73. package/plugins/serviceAws/aws/lambda_ws_init.nlg +49 -0
  74. package/plugins/serviceAws/aws_cloudwatchlogs.nlg +122 -0
  75. package/plugins/serviceAws/aws_cognito.nlg +76 -0
  76. package/plugins/serviceAws/aws_dynamo.nlg +509 -0
  77. package/plugins/serviceAws/aws_lambda.nlg +95 -0
  78. package/plugins/serviceAws/aws_s3.nlg +134 -0
  79. package/plugins/serviceAws/aws_utils.nlg +86 -0
  80. package/plugins/serviceAws/dbt_aws.nlg +769 -0
  81. package/plugins/serviceAws/lambda_naan_control.nlg +175 -0
  82. package/plugins/serviceAws/psm_aws.nlg +258 -0
  83. package/plugins/serviceAws/serviceAws.nlg +38 -0
  84. package/plugins/serviceGitHub/gitops.nlg +522 -0
  85. package/plugins/serviceGitHub/psm_github.nlg +205 -0
  86. package/plugins/serviceGitHub/serviceGitHub.nlg +65 -0
  87. package/plugins/serviceGitLab/gitops.nlg +528 -0
  88. package/plugins/serviceGitLab/psm_gitlab.nlg +205 -0
  89. package/plugins/serviceGitLab/serviceGitLab.nlg +65 -0
  90. package/test/harness.nlg +312 -0
  91. package/test/node_test.js +33 -0
  92. package/test/test_01_core.nlg +768 -0
  93. package/test/test_02_context.nlg +269 -0
  94. package/test/test_03_jsinterop.nlg +137 -0
  95. package/test/test_04_numerics.nlg +450 -0
  96. package/test/test_05_strings.nlg +63 -0
  97. package/test/test_06_lingoparse.nlg +500 -0
  98. package/test/test_07_lingo.nlg +623 -0
@@ -0,0 +1,528 @@
1
+ /*
2
+ * gitops.nlg
3
+ * serviceGitLab
4
+ *
5
+ * GitLab access for performing remote Git operations.
6
+ *
7
+ * column positioning: // // !
8
+ *
9
+ * Copyright (c) 2021 by Richard C. Zulch
10
+ *
11
+ */
12
+
13
+
14
+ /*
15
+ * GitLabOps
16
+ *
17
+ * An object to perfor general GitLab operations using GraphQL.
18
+ *
19
+
20
+ Play-lng> rr = App.nide.locate.connect("04d1e9aa-d154-4e99-b60f-3a67d4033ac4", "Git").1;
21
+ $: Object{2}
22
+ Play-lng> rr.*;
23
+ $: ("userid", "repolist")
24
+ Play-lng> rr.repolist();
25
+ $: (false, {
26
+ data: {
27
+ viewer : {
28
+ repositories: {
29
+ nodes : [
30
+ { name: "DAStool" },
31
+ { name: "DDPinternal" },
32
+ { name: "Naan" },
33
+ { name: "aws-learning" },
34
+ { name: "Naanlang" }] } } } })
35
+ Play-lng> rr.userid();
36
+ $: (false, {
37
+ data: {
38
+ viewer : { login: "rczulch" } } })
39
+
40
+ *
41
+ */
42
+
43
+ closure GitLabOps(access, local gops, url) {
44
+ gops = new(object, this)
45
+ url = "https://gitlab.com/api/graphql"
46
+ urlrest = "https://gitlab.com/api/v4/"
47
+
48
+ // userid
49
+ //
50
+ // Return the userid string for the provided PAT.
51
+ //
52
+ gops.userid = closure userid(local query, error, response, result) {
53
+ query = "{
54
+ \"query\": \"query { currentUser { username }}\"
55
+ }"
56
+ `(error, response) = await(js.w.fetch(
57
+ url, {
58
+ method: "post"
59
+ body: query
60
+ headers: {
61
+ "Content-Type": "application/json",
62
+ "Content-Length": query.length
63
+ "Authorization": "bearer ".concat(access.userPat)
64
+ } }))
65
+ if !error
66
+ `(error, result) = await(response.json())
67
+ if error
68
+ list(Error("GitLab gql fetch failed:", error))
69
+ else if result.error
70
+ list(Error("GitLab query error:", result.error))
71
+ else if !result.data
72
+ list(Error("GitLab empty result"))
73
+ else
74
+ list(false, result.data.currentUser.username)
75
+ }
76
+
77
+ // repolist
78
+ //
79
+ // Return an array of available repositories with Node IDs.
80
+ //
81
+ gops.repolist = closure repolist(local query, response, result) {
82
+ query = "{
83
+ \"query\": \"query { projects (membership: true, first:50) { nodes { name, id, fullPath } } }\"
84
+ }"
85
+ `(error, response) = await(js.w.fetch(
86
+ url, {
87
+ method: "post"
88
+ body: query
89
+ headers: {
90
+ "Content-Type": "application/json",
91
+ "Content-Length": query.length
92
+ "Authorization": "bearer ".concat(access.userPat)
93
+ } }))
94
+ if !error
95
+ `(error, result) = await(response.json())
96
+ if error
97
+ list(Error("GitLab gql fetch failed:", error))
98
+ else if result.error
99
+ list(Error("GitLab query error:", result.error))
100
+ else if !result.data
101
+ list(Error("GitLab empty result"))
102
+ else // output { name, idnum }
103
+ list(false, new(result.data.projects.nodes.map(function(item) {
104
+ {
105
+ name: item.name
106
+ id: item.id.match(RegExp("[0-9]+$")).0
107
+ fullPath: item.fullPath
108
+ }
109
+ })))
110
+ }
111
+
112
+ // repomake
113
+ //
114
+ // Make an empty project (and repo) with the specified name, returning a standard tuple of the
115
+ // `(error, result) form. On success the result is the repodict for the new repo.
116
+ //
117
+ gops.repomake = closure repomake(name, local query, response, result) {
118
+ query = urlrest.concat("projects/", EncodeQuery("?", { name: name }))
119
+ `(error, response) = await(js.w.fetch(
120
+ query, {
121
+ method: "post"
122
+ headers: {
123
+ "Authorization": "bearer ".concat(access.userPat)
124
+ } }))
125
+ if !error
126
+ `(error, result) = await(response.json())
127
+ if error
128
+ list(Error("GitLab post fetch failed:", error))
129
+ else if response.status != 201
130
+ list(Error("GitLab: cannot create repo:", name, new(result), { status: response.status }))
131
+ else
132
+ list(false, {
133
+ name: result.name
134
+ id: result.id
135
+ fullPath: result.path_with_namespace
136
+ })
137
+ }
138
+
139
+ // repo
140
+ //
141
+ // Return a repo access object for the specified repodict.
142
+ //
143
+ gops.repo = function repo(repodict) {
144
+ GitLabRepo(access, repodict)
145
+ }
146
+
147
+ // finis
148
+
149
+ list(false, gops)
150
+ };
151
+
152
+
153
+ /*
154
+ * GitLabRepo
155
+ *
156
+ * An object to perform GitLab repo operations using the REST and GraphQL APIs.
157
+
158
+ rr = App.nide.locate.connect("04d1e9aa-d154-4e99-b60f-3a67d4033ac4", "Git").1;
159
+ glr=rr.repo(rr.repolist().1.1).1;
160
+ glr.tree();
161
+ glr.tree({deep:false});
162
+ glr.tree({path:"myfolder"});
163
+ glr.showfile("app.py");
164
+
165
+ *
166
+ *
167
+ */
168
+
169
+ closure GitLabRepo(access, repodict, local gepo, url) {
170
+ gepo = new(object, this)
171
+ url = "https://gitlab.com/api/graphql"
172
+ urlrest = "https://gitlab.com/api/v4/"
173
+
174
+ // importRestCommit
175
+ //
176
+ // Import a commit from GitLab field terminology to ours.
177
+ //
178
+ function importRestCommit(gldict, local common) {
179
+ common = {
180
+ hash: gldict.id
181
+ author: gldict.author_name
182
+ email: gldict.author_email
183
+ date: gldict.authored_date
184
+ committer_name: gldict.committer_name
185
+ committer_email: gldict.committer_email
186
+ committer_date: gldict.committed_date
187
+ message: gldict.message
188
+ }
189
+ if gldict.parent_ids
190
+ common.parents = gldict.parent_ids
191
+ common
192
+ }
193
+
194
+ // branchesAndTags
195
+ //
196
+ // Return a list of repository branches, with an optional search string.
197
+ //
198
+ closure branchesAndTags(endpoint, pardict, local params, query, error, response, result) {
199
+ if pardict
200
+ params = EncodeQuery("?", pardict)
201
+ else
202
+ params = ""
203
+ query = urlrest.concat("projects/", repodict.id, "/repository/", endpoint, params)
204
+ `(error, response) = await(js.w.fetch(
205
+ query, {
206
+ method: "get"
207
+ headers: {
208
+ "Authorization": "bearer ".concat(access.userPat)
209
+ } }))
210
+ if !error
211
+ `(error, result) = await(response.json())
212
+ if error
213
+ list(Error("GitLab get fetch failed:", error))
214
+ else if !result
215
+ list(Error("GitLab empty result"))
216
+ else
217
+ list(false, new(result.map(function(item, local common) {
218
+ common = {
219
+ name: item.name
220
+ commit: importRestCommit(item.commit)
221
+ }
222
+ if defined(item, merged)
223
+ common.merged = item.merged
224
+ if defined(item, default)
225
+ common.default = item.default
226
+ if defined(item, target)
227
+ common.target = item.target
228
+ if defined(item, message)
229
+ common.message = item.message
230
+ common
231
+ })))
232
+ }
233
+
234
+ // branches
235
+ //
236
+ // Return a list of repository branches, with an optional search string.
237
+ //
238
+ gepo.branches = closure branches(search, local pardict) {
239
+ pardict = {}
240
+ if string(search)
241
+ pardict.search = search
242
+ branchesAndTags("branches", pardict)
243
+ }
244
+
245
+ // tags
246
+ //
247
+ // Return a list of repository tags, with an optional search string.
248
+ //
249
+ gepo.tags = closure tags(search, local pardict) {
250
+ pardict = {}
251
+ if string(search)
252
+ pardict.search = search
253
+ branchesAndTags("tags", pardict)
254
+ }
255
+
256
+ // commits
257
+ //
258
+ // Return a list of commits in the repo, optionally matching the specified file path.
259
+ //
260
+ gepo.commits = closure commits(filepath, local params, query, error, response, result) {
261
+ if filepath
262
+ params = EncodeQuery("?", { path: filepath })
263
+ else
264
+ params = ""
265
+ query = urlrest.concat("projects/", repodict.id, "/repository/commits", params)
266
+ `(error, response) = await(js.w.fetch(
267
+ query, {
268
+ method: "get"
269
+ headers: {
270
+ "Authorization": "bearer ".concat(access.userPat)
271
+ } }))
272
+ if !error
273
+ `(error, result) = await(response.json())
274
+ if error
275
+ list(Error("GitLab get fetch failed:", error))
276
+ else if !result
277
+ list(Error("GitLab empty result"))
278
+ else
279
+ list(false, new(result.map(function(item) {
280
+ importRestCommit(item)
281
+ })))
282
+ }
283
+
284
+ // tree
285
+ //
286
+ // Retrieve a commit tree, with similar structure to filesystem trees. Options include:
287
+ // {
288
+ // path: <relpath> - relative path below repository to start
289
+ // deep: <boolean> - whether to include recursive children.
290
+ // ref: <commit> - branch, tag or commit hash, default "HEAD"
291
+ // }
292
+ //
293
+ gepo.tree = closure tree(options, local path, ref, params, query, error, response, result) {
294
+ path = options.path
295
+ ref = options.ref
296
+ if !ref
297
+ ref = "HEAD"
298
+ params = "ref:".concat("\\\"", ref, "\\\"")
299
+ if !defined(options.deep) || options.deep
300
+ params = params.concat(", recursive: true")
301
+ if path {
302
+ if path.slice(0,1) == "/"
303
+ path = path.slice(1) // remove initial slash
304
+ if path.slice(-1) == "/"
305
+ path = path.slice(0,-1) // remove terminal slash
306
+ if path != ""
307
+ params = params.concat(", path: ", "\\\"", path, "\\\"") }
308
+ else
309
+ path = ""
310
+ query = strcat("{ "
311
+ "\"query\": \"query { "
312
+ "project (fullPath: ", "\\\"", repodict.fullPath, "\\\"", ") { "
313
+ "repository { "
314
+ "tree (", params, ") { "
315
+ "blobs { "
316
+ "nodes { "
317
+ "path "
318
+ "mode "
319
+ "sha "
320
+ "} "
321
+ "pageInfo { "
322
+ "hasNextPage "
323
+ "endCursor "
324
+ "} "
325
+ "} "
326
+ "} "
327
+ "} "
328
+ "} "
329
+ "}\" "
330
+ "}")
331
+ `(error, response) = await(js.w.fetch(
332
+ url, {
333
+ method: "post"
334
+ body: query
335
+ headers: {
336
+ "Content-Type": "application/json",
337
+ "Content-Length": query.length
338
+ "Authorization": "bearer ".concat(access.userPat)
339
+ } }))
340
+ if !error
341
+ `(error, result) = await(response.json())
342
+ if error
343
+ list(Error("GitLab gql fetch failed:", error))
344
+ else if result.error
345
+ list(Error("GitLab query error:", result.error))
346
+ else if !result.data
347
+ list(Error("GitLab empty result"))
348
+ else {
349
+ let (blobs, item, tree, dircache, patharray, parent, name) {
350
+ blobs = result.data.project.repository.tree.blobs
351
+ if blobs.pageInfo.hasNextPage
352
+ debuglog("GitLab repo blobs truncated by paging")
353
+ tree = {
354
+ name: path.split("/").pop()
355
+ data: {
356
+ platform: "GitLab"
357
+ semantics: "git"
358
+ pathsep: "/" }
359
+ parents: []
360
+ children: []
361
+ }
362
+ if path != ""
363
+ tree.parents = new(path.split("/"))
364
+
365
+ // findir
366
+ // Given an array of directory path elements, return the directory dictionary
367
+ dircache = { } // pathnames to dir dict
368
+ function findir(patharray, local dir, dirname) {
369
+ if patharray.length == 0
370
+ tree
371
+ else {
372
+ dirname = patharray.join("/")
373
+ dir = dircache[dirname]
374
+ if !dir {
375
+ parent = findir(patharray.slice(0,-1)) // all-but-last element
376
+ dir = {
377
+ name: patharray.slice(-1).0
378
+ children: [] }
379
+ parent.children.push(dir)
380
+ dircache[dirname] = dir
381
+ }
382
+ dir }
383
+ }
384
+
385
+ // record files in tree
386
+ for item in blobs.nodes {
387
+ patharray = item.path.split("/").slice(tree.parents.length)
388
+ name = patharray.slice(-1).0 // last path element
389
+ parent = findir(patharray.slice(0,-1)) // all-but-last element
390
+ parent.children.push({
391
+ name: name
392
+ mode: item.mode
393
+ hash: item.sha
394
+ })
395
+ }
396
+ tree
397
+ }()
398
+ }
399
+ }
400
+
401
+ // getblob
402
+ //
403
+ // Retrieve a blob using the specified query and method.
404
+ //
405
+ closure getblob(query, method) {
406
+ `(error, response) = await(js.w.fetch(
407
+ query, {
408
+ method: method
409
+ headers: {
410
+ "Authorization": "bearer ".concat(access.userPat)
411
+ } }))
412
+ if !error {
413
+ if method == "head" {
414
+ if response.status != 200
415
+ result = { message: response.status }
416
+ else
417
+ result = {
418
+ name: response.headers.get("x-gitlab-file-name")
419
+ path: response.headers.get("x-gitlab-file-path")
420
+ blobID: response.headers.get("x-gitlab-blob-id")
421
+ commitID: response.headers.get("x-gitlab-commit-id")
422
+ lastCommitID: response.headers.get("x-gitlab-last-commit-id")
423
+ sha256: response.headers.get("x-gitlab-content-sha256")
424
+ size: response.headers.get("x-gitlab-size")
425
+ encoding: response.headers.get("x-gitlab-encoding")
426
+ ref: response.headers.get("x-gitlab-ref")
427
+ }
428
+ }
429
+ else
430
+ `(error, result) = await(response.json())
431
+ }
432
+ if error
433
+ list(Error("GitLab: get/head failed:", error))
434
+ else if response.status != 200
435
+ list(Error("GitLab: cannot retrieve file:", result.message))
436
+ else if method == "head"
437
+ list(false, result)
438
+ else if !result
439
+ list(Error("GitLab: empty result"))
440
+ else {
441
+ if result.encoding == "base64"
442
+ result.content = atob(result.content)
443
+ list(false, {
444
+ name: result.file_name
445
+ path: result.file_path
446
+ blobID: result.blob_id
447
+ commitID: result.commit_id
448
+ lastCommitID: result.last_commit_id
449
+ sha256: result.content_sha256
450
+ size: result.size
451
+ encoding: result.encoding
452
+ ref: result.ref
453
+ content: result.content
454
+ })
455
+ }
456
+ }
457
+
458
+ // readfile
459
+ //
460
+ // Retrieve a named file within a commit. The filepath must be the path of the file within the
461
+ // repo. Available options include:
462
+ // {
463
+ // ref: <commit> - branch, tag or commit hash, default "HEAD"
464
+ // head: <boolean> - true to obtain metadata only without contents
465
+ // }
466
+ //
467
+ gepo.readfile = closure readfile(filepath, options, local ref, params, query, method, error, response, result) {
468
+ if !string(filepath)
469
+ return (list(Error("filepath must be a string:", filepath)))
470
+ ref = options.ref
471
+ if !string(ref)
472
+ ref = "HEAD"
473
+ params = EncodeQuery("?", { ref: ref })
474
+ query = urlrest.concat("projects/", repodict.id, "/repository/blobs/", encodeURIComponent(filepath), params)
475
+ if options.head
476
+ method = "head"
477
+ else
478
+ method = "get"
479
+ getblob(query, method)
480
+ }
481
+
482
+ // showfile
483
+ //
484
+ // Retrieve just the content of a named file within a commit. This is just like readfile except
485
+ // that it just gets the content.
486
+ //
487
+ gepo.showfile = closure showfile(filepath, options, local error, result) {
488
+ `(error, result) = readfile(filepath, options)
489
+ list(error, result.content)
490
+ }
491
+
492
+ // showblob
493
+ //
494
+ // Retrieve a blob by hash, with no metadata--just content.
495
+ //
496
+ gepo.showblob = closure showblob(hash, local query, error, result) {
497
+ if !string(hash)
498
+ return (list(Error("file hash must be a string:", hash)))
499
+ query = urlrest.concat("projects/", repodict.id, "/repository/blobs/", hash)
500
+ `(error, result) = getblob(query, "get")
501
+ list(error, result.content)
502
+ }
503
+
504
+ // finis
505
+
506
+ list(false, gepo)
507
+ };
508
+
509
+
510
+ /*
511
+ * gtopInit
512
+ *
513
+ * Initialize the gitops module.
514
+ *
515
+ */
516
+
517
+ function gtopInit(local manifest) {
518
+
519
+ manifest = `(GitLabOps, GitLabRepo, gtopInit)
520
+
521
+ Naan.module.build(module.id, "gitops", function(modobj, compobj) {
522
+ require("./serviceGitLab.nlg")
523
+ compobj.manifest = manifest
524
+ modobj.exports.GitLabOps = GitLabOps
525
+ modobj.exports.GitLabRepo = GitLabRepo
526
+ })
527
+
528
+ }();