@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.
- package/LICENSE.md +21 -0
- package/README.md +46 -0
- package/dist/env_web.js +431 -0
- package/dist/naan.min.js +73 -0
- package/frameworks/browser/browser.nlg +30 -0
- package/frameworks/browser/pouchdb/pouchdb.min.js +7 -0
- package/frameworks/browser/spark-md5/spark-md5.min.js +1 -0
- package/frameworks/browser/sworker.js +192 -0
- package/frameworks/browser/terminals.nlg +787 -0
- package/frameworks/browser/workers.nlg +386 -0
- package/frameworks/client/apiclient.nlg +183 -0
- package/frameworks/client/client.nlg +29 -0
- package/frameworks/client/psm_client.nlg +572 -0
- package/frameworks/common/common.nlg +464 -0
- package/frameworks/common/preferences.nlg +131 -0
- package/frameworks/common/repltools.nlg +100 -0
- package/frameworks/common/watching.nlg +97 -0
- package/frameworks/node/apiserver.nlg +399 -0
- package/frameworks/node/filesystem.nlg +1012 -0
- package/frameworks/node/gitter.nlg +234 -0
- package/frameworks/node/node.nlg +81 -0
- package/frameworks/node/psm_server.nlg +465 -0
- package/frameworks/node/worker.nlg +560 -0
- package/frameworks/project/build.nlg +1229 -0
- package/frameworks/project/jszip.js +30 -0
- package/frameworks/project/jszip.nlg +87 -0
- package/frameworks/project/proj_cliser.nlg +139 -0
- package/frameworks/project/proj_console.nlg +137 -0
- package/frameworks/project/proj_folder.nlg +143 -0
- package/frameworks/project/proj_lambda.nlg +137 -0
- package/frameworks/project/proj_static.nlg +138 -0
- package/frameworks/project/project.nlg +29 -0
- package/frameworks/project/projects.nlg +587 -0
- package/frameworks/project/uglifyjs.js +1 -0
- package/frameworks/project/uglifyjs.nlg +79 -0
- package/frameworks/running/debugcom.nlg +163 -0
- package/frameworks/running/debugnub.nlg +565 -0
- package/frameworks/running/debugutil.nlg +510 -0
- package/frameworks/running/executors.nlg +767 -0
- package/frameworks/running/running.nlg +151 -0
- package/frameworks/running/sourcecode.nlg +346 -0
- package/frameworks/running/taskexec.nlg +196 -0
- package/frameworks/storage/dbt_pouch.nlg +773 -0
- package/frameworks/storage/file_manager.nlg +772 -0
- package/frameworks/storage/psm.nlg +326 -0
- package/frameworks/storage/psm_dbtables.nlg +814 -0
- package/frameworks/storage/resources.nlg +445 -0
- package/frameworks/storage/storage.nlg +52 -0
- package/lib/browser/env_web.js +431 -0
- package/lib/browser/env_webworker.js +146 -0
- package/lib/browser/require.js +1653 -0
- package/lib/core/naanlib.js +73 -0
- package/lib/env_node.js +282 -0
- package/lib/env_nodeworker.js +165 -0
- package/lib/node_repl.js +25 -0
- package/lib/node_repl_init.nlg +52 -0
- package/package.json +13 -0
- package/plugins/gitClient/clientops.nlg +317 -0
- package/plugins/gitClient/gitClient.nlg +63 -0
- package/plugins/gitClient/gitutils.nlg +1331 -0
- package/plugins/gitClient/minimatch.js +945 -0
- package/plugins/gitClient/minimatch_license.txt +15 -0
- package/plugins/gitClient/minimatch_readme.md +208 -0
- package/plugins/nodeLib/nodeLib.nlg +26 -0
- package/plugins/nodeLib/node_cp.nlg +65 -0
- package/plugins/nodeLib/node_fs.nlg +137 -0
- package/plugins/nodeLib/node_https.nlg +172 -0
- package/plugins/nodeLib/node_util.nlg +180 -0
- package/plugins/serviceAws/aws/aws-sdk.min.js +88 -0
- package/plugins/serviceAws/aws/lambda_rest_index.js +122 -0
- package/plugins/serviceAws/aws/lambda_rest_init.nlg +58 -0
- package/plugins/serviceAws/aws/lambda_ws_index.js +498 -0
- package/plugins/serviceAws/aws/lambda_ws_init.nlg +49 -0
- package/plugins/serviceAws/aws_cloudwatchlogs.nlg +122 -0
- package/plugins/serviceAws/aws_cognito.nlg +76 -0
- package/plugins/serviceAws/aws_dynamo.nlg +509 -0
- package/plugins/serviceAws/aws_lambda.nlg +95 -0
- package/plugins/serviceAws/aws_s3.nlg +134 -0
- package/plugins/serviceAws/aws_utils.nlg +86 -0
- package/plugins/serviceAws/dbt_aws.nlg +769 -0
- package/plugins/serviceAws/lambda_naan_control.nlg +175 -0
- package/plugins/serviceAws/psm_aws.nlg +258 -0
- package/plugins/serviceAws/serviceAws.nlg +38 -0
- package/plugins/serviceGitHub/gitops.nlg +522 -0
- package/plugins/serviceGitHub/psm_github.nlg +205 -0
- package/plugins/serviceGitHub/serviceGitHub.nlg +65 -0
- package/plugins/serviceGitLab/gitops.nlg +528 -0
- package/plugins/serviceGitLab/psm_gitlab.nlg +205 -0
- package/plugins/serviceGitLab/serviceGitLab.nlg +65 -0
- package/test/harness.nlg +312 -0
- package/test/node_test.js +33 -0
- package/test/test_01_core.nlg +768 -0
- package/test/test_02_context.nlg +269 -0
- package/test/test_03_jsinterop.nlg +137 -0
- package/test/test_04_numerics.nlg +450 -0
- package/test/test_05_strings.nlg +63 -0
- package/test/test_06_lingoparse.nlg +500 -0
- 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
|
+
}();
|