@openneuro/server 4.20.5 → 4.20.6-alpha.3

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 (185) hide show
  1. package/package.json +4 -6
  2. package/src/__mocks__/{config.js → config.ts} +5 -5
  3. package/src/app.ts +32 -31
  4. package/src/cache/item.ts +6 -7
  5. package/src/cache/types.ts +8 -8
  6. package/src/{config.js → config.ts} +6 -6
  7. package/src/datalad/__tests__/changelog.spec.ts +83 -0
  8. package/src/datalad/__tests__/dataset.spec.ts +109 -0
  9. package/src/datalad/__tests__/description.spec.ts +141 -0
  10. package/src/datalad/__tests__/files.spec.ts +77 -0
  11. package/src/datalad/__tests__/pagination.spec.ts +136 -0
  12. package/src/datalad/__tests__/{snapshots.spec.js → snapshots.spec.ts} +17 -17
  13. package/src/datalad/{analytics.js → analytics.ts} +4 -4
  14. package/src/datalad/{changelog.js → changelog.ts} +17 -14
  15. package/src/datalad/{dataset.js → dataset.ts} +95 -93
  16. package/src/datalad/{description.js → description.ts} +37 -37
  17. package/src/datalad/draft.ts +38 -0
  18. package/src/datalad/files.ts +26 -20
  19. package/src/datalad/{pagination.js → pagination.ts} +47 -47
  20. package/src/datalad/{readme.js → readme.ts} +13 -11
  21. package/src/datalad/{reexporter.js → reexporter.ts} +4 -4
  22. package/src/datalad/{snapshots.js → snapshots.ts} +56 -62
  23. package/src/datalad/{upload.js → upload.ts} +7 -5
  24. package/src/elasticsearch/elastic-client.ts +11 -0
  25. package/src/elasticsearch/reindex-dataset.ts +7 -7
  26. package/src/graphql/__tests__/__snapshots__/permissions.spec.ts.snap +5 -0
  27. package/src/graphql/__tests__/{comment.spec.js → comment.spec.ts} +17 -17
  28. package/src/graphql/__tests__/permissions.spec.ts +113 -0
  29. package/src/graphql/{permissions.js → permissions.ts} +14 -14
  30. package/src/graphql/resolvers/__tests__/brainlife.spec.ts +11 -11
  31. package/src/graphql/resolvers/__tests__/{dataset-search.spec.js → dataset-search.spec.ts} +25 -23
  32. package/src/graphql/resolvers/__tests__/dataset.spec.ts +175 -0
  33. package/src/graphql/resolvers/__tests__/derivatives.spec.ts +19 -19
  34. package/src/graphql/resolvers/__tests__/importRemoteDataset.spec.ts +20 -20
  35. package/src/graphql/resolvers/__tests__/permssions.spec.ts +35 -0
  36. package/src/graphql/resolvers/__tests__/snapshots.spec.ts +59 -0
  37. package/src/graphql/resolvers/__tests__/user.spec.ts +18 -0
  38. package/src/graphql/resolvers/brainlife.ts +4 -4
  39. package/src/graphql/resolvers/cache.ts +4 -4
  40. package/src/graphql/resolvers/{comment.js → comment.ts} +16 -16
  41. package/src/graphql/resolvers/{dataset-search.js → dataset-search.ts} +45 -43
  42. package/src/graphql/resolvers/{dataset.js → dataset.ts} +38 -52
  43. package/src/graphql/resolvers/datasetType.ts +3 -3
  44. package/src/graphql/resolvers/derivatives.ts +11 -11
  45. package/src/graphql/resolvers/description.ts +18 -0
  46. package/src/graphql/resolvers/{draft.js → draft.ts} +13 -13
  47. package/src/graphql/resolvers/{flaggedFiles.js → flaggedFiles.ts} +4 -4
  48. package/src/graphql/resolvers/{follow.js → follow.ts} +1 -1
  49. package/src/graphql/resolvers/git.ts +3 -3
  50. package/src/graphql/resolvers/history.ts +13 -0
  51. package/src/graphql/resolvers/importRemoteDataset.ts +12 -11
  52. package/src/graphql/resolvers/index.ts +25 -0
  53. package/src/graphql/resolvers/{issues.js → issues.ts} +9 -9
  54. package/src/graphql/resolvers/metadata.ts +8 -8
  55. package/src/graphql/resolvers/{mutation.js → mutation.ts} +26 -26
  56. package/src/graphql/resolvers/{newsletter.js → newsletter.ts} +2 -2
  57. package/src/graphql/resolvers/permissions.ts +15 -21
  58. package/src/graphql/resolvers/publish.ts +17 -0
  59. package/src/graphql/resolvers/query.ts +21 -0
  60. package/src/graphql/resolvers/{readme.js → readme.ts} +3 -3
  61. package/src/graphql/resolvers/{reexporter.js → reexporter.ts} +2 -2
  62. package/src/graphql/resolvers/relation.ts +5 -5
  63. package/src/graphql/resolvers/{reset.js → reset.ts} +2 -2
  64. package/src/graphql/resolvers/reviewer.ts +4 -4
  65. package/src/graphql/resolvers/{snapshots.js → snapshots.ts} +49 -49
  66. package/src/graphql/resolvers/{stars.js → stars.ts} +1 -1
  67. package/src/graphql/resolvers/summary.ts +3 -3
  68. package/src/graphql/resolvers/{upload.js → upload.ts} +5 -5
  69. package/src/graphql/resolvers/{user.js → user.ts} +16 -18
  70. package/src/graphql/resolvers/{validation.js → validation.ts} +12 -14
  71. package/src/graphql/{schema.js → schema.ts} +4 -6
  72. package/src/graphql/utils/{file.js → file.ts} +2 -2
  73. package/src/handlers/{comments.js → comments.ts} +11 -11
  74. package/src/handlers/{config.js → config.ts} +1 -1
  75. package/src/handlers/{datalad.js → datalad.ts} +22 -22
  76. package/src/handlers/{doi.js → doi.ts} +6 -6
  77. package/src/handlers/reviewer.ts +6 -6
  78. package/src/handlers/{sitemap.js → sitemap.ts} +19 -19
  79. package/src/handlers/stars.ts +11 -10
  80. package/src/handlers/{subscriptions.js → subscriptions.ts} +17 -16
  81. package/src/handlers/{users.js → users.ts} +3 -3
  82. package/src/libs/__tests__/apikey.spec.ts +25 -0
  83. package/src/libs/__tests__/datalad-service.spec.ts +27 -0
  84. package/src/libs/__tests__/{dataset.spec.js → dataset.spec.ts} +9 -9
  85. package/src/libs/{apikey.js → apikey.ts} +5 -5
  86. package/src/libs/authentication/__tests__/jwt.spec.ts +59 -0
  87. package/src/libs/authentication/{crypto.js → crypto.ts} +16 -16
  88. package/src/libs/authentication/google.ts +18 -0
  89. package/src/libs/authentication/jwt.ts +40 -33
  90. package/src/libs/authentication/{orcid.js → orcid.ts} +11 -11
  91. package/src/libs/authentication/{passport.js → passport.ts} +45 -30
  92. package/src/libs/authentication/{states.js → states.ts} +17 -20
  93. package/src/libs/{counter.js → counter.ts} +1 -1
  94. package/src/libs/{datalad-service.js → datalad-service.ts} +4 -4
  95. package/src/libs/dataset.ts +9 -0
  96. package/src/libs/doi/__tests__/__snapshots__/doi.spec.ts.snap +17 -0
  97. package/src/libs/doi/__tests__/doi.spec.ts +25 -0
  98. package/src/libs/doi/__tests__/normalize.spec.ts +19 -19
  99. package/src/libs/doi/{index.js → index.ts} +27 -21
  100. package/src/libs/doi/normalize.ts +2 -2
  101. package/src/libs/email/__tests__/index.spec.ts +14 -14
  102. package/src/libs/email/index.ts +4 -4
  103. package/src/libs/email/templates/__tests__/comment-created.spec.ts +12 -12
  104. package/src/libs/email/templates/__tests__/dataset-deleted.spec.ts +6 -6
  105. package/src/libs/email/templates/__tests__/owner-unsubscribed.spec.ts +6 -6
  106. package/src/libs/email/templates/__tests__/snapshot-created.spec.ts +9 -9
  107. package/src/libs/email/templates/__tests__/snapshot-reminder.spec.ts +7 -7
  108. package/src/libs/email/templates/comment-created.ts +2 -1
  109. package/src/libs/email/templates/dataset-deleted.ts +2 -1
  110. package/src/libs/email/templates/dataset-import-failed.ts +2 -1
  111. package/src/libs/email/templates/dataset-imported.ts +2 -1
  112. package/src/libs/email/templates/owner-unsubscribed.ts +2 -1
  113. package/src/libs/email/templates/snapshot-created.ts +2 -1
  114. package/src/libs/email/templates/snapshot-reminder.ts +2 -1
  115. package/src/libs/{notifications.js → notifications.ts} +100 -113
  116. package/src/libs/{orcid.js → orcid.ts} +20 -20
  117. package/src/libs/{redis.js → redis.ts} +6 -6
  118. package/src/models/__tests__/ingestDataset.spec.ts +15 -15
  119. package/src/models/analytics.ts +2 -2
  120. package/src/models/badAnnexObject.ts +6 -6
  121. package/src/models/comment.ts +10 -10
  122. package/src/models/counter.ts +2 -2
  123. package/src/models/dataset.ts +16 -16
  124. package/src/models/deletion.ts +3 -3
  125. package/src/models/deprecatedSnapshot.ts +2 -2
  126. package/src/models/doi.ts +2 -2
  127. package/src/models/file.ts +2 -2
  128. package/src/models/ingestDataset.ts +4 -4
  129. package/src/models/issue.ts +2 -2
  130. package/src/models/key.ts +2 -2
  131. package/src/models/mailgunIdentifier.ts +2 -2
  132. package/src/models/metadata.ts +3 -3
  133. package/src/models/newsletter.ts +3 -3
  134. package/src/models/notification.ts +2 -2
  135. package/src/models/permission.ts +4 -4
  136. package/src/models/reviewer.ts +7 -7
  137. package/src/models/snapshot.ts +2 -2
  138. package/src/models/stars.ts +6 -6
  139. package/src/models/subscription.ts +2 -2
  140. package/src/models/summary.ts +2 -2
  141. package/src/models/upload.ts +3 -3
  142. package/src/models/user.ts +4 -4
  143. package/src/{routes.js → routes.ts} +62 -62
  144. package/src/server.ts +9 -9
  145. package/src/utils/__tests__/datasetOrSnapshot.spec.ts +25 -25
  146. package/src/utils/__tests__/validateUrl.spec.ts +10 -10
  147. package/src/utils/datasetOrSnapshot.ts +2 -2
  148. package/src/utils/validateUrl.ts +1 -1
  149. package/src/datalad/__tests__/changelog.spec.js +0 -82
  150. package/src/datalad/__tests__/dataset.spec.js +0 -109
  151. package/src/datalad/__tests__/description.spec.js +0 -137
  152. package/src/datalad/__tests__/files.spec.js +0 -75
  153. package/src/datalad/__tests__/pagination.spec.js +0 -136
  154. package/src/datalad/draft.js +0 -37
  155. package/src/elasticsearch/elastic-client.js +0 -11
  156. package/src/graphql/__tests__/permissions.spec.js +0 -107
  157. package/src/graphql/pubsub.js +0 -5
  158. package/src/graphql/resolvers/__tests__/dataset.spec.js +0 -175
  159. package/src/graphql/resolvers/__tests__/permssions.spec.js +0 -34
  160. package/src/graphql/resolvers/__tests__/snapshots.spec.js +0 -58
  161. package/src/graphql/resolvers/__tests__/user.spec.js +0 -17
  162. package/src/graphql/resolvers/description.js +0 -29
  163. package/src/graphql/resolvers/history.js +0 -11
  164. package/src/graphql/resolvers/index.js +0 -25
  165. package/src/graphql/resolvers/publish.js +0 -17
  166. package/src/graphql/resolvers/query.js +0 -21
  167. package/src/graphql/resolvers/subscriptions.js +0 -81
  168. package/src/graphql/utils/publish-draft-update.js +0 -13
  169. package/src/libs/__tests__/apikey.spec.js +0 -24
  170. package/src/libs/__tests__/datalad-service.spec.js +0 -26
  171. package/src/libs/authentication/__tests__/jwt.spec.js +0 -23
  172. package/src/libs/authentication/globus.js +0 -11
  173. package/src/libs/authentication/google.js +0 -19
  174. package/src/libs/bidsId.js +0 -68
  175. package/src/libs/dataset.js +0 -9
  176. package/src/libs/doi/__tests__/doi.spec.js +0 -24
  177. package/src/libs/redis-pubsub.js +0 -5
  178. package/src/libs/request.js +0 -155
  179. package/src/libs/scitran.js +0 -25
  180. package/src/libs/subscription-server.js +0 -20
  181. package/src/libs/testing-utils.js +0 -17
  182. package/src/persistent/datasets/.gitignore +0 -3
  183. package/src/persistent/temp/.gitignore +0 -3
  184. /package/src/libs/__mocks__/{notifications.js → notifications.ts} +0 -0
  185. /package/src/libs/authentication/{verifyUser.js → verifyUser.ts} +0 -0
@@ -1,28 +1,26 @@
1
- import * as datalad from '../../datalad/dataset.js'
2
- import pubsub from '../pubsub.js'
3
- import { removeDatasetSearchDocument } from '../../graphql/resolvers/dataset-search.js'
4
- import { snapshots, latestSnapshot } from './snapshots.js'
5
- import { description } from './description.js'
1
+ import * as datalad from "../../datalad/dataset"
2
+ import { removeDatasetSearchDocument } from "./dataset-search"
3
+ import { latestSnapshot, snapshots } from "./snapshots"
4
+ import { description } from "./description"
6
5
  import {
6
+ checkDatasetAdmin,
7
7
  checkDatasetRead,
8
8
  checkDatasetWrite,
9
- checkDatasetAdmin,
10
- } from '../permissions'
11
- import { user } from './user.js'
12
- import { permissions } from './permissions'
13
- import { datasetComments } from './comment.js'
14
- import { metadata } from './metadata'
15
- import { history } from './history.js'
16
- import * as dataladAnalytics from '../../datalad/analytics.js'
17
- import DatasetModel from '../../models/dataset'
18
- import Deletion from '../../models/deletion'
19
- import { reviewers } from './reviewer'
20
- import { getDatasetWorker } from '../../libs/datalad-service.js'
21
- import { getDraftHead } from '../../datalad/dataset.js'
22
- import { getFileName } from '../../datalad/files'
23
- import { onBrainlife } from './brainlife'
24
- import { derivatives } from './derivatives'
25
- import semver from 'semver'
9
+ } from "../permissions"
10
+ import { user } from "./user"
11
+ import { permissions } from "./permissions"
12
+ import { datasetComments } from "./comment"
13
+ import { metadata } from "./metadata"
14
+ import { history } from "./history"
15
+ import * as dataladAnalytics from "../../datalad/analytics"
16
+ import DatasetModel from "../../models/dataset"
17
+ import Deletion from "../../models/deletion"
18
+ import { reviewers } from "./reviewer"
19
+ import { getDatasetWorker } from "../../libs/datalad-service"
20
+ import { getFileName } from "../../datalad/files"
21
+ import { onBrainlife } from "./brainlife"
22
+ import { derivatives } from "./derivatives"
23
+ import semver from "semver"
26
24
 
27
25
  export const dataset = async (obj, { id }, { user, userInfo }) => {
28
26
  await checkDatasetRead(id, user, userInfo)
@@ -56,21 +54,21 @@ export const snapshotCreationComparison = (
56
54
  * Find the canonical name for a dataset from snapshots and drafts
57
55
  * @param {object} obj Dataset object (at least {id: "datasetId"})
58
56
  */
59
- export const datasetName = obj => {
60
- return snapshots(obj).then(results => {
57
+ export const datasetName = (obj) => {
58
+ return snapshots(obj).then((results) => {
61
59
  if (results && results.length) {
62
60
  // Return the latest snapshot name
63
61
  const sortedSnapshots = results.sort(snapshotCreationComparison)
64
62
  return description({
65
63
  id: obj.id,
66
64
  revision: sortedSnapshots[0].hexsha,
67
- }).then(desc => desc.Name)
65
+ }).then((desc) => desc.Name)
68
66
  } else if (obj.revision) {
69
67
  // Return the draft name or null
70
68
  return description({
71
69
  id: obj.id,
72
70
  revision: obj.revision,
73
- }).then(desc => desc.Name)
71
+ }).then((desc) => desc.Name)
74
72
  } else {
75
73
  return null
76
74
  }
@@ -81,9 +79,9 @@ export const datasetName = obj => {
81
79
  * Resolve the best dataset name and cache in mongodb
82
80
  * @param {string} datasetId
83
81
  */
84
- export const updateDatasetName = datasetId =>
85
- datasetName({ id: datasetId }).then(name =>
86
- DatasetModel.updateOne({ id: datasetId }, { $set: { name } }).exec(),
82
+ export const updateDatasetName = (datasetId) =>
83
+ datasetName({ id: datasetId }).then((name) =>
84
+ DatasetModel.updateOne({ id: datasetId }, { $set: { name } }).exec()
87
85
  )
88
86
 
89
87
  /**
@@ -103,11 +101,11 @@ export const createDataset = (
103
101
  })
104
102
  } else {
105
103
  throw new Error(
106
- 'New dataset must be defaced or have participant consent.',
104
+ "New dataset must be defaced or have participant consent.",
107
105
  )
108
106
  }
109
107
  } else {
110
- throw new Error('You must be logged in to create a dataset.')
108
+ throw new Error("You must be logged in to create a dataset.")
111
109
  }
112
110
  }
113
111
 
@@ -134,10 +132,6 @@ export const deleteDataset = async (
134
132
  redirect,
135
133
  user: { _id: user },
136
134
  }).save()
137
- await pubsub.publish('datasetDeleted', {
138
- datasetId: id,
139
- datasetDeleted: id,
140
- })
141
135
  return deleted
142
136
  }
143
137
 
@@ -152,14 +146,6 @@ export const deleteFiles = async (
152
146
  try {
153
147
  await checkDatasetWrite(datasetId, user, userInfo)
154
148
  const deletedFiles = await datalad.deleteFiles(datasetId, files, userInfo)
155
- pubsub.publish('filesUpdated', {
156
- datasetId,
157
- filesUpdated: {
158
- action: 'DELETE',
159
- payload: deletedFiles,
160
- },
161
- })
162
-
163
149
  return true
164
150
  } catch (err) {
165
151
  return false
@@ -223,7 +209,7 @@ export const updatePublic = (
223
209
  /**
224
210
  * Get analytics for a dataset or snapshot
225
211
  */
226
- export const analytics = async obj => {
212
+ export const analytics = async (obj) => {
227
213
  // if the dataset field exists, the request is from a snapshot, and
228
214
  // we resolve the datasetId from the dataset snapshot field of context.
229
215
  // otherwise, just use the id field because the object is a dataset
@@ -249,7 +235,7 @@ export const trackAnalytics = (obj, { datasetId, tag, type }) => {
249
235
  /**
250
236
  * Get the star count for the dataset
251
237
  */
252
- export const stars = async obj => {
238
+ export const stars = async (obj) => {
253
239
  const datasetId = obj && obj.dataset ? (await obj.dataset()).id : obj.id
254
240
  return datalad.getStars(datasetId)
255
241
  }
@@ -257,7 +243,7 @@ export const stars = async obj => {
257
243
  /**
258
244
  * Get the follower count for the dataset
259
245
  */
260
- export const followers = async obj => {
246
+ export const followers = async (obj) => {
261
247
  const datasetId = obj && obj.dataset ? (await obj.dataset()).id : obj.id
262
248
  return datalad.getFollowers(datasetId)
263
249
  }
@@ -269,7 +255,7 @@ export const followers = async obj => {
269
255
  */
270
256
  export const following = (obj, _, { user }) =>
271
257
  user
272
- ? datalad.getUserFollowed(obj.id, user).then(res => (res ? true : false))
258
+ ? datalad.getUserFollowed(obj.id, user).then((res) => (res ? true : false))
273
259
  : null
274
260
 
275
261
  /**
@@ -279,19 +265,19 @@ export const following = (obj, _, { user }) =>
279
265
  */
280
266
  export const starred = (obj, _, { user }) =>
281
267
  user
282
- ? datalad.getUserStarred(obj.id, user).then(res => (res ? true : false))
268
+ ? datalad.getUserStarred(obj.id, user).then((res) => (res ? true : false))
283
269
  : null
284
270
 
285
- const worker = obj => getDatasetWorker(obj.id)
271
+ const worker = (obj) => getDatasetWorker(obj.id)
286
272
 
287
273
  /**
288
274
  * Dataset object
289
275
  */
290
276
  const Dataset = {
291
- uploader: ds => user(ds, { id: ds.uploader }),
292
- draft: async obj => ({
277
+ uploader: (ds) => user(ds, { id: ds.uploader }),
278
+ draft: async (obj) => ({
293
279
  id: obj.id,
294
- revision: await getDraftHead(obj.id),
280
+ revision: await datalad.getDraftHead(obj.id),
295
281
  modified: obj.modified,
296
282
  }),
297
283
  snapshots,
@@ -1,6 +1,6 @@
1
- import { description } from './description.js'
1
+ import { description } from "./description.js"
2
2
 
3
- export async function datasetType(dsOrSnapshot): Promise<'schema' | 'legacy'> {
3
+ export async function datasetType(dsOrSnapshot): Promise<"schema" | "legacy"> {
4
4
  const dsDescription = await description(dsOrSnapshot)
5
- return dsDescription.DatasetType === 'derivative' ? 'schema' : 'legacy'
5
+ return dsDescription.DatasetType === "derivative" ? "schema" : "legacy"
6
6
  }
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  DatasetOrSnapshot,
3
3
  getDatasetFromSnapshotId,
4
- } from '../../utils/datasetOrSnapshot'
5
- import config from '../../config'
4
+ } from "../../utils/datasetOrSnapshot"
5
+ import config from "../../config"
6
6
 
7
- const S3_BUCKET = 'openneuro-derivatives'
8
- const GITHUB_ORGANIZATION = 'OpenNeuroDerivatives'
7
+ const S3_BUCKET = "openneuro-derivatives"
8
+ const GITHUB_ORGANIZATION = "OpenNeuroDerivatives"
9
9
 
10
10
  // Available derivatives at this time
11
- type GitHubDerivative = 'mriqc' | 'fmriprep'
11
+ type GitHubDerivative = "mriqc" | "fmriprep"
12
12
 
13
13
  /**
14
14
  * Test for a derivative on GitHub via API
@@ -49,7 +49,7 @@ export const githubDerivative = async (
49
49
  }
50
50
  }
51
51
 
52
- interface DatasetDerivatives {
52
+ export interface DatasetDerivatives {
53
53
  name: string
54
54
  local: boolean
55
55
  s3Url: URL
@@ -80,17 +80,17 @@ export const derivatives = async (
80
80
  dataset: DatasetOrSnapshot,
81
81
  ): Promise<Array<DatasetDerivatives>> => {
82
82
  let datasetId
83
- if ('tag' in dataset) {
83
+ if ("tag" in dataset) {
84
84
  datasetId = getDatasetFromSnapshotId(dataset.id)
85
85
  } else {
86
86
  datasetId = dataset.id
87
87
  }
88
88
  const available: Array<DatasetDerivatives> = []
89
- if (await githubDerivative(datasetId, 'mriqc')) {
90
- available.push(derivativeObject(datasetId, 'mriqc'))
89
+ if (await githubDerivative(datasetId, "mriqc")) {
90
+ available.push(derivativeObject(datasetId, "mriqc"))
91
91
  }
92
- if (await githubDerivative(datasetId, 'fmriprep')) {
93
- available.push(derivativeObject(datasetId, 'fmriprep'))
92
+ if (await githubDerivative(datasetId, "fmriprep")) {
93
+ available.push(derivativeObject(datasetId, "fmriprep"))
94
94
  }
95
95
  return available
96
96
  }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Resolver implementation for dataset_description.json
3
+ */
4
+ import { setDescription } from "../../datalad/description"
5
+ import { checkDatasetWrite } from "../permissions"
6
+ export { description } from "../../datalad/description"
7
+
8
+ export const updateDescription = (
9
+ obj,
10
+ { datasetId, field, value },
11
+ { user, userInfo },
12
+ ) => {
13
+ return checkDatasetWrite(datasetId, user, userInfo)
14
+ .then(() => setDescription(datasetId, userInfo, { [field]: value }))
15
+ .then((description) => description)
16
+ }
17
+
18
+ export const updateDescriptionList = updateDescription
@@ -1,12 +1,12 @@
1
- import Summary from '../../models/summary'
2
- import { summary } from './summary'
3
- import { issues } from './issues.js'
4
- import { description } from './description.js'
5
- import { readme } from './readme.js'
6
- import { getDraftRevision, updateDatasetRevision } from '../../datalad/draft.js'
7
- import { checkDatasetWrite } from '../permissions.js'
8
- import { getFiles } from '../../datalad/files'
9
- import { filterRemovedAnnexObjects } from '../utils/file.js'
1
+ import Summary from "../../models/summary"
2
+ import { summary } from "./summary"
3
+ import { issues } from "./issues.js"
4
+ import { description } from "./description.js"
5
+ import { readme } from "./readme.js"
6
+ import { getDraftRevision, updateDatasetRevision } from "../../datalad/draft.js"
7
+ import { checkDatasetWrite } from "../permissions.js"
8
+ import { getFiles } from "../../datalad/files"
9
+ import { filterRemovedAnnexObjects } from "../utils/file.js"
10
10
 
11
11
  // A draft must have a dataset parent
12
12
  const draftFiles = async (dataset, args, { userInfo }) => {
@@ -19,7 +19,7 @@ const draftSize = async (dataset, args, { userInfo }) => {
19
19
  const hexsha = await getDraftRevision(dataset.id)
20
20
  return Summary.findOne({ datasetId: dataset.id, id: hexsha })
21
21
  .exec()
22
- .then(res => res?.toObject()?.size)
22
+ .then((res) => res?.toObject()?.size)
23
23
  }
24
24
 
25
25
  /**
@@ -44,15 +44,15 @@ export const revalidate = async (obj, { datasetId }, { user, userInfo }) => {
44
44
  }
45
45
 
46
46
  const draft = {
47
- id: obj => obj.id,
47
+ id: (obj) => obj.id,
48
48
  files: draftFiles,
49
49
  size: draftSize,
50
50
  summary,
51
51
  issues,
52
- modified: obj => obj.modified,
52
+ modified: (obj) => obj.modified,
53
53
  description,
54
54
  readme,
55
- head: obj => obj.revision,
55
+ head: (obj) => obj.revision,
56
56
  }
57
57
 
58
58
  export default draft
@@ -1,5 +1,5 @@
1
- import BadAnnexObject from '../../models/badAnnexObject'
2
- import { checkAdmin } from '../permissions'
1
+ import BadAnnexObject from "../../models/badAnnexObject"
2
+ import { checkAdmin } from "../permissions"
3
3
 
4
4
  export const flaggedFiles = async (
5
5
  obj,
@@ -8,6 +8,6 @@ export const flaggedFiles = async (
8
8
  ) => {
9
9
  await checkAdmin(user, userInfo)
10
10
  return BadAnnexObject.find({ flagged, removed: deleted })
11
- .populate('flagger')
12
- .populate('remover')
11
+ .populate("flagger")
12
+ .populate("remover")
13
13
  }
@@ -1,4 +1,4 @@
1
- import Subscription from '../../models/subscription'
1
+ import Subscription from "../../models/subscription"
2
2
 
3
3
  export const followDataset = async (obj, { datasetId }, { user }) => {
4
4
  const following = await Subscription.findOne({
@@ -1,6 +1,6 @@
1
- import { checkDatasetWrite } from '../permissions.js'
2
- import { generateRepoToken } from '../../libs/authentication/jwt'
3
- import { getDatasetEndpoint } from '../../libs/datalad-service.js'
1
+ import { checkDatasetWrite } from "../permissions.js"
2
+ import { generateRepoToken } from "../../libs/authentication/jwt"
3
+ import { getDatasetEndpoint } from "../../libs/datalad-service.js"
4
4
 
5
5
  /**
6
6
  * Generate a short lived token for git operations
@@ -0,0 +1,13 @@
1
+ import { getDatasetWorker } from "../../libs/datalad-service"
2
+
3
+ export const history = async (obj) => {
4
+ const datasetId = obj.id
5
+ const historyUrl = `http://${
6
+ getDatasetWorker(
7
+ datasetId,
8
+ )
9
+ }/datasets/${datasetId}/history`
10
+ const resp = await fetch(historyUrl)
11
+ const { log } = await resp.json()
12
+ return log
13
+ }
@@ -1,9 +1,9 @@
1
- import IngestDataset from '../../models/ingestDataset'
2
- import { checkDatasetWrite } from '../permissions.js'
3
- import { getDatasetWorker } from '../../libs/datalad-service'
4
- import { generateDataladCookie } from '../../libs/authentication/jwt'
5
- import notifications from '../../libs/notifications'
6
- import config from '../../config'
1
+ import IngestDataset from "../../models/ingestDataset"
2
+ import { checkDatasetWrite } from "../permissions.js"
3
+ import { getDatasetWorker } from "../../libs/datalad-service"
4
+ import { generateDataladCookie } from "../../libs/authentication/jwt"
5
+ import notifications from "../../libs/notifications"
6
+ import config from "../../config"
7
7
 
8
8
  /**
9
9
  * Test if a URL is allowed to be imported
@@ -17,10 +17,10 @@ export function allowedImportUrl(raw: string): boolean {
17
17
  } catch (_) {
18
18
  return false
19
19
  }
20
- if (url.hostname === 'brainlife.io') {
20
+ if (url.hostname === "brainlife.io") {
21
21
  return true
22
22
  } else if (
23
- url.hostname === 'openneuro-test-import-bucket.s3.us-west-2.amazonaws.com'
23
+ url.hostname === "openneuro-test-import-bucket.s3.us-west-2.amazonaws.com"
24
24
  ) {
25
25
  return true
26
26
  } else {
@@ -46,11 +46,12 @@ export async function importRemoteDataset(
46
46
  await ingest.save()
47
47
  const importId = ingest._id.toString()
48
48
  const worker = getDatasetWorker(datasetId)
49
- const importUrl = `http://${worker}/datasets/${datasetId}/import/${importId}`
49
+ const importUrl =
50
+ `http://${worker}/datasets/${datasetId}/import/${importId}`
50
51
  await fetch(importUrl, {
51
- method: 'POST',
52
+ method: "POST",
52
53
  headers: {
53
- 'Content-Type': 'application/json',
54
+ "Content-Type": "application/json",
54
55
  Cookie: generateDataladCookie(config)(userInfo),
55
56
  },
56
57
  body: JSON.stringify({ url }),
@@ -0,0 +1,25 @@
1
+ import { GraphQLDate, GraphQLDateTime, GraphQLTime } from "graphql-iso-date"
2
+ import GraphQLBigInt from "graphql-bigint"
3
+ import Query from "./query.js"
4
+ import Mutation from "./mutation.js"
5
+ import Dataset from "./dataset.js"
6
+ import Draft from "./draft.js"
7
+ import Snapshot from "./snapshots.js"
8
+ import User from "./user.js"
9
+ import Comment from "./comment.js"
10
+
11
+ export default {
12
+ // Scalars
13
+ Date: GraphQLDate,
14
+ Time: GraphQLTime,
15
+ DateTime: GraphQLDateTime,
16
+ BigInt: GraphQLBigInt,
17
+ // Complex types
18
+ Query,
19
+ Mutation,
20
+ User,
21
+ Dataset,
22
+ Draft,
23
+ Snapshot,
24
+ Comment,
25
+ }
@@ -1,6 +1,6 @@
1
- import Issue from '../../models/issue'
2
- import { datasetType } from './datasetType'
3
- import { revalidate } from './validation.js'
1
+ import Issue from "../../models/issue"
2
+ import { datasetType } from "./datasetType"
3
+ import { revalidate } from "./validation.js"
4
4
 
5
5
  /**
6
6
  * Issues resolver
@@ -11,12 +11,12 @@ export const issues = async (dataset, _, { userInfo }) => {
11
11
  datasetId: dataset.id,
12
12
  // Match if we have no validatorMetadata or the correct 'legacy' / 'schema' value if we do
13
13
  $or: [
14
- { 'validatorMetadata.validator': await datasetType(dataset) },
14
+ { "validatorMetadata.validator": await datasetType(dataset) },
15
15
  { validatorMetadata: { $exists: false } },
16
16
  ],
17
17
  })
18
18
  .exec()
19
- .then(data => {
19
+ .then((data) => {
20
20
  if (!data && userInfo) {
21
21
  // If no results were found, acquire a lock and run validation
22
22
  revalidate(
@@ -32,17 +32,17 @@ export const issues = async (dataset, _, { userInfo }) => {
32
32
  /**
33
33
  * Snapshot issues resolver
34
34
  */
35
- export const snapshotIssues = async snapshot => {
36
- const datasetId = snapshot.id.split(':')[0]
35
+ export const snapshotIssues = async (snapshot) => {
36
+ const datasetId = snapshot.id.split(":")[0]
37
37
  return Issue.findOne({
38
38
  id: snapshot.hexsha,
39
39
  datasetId,
40
40
  // Match if we have no validatorMetadata or the correct 'legacy' / 'schema' value if we do
41
41
  $or: [
42
- { 'validatorMetadata.validator': await datasetType(snapshot) },
42
+ { "validatorMetadata.validator": await datasetType(snapshot) },
43
43
  { validatorMetadata: { $exists: false } },
44
44
  ],
45
45
  })
46
46
  .exec()
47
- .then(data => (data ? data.issues : null))
47
+ .then((data) => (data ? data.issues : null))
48
48
  }
@@ -1,9 +1,9 @@
1
- import Snapshot from '../../models/snapshot'
2
- import { LeanDocument } from 'mongoose'
3
- import DatasetModel from '../../models/dataset'
4
- import MetadataModel, { MetadataDocument } from '../../models/metadata'
5
- import { latestSnapshot } from './snapshots'
6
- import { permissions } from './permissions'
1
+ import Snapshot from "../../models/snapshot"
2
+ import { LeanDocument } from "mongoose"
3
+ import DatasetModel from "../../models/dataset"
4
+ import MetadataModel, { MetadataDocument } from "../../models/metadata"
5
+ import { latestSnapshot } from "./snapshots"
6
+ import { permissions } from "./permissions"
7
7
 
8
8
  /**
9
9
  * Summary resolver
@@ -28,7 +28,7 @@ export const metadata = async (
28
28
  const adminUsers = []
29
29
  const { userPermissions } = await permissions(dataset)
30
30
  for (const user of userPermissions) {
31
- if (user.level === 'admin') {
31
+ if (user.level === "admin") {
32
32
  const userObj = await user.user
33
33
  adminUsers.push(userObj.name)
34
34
  }
@@ -50,7 +50,7 @@ export const metadata = async (
50
50
  adminUsers,
51
51
  firstSnapshotCreatedAt,
52
52
  latestSnapshotCreatedAt: snapshot.created,
53
- ages: summary?.subjectMetadata?.map(s => s.age as number),
53
+ ages: summary?.subjectMetadata?.map((s) => s.age as number),
54
54
  modalities: summary?.modalities || [],
55
55
  dataProcessed: summary?.dataProcessed || null,
56
56
  }
@@ -5,41 +5,41 @@ import {
5
5
  createDataset,
6
6
  deleteDataset,
7
7
  deleteFiles,
8
- removeAnnexObject,
9
8
  flagAnnexObject,
10
- updatePublic,
9
+ removeAnnexObject,
11
10
  trackAnalytics,
12
- } from './dataset.js'
13
- import { updateRef } from './draft.js'
11
+ updatePublic,
12
+ } from "./dataset.js"
13
+ import { updateRef } from "./draft.js"
14
14
  import {
15
15
  createSnapshot,
16
16
  deleteSnapshot,
17
17
  deprecateSnapshot,
18
18
  undoDeprecateSnapshot,
19
- } from './snapshots.js'
20
- import { removeUser, setAdmin, setBlocked } from './user.js'
21
- import { updateSummary } from './summary'
22
- import { revalidate, updateValidation } from './validation.js'
23
- import { updatePermissions, removePermissions } from './permissions'
24
- import { followDataset } from './follow.js'
25
- import { starDataset } from './stars.js'
26
- import { publishDataset } from './publish.js'
27
- import { updateDescription, updateDescriptionList } from './description.js'
28
- import { updateReadme } from './readme.js'
29
- import { addComment, editComment, deleteComment } from './comment.js'
30
- import { subscribeToNewsletter } from './newsletter'
31
- import { addMetadata } from './metadata'
32
- import { prepareUpload, finishUpload } from './upload.js'
33
- import { prepareRepoAccess } from './git'
34
- import { cacheClear } from './cache'
35
- import { reexportRemotes } from './reexporter'
36
- import { resetDraft } from './reset'
37
- import { createReviewer, deleteReviewer } from './reviewer'
38
- import { createRelation, deleteRelation } from './relation'
19
+ } from "./snapshots.js"
20
+ import { removeUser, setAdmin, setBlocked } from "./user.js"
21
+ import { updateSummary } from "./summary"
22
+ import { revalidate, updateValidation } from "./validation.js"
23
+ import { removePermissions, updatePermissions } from "./permissions"
24
+ import { followDataset } from "./follow.js"
25
+ import { starDataset } from "./stars.js"
26
+ import { publishDataset } from "./publish.js"
27
+ import { updateDescription, updateDescriptionList } from "./description.js"
28
+ import { updateReadme } from "./readme.js"
29
+ import { addComment, deleteComment, editComment } from "./comment.js"
30
+ import { subscribeToNewsletter } from "./newsletter"
31
+ import { addMetadata } from "./metadata"
32
+ import { finishUpload, prepareUpload } from "./upload.js"
33
+ import { prepareRepoAccess } from "./git"
34
+ import { cacheClear } from "./cache"
35
+ import { reexportRemotes } from "./reexporter"
36
+ import { resetDraft } from "./reset"
37
+ import { createReviewer, deleteReviewer } from "./reviewer"
38
+ import { createRelation, deleteRelation } from "./relation"
39
39
  import {
40
- importRemoteDataset,
41
40
  finishImportRemoteDataset,
42
- } from './importRemoteDataset'
41
+ importRemoteDataset,
42
+ } from "./importRemoteDataset"
43
43
 
44
44
  const Mutation = {
45
45
  createDataset,
@@ -4,7 +4,7 @@
4
4
  * Adds emails to newsletter mailing list.
5
5
  */
6
6
 
7
- import Newsletter from '../../models/newsletter'
7
+ import Newsletter from "../../models/newsletter"
8
8
 
9
9
  // finds or adds email to newsletter collection
10
10
  // returns true if email exists or is successfully created
@@ -13,7 +13,7 @@ export const subscribeToNewsletter = (obj, { email }) => {
13
13
  // check if email is not empty
14
14
  if (!email) return false
15
15
  return Newsletter.create({ email })
16
- .then(subscriber => Boolean(subscriber))
16
+ .then((subscriber) => Boolean(subscriber))
17
17
  .catch(() => false)
18
18
  }
19
19