@openneuro/server 4.28.3 → 4.29.0-alpha.1
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/package.json +9 -9
- package/src/app.ts +0 -2
- package/src/cache/item.ts +4 -4
- package/src/datalad/__tests__/files.spec.ts +0 -25
- package/src/datalad/analytics.ts +0 -1
- package/src/datalad/dataset.ts +17 -7
- package/src/datalad/description.ts +11 -11
- package/src/datalad/draft.ts +1 -1
- package/src/datalad/pagination.ts +3 -3
- package/src/datalad/snapshots.ts +6 -2
- package/src/elasticsearch/reindex-dataset.ts +2 -6
- package/src/graphql/permissions.ts +1 -1
- package/src/graphql/resolvers/__tests__/brainlife.spec.ts +1 -1
- package/src/graphql/resolvers/brainlife.ts +3 -5
- package/src/graphql/resolvers/cache.ts +1 -1
- package/src/graphql/resolvers/dataset-search.ts +4 -4
- package/src/graphql/resolvers/dataset.ts +14 -10
- package/src/graphql/resolvers/derivatives.ts +5 -7
- package/src/graphql/resolvers/draft.ts +4 -15
- package/src/graphql/resolvers/importRemoteDataset.ts +1 -0
- package/src/graphql/resolvers/metadata.ts +5 -4
- package/src/graphql/resolvers/mutation.ts +6 -3
- package/src/graphql/resolvers/permissions.ts +52 -33
- package/src/graphql/resolvers/reset.ts +1 -1
- package/src/graphql/resolvers/reviewer.ts +1 -0
- package/src/graphql/resolvers/snapshots.ts +4 -2
- package/src/graphql/resolvers/summary.ts +4 -4
- package/src/graphql/resolvers/validation.ts +37 -2
- package/src/graphql/schema.ts +59 -50
- package/src/handlers/comments.ts +7 -6
- package/src/handlers/datalad.ts +2 -3
- package/src/libs/__tests__/dataset.spec.ts +1 -1
- package/src/libs/email/index.ts +3 -2
- package/src/models/analytics.ts +2 -1
- package/src/models/badAnnexObject.ts +3 -2
- package/src/models/comment.ts +2 -1
- package/src/models/counter.ts +2 -1
- package/src/models/dataset.ts +3 -2
- package/src/models/deletion.ts +2 -1
- package/src/models/deprecatedSnapshot.ts +2 -1
- package/src/models/doi.ts +2 -1
- package/src/models/file.ts +3 -2
- package/src/models/ingestDataset.ts +2 -1
- package/src/models/issue.ts +2 -1
- package/src/models/key.ts +2 -1
- package/src/models/mailgunIdentifier.ts +2 -1
- package/src/models/metadata.ts +2 -1
- package/src/models/newsletter.ts +2 -1
- package/src/models/notification.ts +2 -1
- package/src/models/permission.ts +2 -1
- package/src/models/reviewer.ts +2 -1
- package/src/models/snapshot.ts +2 -1
- package/src/models/stars.ts +2 -1
- package/src/models/subscription.ts +2 -1
- package/src/models/summary.ts +9 -2
- package/src/models/upload.ts +2 -1
- package/src/models/user.ts +2 -1
- package/src/models/validation.ts +58 -0
- package/src/routes.ts +1 -1
- package/src/utils/validateUrl.ts +1 -1
- package/tsconfig.json +3 -1
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
trackAnalytics,
|
|
11
11
|
updatePublic,
|
|
12
12
|
} from "./dataset.js"
|
|
13
|
-
import { updateRef } from "./draft.js"
|
|
14
13
|
import {
|
|
15
14
|
createSnapshot,
|
|
16
15
|
deleteSnapshot,
|
|
@@ -20,7 +19,11 @@ import {
|
|
|
20
19
|
import { removeUser, setAdmin, setBlocked } from "./user.js"
|
|
21
20
|
import { updateSummary } from "./summary"
|
|
22
21
|
import { revalidate, updateValidation } from "./validation.js"
|
|
23
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
removePermissions,
|
|
24
|
+
updateOrcidPermissions,
|
|
25
|
+
updatePermissions,
|
|
26
|
+
} from "./permissions"
|
|
24
27
|
import { followDataset } from "./follow.js"
|
|
25
28
|
import { starDataset } from "./stars.js"
|
|
26
29
|
import { publishDataset } from "./publish.js"
|
|
@@ -55,6 +58,7 @@ const Mutation = {
|
|
|
55
58
|
updateValidation,
|
|
56
59
|
updatePublic,
|
|
57
60
|
updatePermissions,
|
|
61
|
+
updateOrcidPermissions,
|
|
58
62
|
removePermissions,
|
|
59
63
|
removeUser,
|
|
60
64
|
setAdmin,
|
|
@@ -71,7 +75,6 @@ const Mutation = {
|
|
|
71
75
|
deleteComment,
|
|
72
76
|
subscribeToNewsletter,
|
|
73
77
|
addMetadata,
|
|
74
|
-
updateRef,
|
|
75
78
|
prepareUpload,
|
|
76
79
|
finishUpload,
|
|
77
80
|
cacheClear,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import User
|
|
2
|
-
import
|
|
1
|
+
import User from "../../models/user"
|
|
2
|
+
import type { UserDocument } from "../../models/user"
|
|
3
|
+
import Permission from "../../models/permission"
|
|
4
|
+
import type { PermissionDocument } from "../../models/permission"
|
|
3
5
|
import { checkDatasetAdmin } from "../permissions"
|
|
4
6
|
import { user } from "./user"
|
|
5
7
|
|
|
@@ -27,17 +29,33 @@ const publishPermissions = async (datasetId) => {
|
|
|
27
29
|
const ds = { id: datasetId }
|
|
28
30
|
const { id, userPermissions } = await permissions(ds)
|
|
29
31
|
const permissionsUpdated = {
|
|
30
|
-
id
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
id,
|
|
33
|
+
userPermissions: await Promise.all(
|
|
34
|
+
userPermissions.map(async (userPermission) => ({
|
|
35
|
+
...userPermission,
|
|
36
|
+
user: await user(ds, { id: userPermission.userId }),
|
|
37
|
+
})),
|
|
38
|
+
),
|
|
39
|
+
}
|
|
40
|
+
return permissionsUpdated
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function updateUsers(datasetId: string, level: string, users) {
|
|
44
|
+
for (const user of users) {
|
|
45
|
+
await Permission.updateOne(
|
|
46
|
+
{
|
|
47
|
+
datasetId: datasetId,
|
|
48
|
+
userId: user.id,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
datasetId: datasetId,
|
|
52
|
+
userId: user.id,
|
|
53
|
+
level: level,
|
|
54
|
+
},
|
|
55
|
+
{ upsert: true },
|
|
56
|
+
).exec()
|
|
40
57
|
}
|
|
58
|
+
return publishPermissions(datasetId)
|
|
41
59
|
}
|
|
42
60
|
|
|
43
61
|
/**
|
|
@@ -54,28 +72,29 @@ export const updatePermissions = async (obj, args, { user, userInfo }) => {
|
|
|
54
72
|
throw new Error("A user with that email address does not exist")
|
|
55
73
|
}
|
|
56
74
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
.exec()
|
|
72
|
-
.then(() => resolve())
|
|
73
|
-
.catch((err) => reject(err))
|
|
74
|
-
})
|
|
75
|
+
return updateUsers(args.datasetId, args.level, users)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* ORCID variant of updatePermissions
|
|
80
|
+
*/
|
|
81
|
+
export const updateOrcidPermissions = async (obj, args, { user, userInfo }) => {
|
|
82
|
+
await checkDatasetAdmin(args.datasetId, user, userInfo)
|
|
83
|
+
// Get all users associated with the ORCID provided
|
|
84
|
+
const users = await User.find({
|
|
85
|
+
"$or": [{ "orcid": args.userOrcid }, {
|
|
86
|
+
"providerId": args.userOrcid,
|
|
87
|
+
"provider": "orcid",
|
|
88
|
+
}],
|
|
75
89
|
})
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
90
|
+
.collation({ locale: "en", strength: 2 })
|
|
91
|
+
.exec()
|
|
92
|
+
|
|
93
|
+
if (!users.length) {
|
|
94
|
+
throw new Error("A user with that ORCID does not exist")
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return updateUsers(args.datasetId, args.level, users)
|
|
79
98
|
}
|
|
80
99
|
|
|
81
100
|
/**
|
|
@@ -37,6 +37,7 @@ export async function deleteReviewer(
|
|
|
37
37
|
/**
|
|
38
38
|
* Resolver for dataset reviewers
|
|
39
39
|
*/
|
|
40
|
+
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
|
40
41
|
export function reviewers(obj, _, { user, userInfo }) {
|
|
41
42
|
return Reviewer.find({ datasetId: obj.id }).lean().exec()
|
|
42
43
|
}
|
|
@@ -16,6 +16,7 @@ import CacheItem, { CacheType } from "../../cache/item"
|
|
|
16
16
|
import { normalizeDOI } from "../../libs/doi/normalize"
|
|
17
17
|
import { getDraftHead } from "../../datalad/dataset"
|
|
18
18
|
import { downloadFiles } from "../../datalad/snapshots"
|
|
19
|
+
import { snapshotValidation } from "./validation"
|
|
19
20
|
|
|
20
21
|
export const snapshots = (obj) => {
|
|
21
22
|
return datalad.getSnapshots(obj.id)
|
|
@@ -77,7 +78,7 @@ export const matchKnownObjects = (desc) => {
|
|
|
77
78
|
} else {
|
|
78
79
|
objects.push({ id: rawDOI })
|
|
79
80
|
}
|
|
80
|
-
} catch (
|
|
81
|
+
} catch (_err) {
|
|
81
82
|
continue
|
|
82
83
|
}
|
|
83
84
|
}
|
|
@@ -227,7 +228,7 @@ export const latestSnapshot = async (obj, _, context) => {
|
|
|
227
228
|
// In the case where there are no real snapshots, return most recent commit as snapshot
|
|
228
229
|
return await snapshot(
|
|
229
230
|
obj,
|
|
230
|
-
{ datasetId: obj.id, tag: await getDraftHead(obj.id) },
|
|
231
|
+
{ datasetId: obj.id, tag: (await getDraftHead(obj.id)).ref },
|
|
231
232
|
context,
|
|
232
233
|
)
|
|
233
234
|
}
|
|
@@ -258,6 +259,7 @@ export const deleteSnapshot = (obj, { datasetId, tag }, { user, userInfo }) => {
|
|
|
258
259
|
const Snapshot = {
|
|
259
260
|
analytics: (snapshot) => analytics(snapshot),
|
|
260
261
|
issues: (snapshot) => snapshotIssues(snapshot),
|
|
262
|
+
validation: (snapshot) => snapshotValidation(snapshot),
|
|
261
263
|
}
|
|
262
264
|
|
|
263
265
|
export default Snapshot
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Summary
|
|
2
|
-
import {
|
|
1
|
+
import Summary from "../../models/summary"
|
|
2
|
+
import type { SummaryDocument } from "../../models/summary"
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Summary resolver
|
|
@@ -9,9 +9,9 @@ export async function summary(dataset): Promise<Partial<SummaryDocument>> {
|
|
|
9
9
|
await Summary.findOne({
|
|
10
10
|
id: dataset.revision,
|
|
11
11
|
datasetId: dataset.id,
|
|
12
|
-
// Match if we have no validatorMetadata or the correct 'legacy' / 'schema' value if we do
|
|
13
12
|
$or: [
|
|
14
|
-
{ "validatorMetadata.validator":
|
|
13
|
+
{ "validatorMetadata.validator": "schema" },
|
|
14
|
+
{ "validatorMetadata.validator": "legacy" },
|
|
15
15
|
{ validatorMetadata: { $exists: false } },
|
|
16
16
|
],
|
|
17
17
|
}).exec()
|
|
@@ -1,16 +1,51 @@
|
|
|
1
1
|
import config from "../../config"
|
|
2
2
|
import { generateDataladCookie } from "../../libs/authentication/jwt"
|
|
3
3
|
import { getDatasetWorker } from "../../libs/datalad-service"
|
|
4
|
-
import
|
|
4
|
+
import Validation from "../../models/validation"
|
|
5
5
|
import { redlock } from "../../libs/redis"
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Issues resolver for schema validator
|
|
9
|
+
*/
|
|
10
|
+
export const validation = async (dataset, _, { userInfo }) => {
|
|
11
|
+
return Validation.findOne({
|
|
12
|
+
id: dataset.revision,
|
|
13
|
+
datasetId: dataset.id,
|
|
14
|
+
})
|
|
15
|
+
.exec()
|
|
16
|
+
.then((data) => {
|
|
17
|
+
if (!data && userInfo) {
|
|
18
|
+
// If no results were found, acquire a lock and run validation
|
|
19
|
+
revalidate(
|
|
20
|
+
null,
|
|
21
|
+
{ datasetId: dataset.id, ref: dataset.revision },
|
|
22
|
+
{ userInfo },
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
return data
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Snapshot issues resolver for schema validator
|
|
31
|
+
*/
|
|
32
|
+
export const snapshotValidation = async (snapshot) => {
|
|
33
|
+
const datasetId = snapshot.id.split(":")[0]
|
|
34
|
+
return Validation.findOne({
|
|
35
|
+
id: snapshot.hexsha,
|
|
36
|
+
datasetId,
|
|
37
|
+
})
|
|
38
|
+
.exec()
|
|
39
|
+
.then((data) => (data ? data.issues : null))
|
|
40
|
+
}
|
|
41
|
+
|
|
7
42
|
/**
|
|
8
43
|
* Save issues data returned by the datalad service
|
|
9
44
|
*
|
|
10
45
|
* Returns only a boolean if successful or not
|
|
11
46
|
*/
|
|
12
47
|
export const updateValidation = (obj, args) => {
|
|
13
|
-
return
|
|
48
|
+
return Validation.updateOne(
|
|
14
49
|
{
|
|
15
50
|
id: args.validation.id,
|
|
16
51
|
datasetId: args.validation.datasetId,
|
package/src/graphql/schema.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import { schemaComposer } from "graphql-compose"
|
|
3
2
|
import resolvers from "./resolvers"
|
|
4
3
|
import {
|
|
@@ -120,9 +119,11 @@ export const typeDefs = `
|
|
|
120
119
|
# Update a draft summary
|
|
121
120
|
updateSummary(summary: SummaryInput!): Summary
|
|
122
121
|
# Update a draft with validation results
|
|
123
|
-
updateValidation(validation:
|
|
122
|
+
updateValidation(validation: ValidatorInput!): Boolean
|
|
124
123
|
# Update a users's permissions on a dataset
|
|
125
|
-
updatePermissions(datasetId: ID!, userEmail: String!, level: String):
|
|
124
|
+
updatePermissions(datasetId: ID!, userEmail: String!, level: String!): DatasetPermissions
|
|
125
|
+
# Update a users's permissions for a given ORCID
|
|
126
|
+
updateOrcidPermissions(datasetId: ID!, userOrcid: String!, level: String!): DatasetPermissions
|
|
126
127
|
# Remove a users's permissions on a dataset
|
|
127
128
|
removePermissions(datasetId: ID!, userId: String!): Boolean
|
|
128
129
|
# Remove a user
|
|
@@ -155,8 +156,6 @@ export const typeDefs = `
|
|
|
155
156
|
subscribeToNewsletter(email: String!): Boolean
|
|
156
157
|
# Upserts dataset metadata
|
|
157
158
|
addMetadata(datasetId: ID!, metadata: MetadataInput!): Metadata
|
|
158
|
-
# Update draft reference pointer
|
|
159
|
-
updateRef(datasetId: ID!, ref: String!): Boolean
|
|
160
159
|
# Start an upload
|
|
161
160
|
prepareUpload(datasetId: ID!, uploadId: ID!): UploadMetadata
|
|
162
161
|
# Add files from a completed upload to the dataset draft
|
|
@@ -219,7 +218,15 @@ export const typeDefs = `
|
|
|
219
218
|
}
|
|
220
219
|
|
|
221
220
|
# BIDS Validator metadata
|
|
222
|
-
|
|
221
|
+
type ValidatorMetadata {
|
|
222
|
+
# Unique string identifying the type of BIDS validator software
|
|
223
|
+
validator: String
|
|
224
|
+
# Semantic versioning string for the version of the validation software
|
|
225
|
+
version: String
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# BIDS Validator metadata
|
|
229
|
+
input ValidatorMetadataInput {
|
|
223
230
|
# Unique string identifying the type of BIDS validator software
|
|
224
231
|
validator: String
|
|
225
232
|
# Semantic versioning string for the version of the validation software
|
|
@@ -241,7 +248,7 @@ export const typeDefs = `
|
|
|
241
248
|
dataProcessed: Boolean
|
|
242
249
|
pet: SummaryPetInput
|
|
243
250
|
# Metadata for validation software used
|
|
244
|
-
validatorMetadata:
|
|
251
|
+
validatorMetadata: ValidatorMetadataInput
|
|
245
252
|
# BIDS Specification schema version
|
|
246
253
|
schemaVersion: String
|
|
247
254
|
}
|
|
@@ -253,11 +260,12 @@ export const typeDefs = `
|
|
|
253
260
|
group: String
|
|
254
261
|
}
|
|
255
262
|
|
|
256
|
-
input
|
|
263
|
+
input ValidatorInput {
|
|
257
264
|
id: ID! # Git reference for this validation
|
|
258
265
|
datasetId: ID!
|
|
259
|
-
issues: [
|
|
260
|
-
|
|
266
|
+
issues: [ValidatorIssueInput]!
|
|
267
|
+
codeMessages: [ValidatorCodeMessageInput]!
|
|
268
|
+
validatorMetadata: ValidatorMetadataInput!
|
|
261
269
|
}
|
|
262
270
|
|
|
263
271
|
# Dataset Metadata
|
|
@@ -287,13 +295,6 @@ export const typeDefs = `
|
|
|
287
295
|
affirmedConsent: Boolean
|
|
288
296
|
}
|
|
289
297
|
|
|
290
|
-
# Validation updated message
|
|
291
|
-
type ValidationUpdate {
|
|
292
|
-
id: ID!
|
|
293
|
-
datasetId: ID!
|
|
294
|
-
issues: [ValidationIssue]
|
|
295
|
-
}
|
|
296
|
-
|
|
297
298
|
# Information for pagination in a connection.
|
|
298
299
|
type PageInfo {
|
|
299
300
|
# When paginating forwards, are there more items?
|
|
@@ -450,6 +451,28 @@ export const typeDefs = `
|
|
|
450
451
|
binary: Boolean
|
|
451
452
|
}
|
|
452
453
|
|
|
454
|
+
type ValidatorCodeMessage {
|
|
455
|
+
code: String!
|
|
456
|
+
message: String!
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
# BIDS Validator (schema) issues
|
|
460
|
+
type ValidatorIssue {
|
|
461
|
+
code: String!
|
|
462
|
+
subCode: String
|
|
463
|
+
location: String
|
|
464
|
+
severity: Severity
|
|
465
|
+
rule: String
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
type DatasetValidation {
|
|
469
|
+
# Hash of the data validated
|
|
470
|
+
id: String
|
|
471
|
+
datasetId: String
|
|
472
|
+
issues: [ValidatorIssue]
|
|
473
|
+
codeMessages: [ValidatorCodeMessage]
|
|
474
|
+
}
|
|
475
|
+
|
|
453
476
|
# Ephemeral draft or working tree for a dataset
|
|
454
477
|
type Draft {
|
|
455
478
|
id: ID
|
|
@@ -459,8 +482,10 @@ export const typeDefs = `
|
|
|
459
482
|
modified: DateTime
|
|
460
483
|
# Validator summary
|
|
461
484
|
summary: Summary
|
|
462
|
-
# Validator issues
|
|
485
|
+
# Validator issues (legacy validator)
|
|
463
486
|
issues: [ValidationIssue]
|
|
487
|
+
# Validator issues (schema validator)
|
|
488
|
+
validation: DatasetValidation
|
|
464
489
|
# Committed files in the working tree
|
|
465
490
|
files(tree: String): [DatasetFile]
|
|
466
491
|
# dataset_description.json fields
|
|
@@ -486,8 +511,10 @@ export const typeDefs = `
|
|
|
486
511
|
created: DateTime
|
|
487
512
|
# bids-validator summary of this snapshot
|
|
488
513
|
summary: Summary
|
|
489
|
-
#
|
|
514
|
+
# Validator issues (legacy validator)
|
|
490
515
|
issues: [ValidationIssue]
|
|
516
|
+
# Validator issues (schema validator)
|
|
517
|
+
validation: DatasetValidation
|
|
491
518
|
# Snapshot files
|
|
492
519
|
files(tree: String): [DatasetFile]
|
|
493
520
|
# dataset_description.json fields
|
|
@@ -614,6 +641,8 @@ export const typeDefs = `
|
|
|
614
641
|
pet: SummaryPetFields
|
|
615
642
|
# BIDS Specification schema version
|
|
616
643
|
schemaVersion: String
|
|
644
|
+
# Validator metadata
|
|
645
|
+
validatorMetadata: ValidatorMetadata
|
|
617
646
|
}
|
|
618
647
|
|
|
619
648
|
type SummaryPetFields {
|
|
@@ -668,14 +697,17 @@ export const typeDefs = `
|
|
|
668
697
|
helpUrl: String
|
|
669
698
|
}
|
|
670
699
|
|
|
671
|
-
input
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
700
|
+
input ValidatorIssueInput {
|
|
701
|
+
code: String!
|
|
702
|
+
subCode: String
|
|
703
|
+
location: String
|
|
704
|
+
severity: Severity
|
|
705
|
+
rule: String
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
input ValidatorCodeMessageInput {
|
|
709
|
+
code: String!
|
|
710
|
+
message: String!
|
|
679
711
|
}
|
|
680
712
|
|
|
681
713
|
type ValidationIssueFile {
|
|
@@ -692,35 +724,12 @@ export const typeDefs = `
|
|
|
692
724
|
helpUrl: String
|
|
693
725
|
}
|
|
694
726
|
|
|
695
|
-
input ValidationIssueFileInput {
|
|
696
|
-
name: String
|
|
697
|
-
path: String
|
|
698
|
-
key: String
|
|
699
|
-
code: Int
|
|
700
|
-
file: ValidationIssueFileDetailInput
|
|
701
|
-
evidence: String
|
|
702
|
-
line: Int
|
|
703
|
-
character: Int
|
|
704
|
-
severity: Severity
|
|
705
|
-
reason: String
|
|
706
|
-
helpUrl: String
|
|
707
|
-
# Temporary field for compatibility (remove after bids-validator@1.13.0)
|
|
708
|
-
_datasetAbsPath: String
|
|
709
|
-
}
|
|
710
|
-
|
|
711
727
|
type ValidationIssueFileDetail {
|
|
712
728
|
name: String
|
|
713
729
|
path: String
|
|
714
730
|
relativePath: String
|
|
715
731
|
}
|
|
716
732
|
|
|
717
|
-
input ValidationIssueFileDetailInput {
|
|
718
|
-
name: String
|
|
719
|
-
path: String
|
|
720
|
-
relativePath: String
|
|
721
|
-
webkitRelativePath: String
|
|
722
|
-
}
|
|
723
|
-
|
|
724
733
|
# File metadata and link to contents
|
|
725
734
|
type DatasetFile {
|
|
726
735
|
id: ID!
|
package/src/handlers/comments.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import notifications from "../libs/notifications.js"
|
|
3
|
-
import
|
|
2
|
+
import formatISO from "date-fns/formatISO"
|
|
4
3
|
import User from "../models/user"
|
|
5
4
|
import Comment from "../models/comment"
|
|
6
5
|
import MailgunIdentifier from "../models/mailgunIdentifier"
|
|
@@ -15,9 +14,11 @@ const ObjectID = mongoose.Schema.Types.ObjectId
|
|
|
15
14
|
* item that can be stored as if it came from
|
|
16
15
|
* a client-side draft.js editor
|
|
17
16
|
*/
|
|
18
|
-
const textToDraft = (text) => {
|
|
17
|
+
const textToDraft = (text: string) => {
|
|
19
18
|
return JSON.stringify(
|
|
20
|
-
convertToRaw(
|
|
19
|
+
convertToRaw(
|
|
20
|
+
ContentState.createFromBlockArray(convertFromHTML(text).contentBlocks),
|
|
21
|
+
),
|
|
21
22
|
)
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -28,7 +29,6 @@ const textToDraft = (text) => {
|
|
|
28
29
|
* ** maybe returns the newly created comment id
|
|
29
30
|
*/
|
|
30
31
|
export async function reply(req, res, next) {
|
|
31
|
-
/* eslint-disable no-console */
|
|
32
32
|
let comment
|
|
33
33
|
const parentId = req.params.commentId
|
|
34
34
|
? decodeURIComponent(req.params.commentId)
|
|
@@ -49,6 +49,7 @@ export async function reply(req, res, next) {
|
|
|
49
49
|
}
|
|
50
50
|
const user = await User.findOne({ id: userId }).exec()
|
|
51
51
|
const originalComment = await Comment.findOne({
|
|
52
|
+
// @ts-expect-error This is needed as an object and also a type
|
|
52
53
|
_id: ObjectID(parentId),
|
|
53
54
|
}).exec()
|
|
54
55
|
if (user && originalComment) {
|
|
@@ -63,7 +64,7 @@ export async function reply(req, res, next) {
|
|
|
63
64
|
parentId: parentId,
|
|
64
65
|
text: text,
|
|
65
66
|
user: flattenedUser,
|
|
66
|
-
createDate:
|
|
67
|
+
createDate: formatISO(new Date()),
|
|
67
68
|
}
|
|
68
69
|
Comment.create(comment, (err, response) => {
|
|
69
70
|
if (err) {
|
package/src/handlers/datalad.ts
CHANGED
|
@@ -71,12 +71,11 @@ export const getFile = async (req, res) => {
|
|
|
71
71
|
if (r.status === 404) {
|
|
72
72
|
res.status(404).send("Requested dataset or file cannot be found")
|
|
73
73
|
} else {
|
|
74
|
-
// @ts-expect-error
|
|
74
|
+
// @ts-expect-error https://github.com/denoland/deno/issues/19620
|
|
75
75
|
Readable.fromWeb(r.body, { highWaterMark: 4194304 }).pipe(res)
|
|
76
76
|
}
|
|
77
77
|
})
|
|
78
|
-
.catch((
|
|
79
|
-
console.error(err)
|
|
78
|
+
.catch((_err) => {
|
|
80
79
|
res.status(500).send("Internal error transferring requested file")
|
|
81
80
|
})
|
|
82
81
|
}
|
package/src/libs/email/index.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import config from "../../config"
|
|
2
|
+
import mailjet from "node-mailjet"
|
|
2
3
|
|
|
3
4
|
let transport
|
|
4
5
|
let perform_api_call = true
|
|
5
6
|
try {
|
|
6
|
-
const mailjet = require("node-mailjet")
|
|
7
7
|
transport = mailjet.connect(
|
|
8
8
|
config.notifications.email.apiKey,
|
|
9
9
|
config.notifications.email.secret,
|
|
10
10
|
)
|
|
11
|
-
} catch (
|
|
11
|
+
} catch (_err) {
|
|
12
12
|
perform_api_call = false
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -42,6 +42,7 @@ export const send = (email: Record<string, string>): Promise<Response> => {
|
|
|
42
42
|
.request(mailjetFormat(email))
|
|
43
43
|
} else {
|
|
44
44
|
// Mailjet is not configured, instead log emails
|
|
45
|
+
/* eslint-disable no-console */
|
|
45
46
|
console.dir(email)
|
|
46
47
|
}
|
|
47
48
|
}
|
package/src/models/analytics.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import mongoose
|
|
2
|
-
import {
|
|
1
|
+
import mongoose from "mongoose"
|
|
2
|
+
import type { Document } from "mongoose"
|
|
3
|
+
import type { UserDocument } from "./user"
|
|
3
4
|
const ObjectId = mongoose.Schema.Types.ObjectId
|
|
4
5
|
|
|
5
6
|
export interface BadAnnexObject extends Document {
|
package/src/models/comment.ts
CHANGED
package/src/models/counter.ts
CHANGED
package/src/models/dataset.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import mongoose
|
|
1
|
+
import mongoose from "mongoose"
|
|
2
|
+
import type { Document } from "mongoose"
|
|
2
3
|
const { Schema, model } = mongoose
|
|
3
4
|
|
|
4
5
|
// External relations annotating the whole dataset
|
|
@@ -28,7 +29,7 @@ export interface DatasetDocument extends Document {
|
|
|
28
29
|
views: number
|
|
29
30
|
related: [DatasetRelationDocument]
|
|
30
31
|
schemaValidator: boolean
|
|
31
|
-
_conditions:
|
|
32
|
+
_conditions: object
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
const datasetSchema = new Schema<DatasetDocument>(
|
package/src/models/deletion.ts
CHANGED
package/src/models/doi.ts
CHANGED
package/src/models/file.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import mongoose
|
|
1
|
+
import mongoose from "mongoose"
|
|
2
|
+
import type { Document } from "mongoose"
|
|
2
3
|
const { Schema, model } = mongoose
|
|
3
4
|
|
|
4
5
|
export interface FileDocument extends Document {
|
|
5
6
|
datasetId: string
|
|
6
7
|
tag: string
|
|
7
|
-
files:
|
|
8
|
+
files: object[]
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
const fileSchema = new Schema({
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Model for ingest of new datasets from a remote URL (zip/tarball)
|
|
3
3
|
*/
|
|
4
|
-
import mongoose
|
|
4
|
+
import mongoose from "mongoose"
|
|
5
|
+
import type { Document, ObjectId } from "mongoose"
|
|
5
6
|
const { Schema, model } = mongoose
|
|
6
7
|
import { validateUrl } from "../utils/validateUrl"
|
|
7
8
|
|
package/src/models/issue.ts
CHANGED