@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,522 @@
1
+ /*
2
+ * gitops.nlg
3
+ * serviceGitHub
4
+ *
5
+ * GitHub 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
+ * GitHubOps
16
+ *
17
+ * An object to perform GitHub operations using GraphQL.
18
+ *
19
+
20
+ Play-lng> rr = App.nide.locate.connect("d1f7b1ef-8f78-46de-a53f-529053ef4c4b", "Git").1;
21
+ $: Object{2}
22
+ Play-lng> rr.*;
23
+ $: ("userid", "repolist")
24
+ Play-lng> rr.userid();
25
+ $: (false, {
26
+ data: {
27
+ viewer : { login: "rczulch" } } })
28
+ Play-lng> rr.repolist();
29
+ $: (false, [
30
+ { name: "DAStool", id: "MDEwOlJlcG9zaXRvcnkyMDU1ODA5MTY=" },
31
+ { name: "DDPinternal", id: "MDEwOlJlcG9zaXRvcnkyMDU1ODYyNTU=" },
32
+ { name: "Naan", id: "MDEwOlJlcG9zaXRvcnkyMDU1OTc2MDA=" },
33
+ { name: "aws-learning", id: "MDEwOlJlcG9zaXRvcnkyMTcxNzI4NzQ=" },
34
+ { name: "Naanlang", id: "MDEwOlJlcG9zaXRvcnkzMTA3MzcwNTM=" },
35
+ { name: "lightning-fs", id: "MDEwOlJlcG9zaXRvcnkzMjkxOTI4MTg=" },
36
+ { name: "isomorphic-git", id: "MDEwOlJlcG9zaXRvcnkzMjkyMDYwNzk=" }])
37
+
38
+ *
39
+ */
40
+
41
+ closure GitHubOps(access, local gops, url) {
42
+ gops = new(object, this)
43
+ url = "https://api.github.com/graphql"
44
+ urlrest = "https://api.github.com/"
45
+
46
+ // userid
47
+ //
48
+ // Return the userid string for the provided PAT.
49
+ //
50
+ gops.userid = function userid(local query, response, result) {
51
+ query = "{
52
+ \"query\": \"query { viewer { login }}\"
53
+ }"
54
+ `(error, response) = await(js.w.fetch(
55
+ url, {
56
+ method: "post"
57
+ body: query
58
+ headers: {
59
+ "Content-Type": "application/json",
60
+ "Content-Length": query.length
61
+ "Authorization": "bearer ".concat(access.userPat)
62
+ } }))
63
+ if !error
64
+ `(error, result) = await(response.json())
65
+ if error
66
+ list(Error("GitHub gql fetch failed:", error))
67
+ else if result.error
68
+ list(Error("GitHub query error:", result.error))
69
+ else if !result.data
70
+ list(Error("GitHub empty result"))
71
+ else
72
+ list(false, result.data.viewer.login)
73
+ }
74
+
75
+ // repolist
76
+ //
77
+ // Return an array of available repositories with Node IDs.
78
+ //
79
+ gops.repolist = function repolist(local query, response, result) {
80
+ query = "{
81
+ \"query\": \"query { viewer { repositories (first:50) { nodes { name, id, nameWithOwner } } } }\"
82
+ }"
83
+ `(error, response) = await(js.w.fetch(
84
+ url, {
85
+ method: "post"
86
+ body: query
87
+ headers: {
88
+ "Content-Type": "application/json",
89
+ "Content-Length": query.length
90
+ "Authorization": "bearer ".concat(access.userPat)
91
+ } }))
92
+ if !error
93
+ `(error, result) = await(response.json())
94
+ if error
95
+ list(Error("GitHub gql fetch failed:", error))
96
+ else if result.error
97
+ list(Error("GitHub query error:", result.error))
98
+ else if !result.data
99
+ list(Error("GitHub empty result"))
100
+ else
101
+ list(false, new(result.data.viewer.repositories.nodes))
102
+ }
103
+
104
+ // repomake
105
+ //
106
+ // Make an empty project (and repo) with the specified name, returning a standard tuple of the
107
+ // `(error, result) form. On success the result is the repodict for the new repo.
108
+ //
109
+ gops.repomake = function repomake(name, local response, result) {
110
+ `(error, response) = await(js.w.fetch(
111
+ urlrest.concat("user/repos"), {
112
+ method: "post"
113
+ body: JSON.stringify({ name: name, private: true })
114
+ headers: {
115
+ "Accept": "application/vnd.github.v3+json",
116
+ "Authorization": "bearer ".concat(access.userPat)
117
+ } }))
118
+ if !error
119
+ `(error, result) = await(response.json())
120
+ if error
121
+ list(Error("GitHub post fetch failed:", error))
122
+ else if response.status != 201
123
+ list(Error("GitHub: cannot create repo:", name, new(result), { status: response.status }))
124
+ else
125
+ list(false, {
126
+ name: result.name
127
+ id: result.id
128
+ nameWithOwner: result.full_name
129
+ })
130
+ }
131
+
132
+ // repo
133
+ //
134
+ // Return a repo access object for the specified fullPath.
135
+ //
136
+ gops.repo = function repo(repodict) {
137
+ GitHubRepo(access, repodict)
138
+ }
139
+
140
+ // finis
141
+
142
+ list(false, gops)
143
+ };
144
+
145
+
146
+ /*
147
+ * GitHubRepo
148
+ *
149
+ * An object to perform GitHub repo operations using the REST and GraphQL APIs.
150
+
151
+ rr = App.nide.locate.connect("d1f7b1ef-8f78-46de-a53f-529053ef4c4b", "Git").1;
152
+ glr=rr.repo(rr.repolist().1.0).1;
153
+ glr.commits();
154
+ glr.branches();
155
+ glr.tags();
156
+
157
+ *
158
+ *
159
+ */
160
+
161
+ closure GitHubRepo(access, repodict, local gepo, url) {
162
+ gepo = new(object, this)
163
+ url = "https://api.github.com/graphql"
164
+ urlrest = "https://api.github.com/"
165
+
166
+ // restPagedGet
167
+ //
168
+ // Accumulate an array of results from the specified URL using pagination.
169
+ //
170
+ closure restPagedGet(query, mapper, local accum, error, response, result, paging) {
171
+ accum = []
172
+ loop {
173
+ `(error, response) = await(js.w.fetch(
174
+ query, {
175
+ method: "get"
176
+ headers: {
177
+ "Accept": "application/vnd.github.v3+json",
178
+ "Authorization": "bearer ".concat(access.userPat)
179
+ } }))
180
+ if !error
181
+ `(error, result) = await(response.json())
182
+ if error
183
+ list(Error("GitHub get fetch failed:", error))
184
+ else if !result
185
+ list(Error("GitHub empty result"))
186
+ else {
187
+ accum = accum.concat(new(result.map(mapper)))
188
+ paging = gtopParseLinkHeader(response.headers.get("Link"))
189
+ if paging.next {
190
+ query = paging.next.url
191
+ continue } // do more pages
192
+ list(false, accum)
193
+ }
194
+ break
195
+ }
196
+ }
197
+
198
+ // branchesAndTags
199
+ //
200
+ // Return a list of repository branches, with an optional search string.
201
+ //
202
+ closure branchesAndTags(endpoint, pardict, local params, query) {
203
+ if !pardict
204
+ pardict = {}
205
+ pardict.per_page = 100
206
+ params = EncodeQuery("?", pardict)
207
+ query = urlrest.concat("repos/", repodict.nameWithOwner, "/", endpoint, params)
208
+ restPagedGet(query, function(item) {
209
+ {
210
+ name: item.name
211
+ commit: {
212
+ hash: item.commit.sha
213
+ }
214
+ }
215
+ })
216
+ }
217
+
218
+ // info
219
+ //
220
+ // Report info about the repository.
221
+ //
222
+ gepo.info = closure info() {
223
+
224
+ }
225
+
226
+ // branches
227
+ //
228
+ // Return a list of repository branches, with an optional search string.
229
+ //
230
+ gepo.branches = closure branches(search) {
231
+ branchesAndTags("branches", {})
232
+ }
233
+
234
+ // branches
235
+ //
236
+ // Return a list of repository branches, with an optional search string.
237
+ //
238
+ gepo.tags = closure tags(search) {
239
+ branchesAndTags("tags", {})
240
+ }
241
+
242
+ // commits
243
+ //
244
+ // Return a list of commits in the repo, optionally matching the specified file path.
245
+ //
246
+ //
247
+ gepo.commits = closure commits(filepath, local pardict, query, error, response, result) {
248
+ pardict = {
249
+ per_page: 100
250
+ }
251
+ if filepath
252
+ pardict.path = filepath
253
+ query = urlrest.concat("repos/", repodict.nameWithOwner, "/commits", EncodeQuery("?", pardict))
254
+ restPagedGet(query, function(item, local commit, common) {
255
+ commit = item.commit
256
+ common = {
257
+ hash: item.sha
258
+ author: commit.author.name
259
+ email: commit.author.email
260
+ date: commit.author.date
261
+ committer_name: commit.committer.name
262
+ committer_email: commit.committer.email
263
+ committer_date: commit.committer.date
264
+ message: commit.message
265
+ }
266
+ if item.parents.length > 0
267
+ common.parents = item.parents.map(function(parent) {
268
+ parent.sha
269
+ })
270
+ common
271
+ })
272
+ }
273
+
274
+ // tree
275
+ //
276
+ // Retrieve a commit tree, with similar structure to filesystem trees. Options include:
277
+ // {
278
+ // path: <relpath> - relative path below repository to start
279
+ // deep: <boolean> - whether to include recursive children
280
+ // ref: <commit> - branch, tag or commit hash, default "HEAD"
281
+ // }
282
+ //
283
+ // The GitHub API for trees offers size and sha, so we're storing those for now.
284
+ //
285
+ gepo.tree = closure tree(options, local path, ref, deep, params, query, error, response, result) {
286
+ path = options.path
287
+ ref = options.ref
288
+ if !ref
289
+ ref = "HEAD"
290
+ if !defined(options.deep) || options.deep
291
+ deep = true
292
+ if path {
293
+ if path.slice(0,1) == "/"
294
+ path = path.slice(1) // remove initial slash
295
+ if path.slice(-1) == "/"
296
+ path = path.slice(0,-1) // remove terminal slash
297
+ if path != ""
298
+ params = params.concat(", path: ", "\\\"", path, "\\\"") }
299
+ else
300
+ path = ""
301
+ if path.length > 0 || deep
302
+ params = EncodeQuery("?", { recursive: true }) // need recursive
303
+ else
304
+ params = ""
305
+ query = urlrest.concat("repos/", repodict.nameWithOwner, "/git/trees/", ref, params)
306
+ `(error, response) = await(js.w.fetch(
307
+ query, {
308
+ method: "get"
309
+ headers: {
310
+ "Accept": "application/vnd.github.v3+json",
311
+ "Authorization": "bearer ".concat(access.userPat)
312
+ } }))
313
+ if !error
314
+ `(error, result) = await(response.json())
315
+ if error
316
+ list(Error("GitHub get fetch failed:", error))
317
+ else if response.status != 200
318
+ list(Error("GitHub: cannot retrieve file:", result.message, { status: response.status }))
319
+ else if !result
320
+ list(Error("GitHub empty result"))
321
+ else {
322
+ let (item, tree, dircache, patharray, parent, name) {
323
+ if result.truncated
324
+ debuglog("GitHub repo blobs truncated by paging")
325
+ tree = {
326
+ name: path.split("/").pop()
327
+ data: {
328
+ platform: "GitHub"
329
+ semantics: "git"
330
+ pathsep: "/" }
331
+ parents: []
332
+ children: []
333
+ }
334
+ if path != ""
335
+ tree.parents = new(path.split("/"))
336
+
337
+ // findir
338
+ // Given an array of directory path elements, return the directory dictionary
339
+ dircache = { } // pathnames to dir dict
340
+ function findir(patharray, local dir, dirname) {
341
+ if patharray.length == 0
342
+ tree
343
+ else {
344
+ dirname = patharray.join("/")
345
+ dir = dircache[dirname]
346
+ if !dir {
347
+ parent = findir(patharray.slice(0,-1)) // all-but-last element
348
+ dir = {
349
+ name: patharray.slice(-1).0
350
+ children: [] }
351
+ parent.children.push(dir)
352
+ dircache[dirname] = dir
353
+ }
354
+ dir }
355
+ }
356
+
357
+ // record files in tree
358
+ for item in result.tree {
359
+ if item.type == "tree"
360
+ continue
361
+ if !item.path.startsWith(path)
362
+ continue // filter by specified path
363
+ if !deep && item.path.indexOf("/") >= 0
364
+ continue // only one level
365
+ patharray = item.path.split("/").slice(tree.parents.length)
366
+ name = patharray.slice(-1).0 // last path element
367
+ parent = findir(patharray.slice(0,-1)) // all-but-last element
368
+ parent.children.push({
369
+ name: name
370
+ mode: item.mode
371
+ size: item.size
372
+ hash: item.sha
373
+ })
374
+ }
375
+ tree
376
+ }()
377
+ }
378
+ }
379
+
380
+ // getblob
381
+ //
382
+ // Retrieve a blob using the specified query.
383
+ //
384
+ closure getblob(query) {
385
+ `(error, response) = await(js.w.fetch(
386
+ query, {
387
+ method: "get"
388
+ headers: {
389
+ "Accept": "application/vnd.github.v3+json",
390
+ "Authorization": "bearer ".concat(access.userPat)
391
+ } }))
392
+ if !error
393
+ `(error, result) = await(response.json())
394
+ if error
395
+ list(Error("GitHub: get failed:", error))
396
+ else if response.status != 200
397
+ list(Error("GitHub: cannot retrieve blob:", result.message, { status: response.status }))
398
+ else if !result
399
+ list(Error("GitHub: empty result"))
400
+ else {
401
+ if result.encoding == "base64"
402
+ result.content = atob(result.content)
403
+ list(false, {
404
+ name: result.name
405
+ path: result.path
406
+ hash: result.sha
407
+ size: result.size
408
+ type: result.type
409
+ encoding: result.encoding
410
+ content: result.content
411
+ })
412
+ }
413
+ }
414
+
415
+ // readfile
416
+ //
417
+ // Retrieve a named file within a commit. The filepath must be the path of the file within the
418
+ // repo. Available options include:
419
+ // {
420
+ // ref: <commit> - branch, tag or commit hash, default to main branch
421
+ // }
422
+ //
423
+ gepo.readfile = closure readfile(filepath, options, local ref, params, query, method, error, response, result) {
424
+ if !string(filepath)
425
+ return (list(Error("filepath must be a string:", filepath)))
426
+ ref = options.ref
427
+ if string(ref)
428
+ params = EncodeQuery("?", { ref: ref })
429
+ else
430
+ params = ""
431
+ query = urlrest.concat("repos/", repodict.nameWithOwner, "/contents/", encodeURIComponent(filepath), params)
432
+ getblob(query)
433
+ }
434
+
435
+ // showfile
436
+ //
437
+ // Retrieve just the content of a named file within a commit. This is just like readfile except
438
+ // that it just gets the content.
439
+ //
440
+ gepo.showfile = closure showfile(filepath, options, local error, result) {
441
+ `(error, result) = readfile(filepath, options)
442
+ list(error, result.content)
443
+ }
444
+
445
+ // showblob
446
+ //
447
+ // Retrieve a blob by hash, with no metadata--just content.
448
+ //
449
+ gepo.showblob = closure showblob(hash, local query, error, result) {
450
+ if !string(hash)
451
+ return (list(Error("file hash must be a string:", hash)))
452
+ query = urlrest.concat("repos/", repodict.nameWithOwner, "/git/blobs/", hash)
453
+ `(error, result) = getblob(query)
454
+ list(error, result.content)
455
+ }
456
+
457
+ // finis
458
+
459
+ list(false, gepo)
460
+
461
+ };
462
+
463
+
464
+ /*
465
+ * gtopParseLinkHeader
466
+ *
467
+ * Parse link header response from REST API, which provides information on pagination. Example
468
+ * Link header is as follows (newlines added):
469
+ * <https://api.github.com/repositories/205580916/tags?per_page=2&page=1>; rel="prev",
470
+ * <https://api.github.com/repositories/205580916/tags?per_page=2&page=3>; rel="next",
471
+ * <https://api.github.com/repositories/205580916/tags?per_page=2&page=3>; rel="last",
472
+ * <https://api.github.com/repositories/205580916/tags?per_page=2&page=1>; rel="first"
473
+ * for which it will output a dictionary:
474
+ * {
475
+ * prev : {
476
+ * url : "https://api.github.com/repositories/205580916/tags?per_page=2&page=1",
477
+ * page : 1 },
478
+ * next : {
479
+ * url : "https://api.github.com/repositories/205580916/tags?per_page=2&page=3",
480
+ * page : 3 },
481
+ * last : {
482
+ * url : "https://api.github.com/repositories/205580916/tags?per_page=2&page=3",
483
+ * page : 3 },
484
+ * first: {
485
+ * url : "https://api.github.com/repositories/205580916/tags?per_page=2&page=1",
486
+ * page : 1 } }
487
+ *
488
+ */
489
+
490
+ gtopParseLinkHeaderRegExp;
491
+
492
+ function gtopParseLinkHeader(header, local segment, output) {
493
+ if !jsInstanceOf(gtopParseLinkHeaderRegExp, RegExp.prototype)
494
+ gtopParseLinkHeaderRegExp = RegExp('<([^?]+\\?[=\\w&?]+page=(\\d+))>;\\s*rel="(\\w+)"', 'g')
495
+ output = { }
496
+ while result = gtopParseLinkHeaderRegExp.exec(header)
497
+ output[result.3] = {
498
+ url: result.1
499
+ page: toint(result.2)
500
+ }
501
+ output
502
+ };
503
+
504
+
505
+ /*
506
+ * gtopInit
507
+ *
508
+ * Initialize the gitops module.
509
+ *
510
+ */
511
+
512
+ function gtopInit(local manifest) {
513
+
514
+ manifest = `(GitHubOps, GitHubRepo, gtopParseLinkHeader, gtopInit)
515
+
516
+ Naan.module.build(module.id, "gitops", function(modobj, compobj) {
517
+ require("./serviceGitHub.nlg")
518
+ compobj.manifest = manifest
519
+ modobj.exports.GitHubOps = GitHubOps
520
+ })
521
+
522
+ }();