bids-validator-deno 2.2.10__tar.gz → 2.3.1.dev0__tar.gz

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 (117) hide show
  1. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/PKG-INFO +1 -1
  2. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/deno.json +9 -7
  3. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/pdm_build.py +17 -2
  4. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/pyproject.toml +1 -1
  5. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/bids-validator.ts +2 -2
  6. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/filetree.ts +2 -2
  7. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/openers.test.ts +13 -14
  8. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/openers.ts +4 -4
  9. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/repo.ts +3 -3
  10. bids_validator_deno-2.3.1.dev0/src/summary/summary.test.ts +142 -0
  11. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/summary/summary.ts +7 -0
  12. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/utils/output.ts +27 -22
  13. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/hed.ts +1 -1
  14. bids_validator_deno-2.2.10/src/summary/summary.test.ts +0 -15
  15. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/LICENSE +0 -0
  16. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/README.md +0 -0
  17. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/.git-meta.json +0 -0
  18. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/access.test.ts +0 -0
  19. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/access.ts +0 -0
  20. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/browser.test.ts +0 -0
  21. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/browser.ts +0 -0
  22. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/deno.test.ts +0 -0
  23. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/deno.ts +0 -0
  24. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/dwi.test.ts +0 -0
  25. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/dwi.ts +0 -0
  26. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/filetree.test.ts +0 -0
  27. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/gzip.test.ts +0 -0
  28. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/gzip.ts +0 -0
  29. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/ignore.test.ts +0 -0
  30. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/ignore.ts +0 -0
  31. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/inheritance.test.ts +0 -0
  32. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/inheritance.ts +0 -0
  33. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/json.test.ts +0 -0
  34. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/json.ts +0 -0
  35. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/nifti.test.ts +0 -0
  36. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/nifti.ts +0 -0
  37. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/repo.test.ts +0 -0
  38. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/streams.test.ts +0 -0
  39. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/streams.ts +0 -0
  40. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/tiff.test.ts +0 -0
  41. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/tiff.ts +0 -0
  42. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/tsv.test.ts +0 -0
  43. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/files/tsv.ts +0 -0
  44. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/issues/datasetIssues.test.ts +0 -0
  45. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/issues/datasetIssues.ts +0 -0
  46. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/issues/list.test.ts +0 -0
  47. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/issues/list.ts +0 -0
  48. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/main.ts +0 -0
  49. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/applyRules.test.ts +0 -0
  50. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/applyRules.ts +0 -0
  51. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/associations.test.ts +0 -0
  52. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/associations.ts +0 -0
  53. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/context.test.ts +0 -0
  54. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/context.ts +0 -0
  55. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/datatypes.test.ts +0 -0
  56. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/datatypes.ts +0 -0
  57. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/entities.test.ts +0 -0
  58. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/entities.ts +0 -0
  59. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/expressionLanguage.test.ts +0 -0
  60. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/expressionLanguage.ts +0 -0
  61. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/fixtures.test.ts +0 -0
  62. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/tables.test.ts +0 -0
  63. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/tables.ts +0 -0
  64. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/walk.test.ts +0 -0
  65. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/schema/walk.ts +0 -0
  66. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/setup/loadSchema.test.ts +0 -0
  67. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/setup/loadSchema.ts +0 -0
  68. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/setup/options.test.ts +0 -0
  69. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/setup/options.ts +0 -0
  70. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/setup/requestPermissions.ts +0 -0
  71. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/summary/collectSubjectMetadata.ts +0 -0
  72. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/README.md +0 -0
  73. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/bom-utf16.tsv +0 -0
  74. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/bom-utf8.json +0 -0
  75. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/generate-filenames.ts +0 -0
  76. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/local/bids_examples.test.ts +0 -0
  77. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/local/common.ts +0 -0
  78. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/local/derivatives.test.ts +0 -0
  79. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/local/empty_files.test.ts +0 -0
  80. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/local/hed-integration.test.ts +0 -0
  81. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/local/nifti_rules.test.ts +0 -0
  82. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/local/valid_dataset.test.ts +0 -0
  83. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/local/valid_filenames.test.ts +0 -0
  84. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/local/valid_headers.test.ts +0 -0
  85. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/nullReadBytes.ts +0 -0
  86. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/regression.test.ts +0 -0
  87. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/schema-expression-language.test.ts +0 -0
  88. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/simple-dataset.ts +0 -0
  89. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/tests/utils.ts +0 -0
  90. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/types/check.ts +0 -0
  91. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/types/columns.test.ts +0 -0
  92. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/types/columns.ts +0 -0
  93. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/types/filetree.ts +0 -0
  94. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/types/issues.ts +0 -0
  95. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/types/schema.ts +0 -0
  96. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/types/validation-result.ts +0 -0
  97. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/utils/errors.ts +0 -0
  98. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/utils/logger.test.ts +0 -0
  99. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/utils/logger.ts +0 -0
  100. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/utils/memoize.ts +0 -0
  101. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/utils/objectPathHandler.ts +0 -0
  102. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/utils/queue.ts +0 -0
  103. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/bids.test.ts +0 -0
  104. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/bids.ts +0 -0
  105. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/citation.test.ts +0 -0
  106. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/citation.ts +0 -0
  107. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/filenameCase.test.ts +0 -0
  108. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/filenameCase.ts +0 -0
  109. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/filenameIdentify.test.ts +0 -0
  110. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/filenameIdentify.ts +0 -0
  111. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/filenameValidate.test.ts +0 -0
  112. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/filenameValidate.ts +0 -0
  113. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/internal/emptyFile.ts +0 -0
  114. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/internal/unusedFile.ts +0 -0
  115. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/json.ts +0 -0
  116. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/validators/validateFiles.test.ts +0 -0
  117. {bids_validator_deno-2.2.10 → bids_validator_deno-2.3.1.dev0}/src/version.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bids-validator-deno
3
- Version: 2.2.10
3
+ Version: 2.3.1.dev0
4
4
  Summary: Typescript implementation of the BIDS validator
5
5
  Keywords: BIDS,BIDS validator
6
6
  Author: bids-standard developers
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bids/validator",
3
- "version": "2.2.10",
3
+ "version": "2.3.1-dev",
4
4
  "exports": {
5
5
  ".": "./src/bids-validator.ts",
6
6
  "./main": "./src/main.ts",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "imports": {
30
30
  "@ajv": "npm:ajv@^8.17.1",
31
- "@bids/schema": "jsr:@bids/schema@~1.1.3",
31
+ "@bids/schema": "jsr:@bids/schema@~1.1.6",
32
32
  "@bradenmacdonald/s3-lite-client": "jsr:@bradenmacdonald/s3-lite-client@^0.9.4",
33
33
  "@cliffy/command": "jsr:@effigies/cliffy-command@1.0.0-dev.8",
34
34
  "@cliffy/table": "jsr:@effigies/cliffy-table@1.0.0-dev.5",
@@ -38,16 +38,18 @@
38
38
  "@mango/nifti": "npm:@bids/nifti-reader-js@^0.6.9",
39
39
  "@std/assert": "jsr:@std/assert@^1.0.16",
40
40
  "@std/fmt": "jsr:@std/fmt@^1.0.8",
41
- "@std/fs": "jsr:@std/fs@^1.0.20",
41
+ "@std/fs": "jsr:@std/fs@^1.0.21",
42
42
  "@std/io": "jsr:@std/io@^0.225.2",
43
43
  "@std/log": "jsr:@std/log@^0.224.14",
44
- "@std/path": "jsr:@std/path@^1.1.3",
45
- "@std/streams": "jsr:@std/streams@^1.0.14",
44
+ "@std/path": "jsr:@std/path@^1.1.4",
45
+ "@std/streams": "jsr:@std/streams@^1.0.16",
46
46
  "@std/testing": "jsr:@std/testing@^1.0.16",
47
47
  "@std/yaml": "jsr:@std/yaml@^1.0.10",
48
- "isomorphic-git": "npm:isomorphic-git@^1.35.1",
48
+ "ansi-escapes": "npm:ansi-escapes@^7.2.0",
49
+ "isomorphic-git": "npm:isomorphic-git@^1.36.1",
49
50
  "hash-wasm": "npm:hash-wasm@^4.12.0",
50
- "marked": "npm:marked@^15.0.4"
51
+ "marked": "npm:marked@^15.0.12",
52
+ "supports-hyperlinks": "npm:supports-hyperlinks@^4.4.0"
51
53
  },
52
54
  "nodeModulesDir": "auto",
53
55
  "tasks": {
@@ -21,12 +21,27 @@ def pdm_build_initialize(context):
21
21
  if deno is None:
22
22
  raise OSError("Deno is not installed or not in PATH")
23
23
 
24
+ permissions = [
25
+ # Access filesystem for reading BIDS datasets
26
+ "--allow-read",
27
+ # Accept environment variables
28
+ "--allow-env",
29
+ # Access network for fetching remote schemas
30
+ "--allow-net",
31
+ # Allow writing results to file
32
+ "--allow-write",
33
+ # Run git to get version info
34
+ "--allow-run=git",
35
+ ]
36
+ if sysconfig.get_platform().startswith("win"):
37
+ # Terminal detection code in supports-hyperlinks calls osRelease
38
+ permissions.append("--allow-sys=osRelease")
39
+
24
40
  subprocess.run(
25
41
  [
26
42
  deno,
27
43
  "compile",
28
- "-ERNW",
29
- "--allow-run",
44
+ *permissions,
30
45
  # Types are checked elsewhere. Type checking at wheel build
31
46
  # is painful if some platforms have newer typescript than others.
32
47
  "--no-check",
@@ -18,7 +18,7 @@ keywords = [
18
18
  "BIDS validator",
19
19
  ]
20
20
  dynamic = []
21
- version = "2.2.10"
21
+ version = "2.3.1-dev"
22
22
 
23
23
  [project.license]
24
24
  text = "MIT"
@@ -1,9 +1,9 @@
1
1
  import { main } from './main.ts'
2
+ import { detectErrors } from './summary/summary.ts'
2
3
 
3
4
  const result = await main()
4
5
 
5
- const errors = result.issues.get({ severity: 'error' })
6
- if (errors.length) {
6
+ if (detectErrors(result)) {
7
7
  Deno.exit(16)
8
8
  }
9
9
  Deno.exit(0)
@@ -45,7 +45,7 @@ function rerootTree({
45
45
  }: RerootTreeOptions): FileTree {
46
46
  const tree = new FileTree(
47
47
  oldTree.path.substr(newRoot.length) || '/',
48
- parent ? oldTree.name : `${oldTree.path}/`, // Set the name of the root to its full path
48
+ parent ? oldTree.name : `${oldTree.path}/`, // Set the name of the root to its full path
49
49
  parent,
50
50
  ignore,
51
51
  )
@@ -60,7 +60,7 @@ function rerootTree({
60
60
 
61
61
  export async function subtree(filetree: FileTree): Promise<FileTree> {
62
62
  const ignore = new FileIgnoreRules([])
63
- const tree = rerootTree({oldTree: filetree, newRoot: filetree.path, ignore})
63
+ const tree = rerootTree({ oldTree: filetree, newRoot: filetree.path, ignore })
64
64
  const bidsignore = tree.get('.bidsignore')
65
65
  if (bidsignore) {
66
66
  try {
@@ -2,13 +2,12 @@
2
2
  * File openers for use in testing
3
3
  */
4
4
  import { assertEquals, assertRejects } from '@std/assert'
5
- import { resolvesNext, stub } from "@std/testing/mock";
5
+ import { resolvesNext, stub } from '@std/testing/mock'
6
6
  import { type FileOpener } from '../types/filetree.ts'
7
7
  import { streamFromString } from '../tests/utils.ts'
8
8
  import { createUTF8Stream } from './streams.ts'
9
9
  import { HTTPOpener } from './openers.ts'
10
10
 
11
-
12
11
  const textEncoder = new TextEncoder()
13
12
  const textDecoder = new TextDecoder()
14
13
 
@@ -157,25 +156,25 @@ Deno.test('Validate CompressedStringOpener', async (t) => {
157
156
  })
158
157
 
159
158
  Deno.test('Validate HTTPOpener', async (t) => {
160
- const url = "http://example.com"
159
+ const url = 'http://example.com'
161
160
  await t.step('Use successful fetch stub', async () => {
162
161
  using _fetchStub = stub(
163
162
  globalThis,
164
- "fetch",
165
- resolvesNext([new Response("Hello, world!")]),
166
- );
163
+ 'fetch',
164
+ resolvesNext([new Response('Hello, world!')]),
165
+ )
167
166
  const httpOpener = new HTTPOpener(url, 1)
168
- assertEquals(await httpOpener.text(), "Hello, world!");
167
+ assertEquals(await httpOpener.text(), 'Hello, world!')
169
168
  })
170
169
  await t.step('Use failed fetch stub', async () => {
171
170
  using _fetchStub = stub(
172
171
  globalThis,
173
- "fetch",
174
- resolvesNext([new Response("Not Found", { status: 404, statusText: "Not Found" })])
175
- );
172
+ 'fetch',
173
+ resolvesNext([new Response('Not Found', { status: 404, statusText: 'Not Found' })]),
174
+ )
176
175
  const httpOpener = new HTTPOpener(url, 1)
177
- assertRejects(httpOpener.text);
178
- assertRejects(httpOpener.stream);
179
- assertRejects(() => httpOpener.readBytes(1, 0));
176
+ assertRejects(httpOpener.text)
177
+ assertRejects(httpOpener.stream)
178
+ assertRejects(() => httpOpener.readBytes(1, 0))
180
179
  })
181
- });
180
+ })
@@ -106,8 +106,8 @@ export class HTTPOpener implements FileOpener {
106
106
  this.size = size
107
107
  }
108
108
 
109
- async _fetch(headers={}): Promise<Response> {
110
- return fetch(this.url, {headers}).then((response) => {
109
+ async _fetch(headers = {}): Promise<Response> {
110
+ return fetch(this.url, { headers }).then((response) => {
111
111
  if (!response.ok || !response.body) {
112
112
  throw new Error(`Failed to fetch ${this.url}: ${response.status} ${response.statusText}`)
113
113
  }
@@ -116,11 +116,11 @@ export class HTTPOpener implements FileOpener {
116
116
  }
117
117
 
118
118
  async stream(): Promise<ReadableStream<Uint8Array<ArrayBuffer>>> {
119
- return this._fetch().then(response => response.body!)
119
+ return this._fetch().then((response) => response.body!)
120
120
  }
121
121
 
122
122
  async text(): Promise<string> {
123
- return this._fetch().then(response => response.text())
123
+ return this._fetch().then((response) => response.text())
124
124
  }
125
125
 
126
126
  async readBytes(size: number, offset = 0): Promise<Uint8Array<ArrayBuffer>> {
@@ -38,8 +38,8 @@ class NonSigningClient {
38
38
  async presignedGetObject(
39
39
  objectName: string,
40
40
  options: {
41
- versionId: string,
42
- }
41
+ versionId: string
42
+ },
43
43
  ): Promise<string> {
44
44
  return `${this.endPoint}/${this.bucket}/${objectName}?versionId=${options.versionId}`
45
45
  }
@@ -215,7 +215,7 @@ export async function resolveAnnexedFile(
215
215
 
216
216
  const metadata = rmet[uuid]
217
217
  const client = await createS3Client({ endPoint: `https://${host}`, bucket, region })
218
- const url = await client.presignedGetObject(metadata.path, {versionId: metadata.version})
218
+ const url = await client.presignedGetObject(metadata.path, { versionId: metadata.version })
219
219
 
220
220
  return { url }
221
221
  }
@@ -0,0 +1,142 @@
1
+ import { computeModalities, modalityPrettyLookup, Summary } from './summary.ts'
2
+ import { assertEquals, type assertObjectMatch } from '@std/assert'
3
+ import { detectErrors } from './summary.ts'
4
+ import { ValidationResult } from '../types/validation-result.ts'
5
+ import { DatasetIssues } from '../issues/datasetIssues.ts'
6
+ import type { Issue } from '../types/issues.ts'
7
+
8
+ Deno.test('Summary class and helper functions', async (t) => {
9
+ await t.step('Constructor succeeds', () => {
10
+ new Summary()
11
+ })
12
+ await t.step('computeModalities properly sorts modality counts', () => {
13
+ const modalitiesIn = { eeg: 5, pet: 6, mri: 6, ieeg: 6 }
14
+ const modalitiesOut = ['pet', 'ieeg', 'mri', 'eeg'].map(
15
+ (x) => modalityPrettyLookup[x],
16
+ )
17
+ assertEquals(computeModalities(modalitiesIn), modalitiesOut)
18
+ })
19
+ })
20
+
21
+ const json_mock_validation_result = {
22
+ 'issues': {
23
+ 'issues': [],
24
+ 'codeMessages': {},
25
+ },
26
+ 'summary': {
27
+ 'sessions': [],
28
+ 'subjects': [
29
+ '01',
30
+ ],
31
+ 'subjectMetadata': [],
32
+ 'tasks': [],
33
+ 'modalities': [
34
+ 'MRI',
35
+ ],
36
+ 'secondaryModalities': [
37
+ 'MRI_Structural',
38
+ ],
39
+ 'totalFiles': 14,
40
+ 'size': 1513,
41
+ 'dataProcessed': false,
42
+ 'pet': {},
43
+ 'dataTypes': [
44
+ 'fmap',
45
+ 'anat',
46
+ ],
47
+ 'schemaVersion': '1.1.3',
48
+ },
49
+ 'derivativesSummary': {
50
+ '/derivatives/mock/': {
51
+ 'issues': {
52
+ 'issues': [
53
+ {
54
+ 'code': 'EMPTY_FILE',
55
+ 'severity': 'error',
56
+ 'location': '/README',
57
+ },
58
+ ],
59
+ },
60
+ 'summary': {
61
+ 'sessions': [],
62
+ 'subjects': [
63
+ '01',
64
+ ],
65
+ 'subjectMetadata': [],
66
+ 'tasks': [],
67
+ 'modalities': [
68
+ 'MRI',
69
+ ],
70
+ 'secondaryModalities': [
71
+ 'MRI_Structural',
72
+ ],
73
+ 'totalFiles': 12,
74
+ 'size': 3715,
75
+ 'dataProcessed': true,
76
+ 'pet': {},
77
+ 'dataTypes': [
78
+ 'fmap',
79
+ 'anat',
80
+ ],
81
+ 'schemaVersion': '1.1.3',
82
+ },
83
+ },
84
+ },
85
+ }
86
+
87
+ const mockValidationResultBadDerivatives: ValidationResult = {
88
+ issues: new DatasetIssues({
89
+ issues: json_mock_validation_result.issues.issues as Issue[],
90
+ codeMessages: new Map(Object.entries(json_mock_validation_result.issues.codeMessages)),
91
+ }),
92
+ summary: json_mock_validation_result.summary,
93
+ derivativesSummary: {
94
+ '/derivatives/mock/': {
95
+ issues: new DatasetIssues({
96
+ issues: json_mock_validation_result.derivativesSummary['/derivatives/mock/'].issues
97
+ .issues as Issue[],
98
+ }),
99
+ summary: json_mock_validation_result.derivativesSummary['/derivatives/mock/'].summary,
100
+ },
101
+ },
102
+ }
103
+
104
+ const mockValidationResultBadRawData: ValidationResult = {
105
+ issues: new DatasetIssues({
106
+ issues: json_mock_validation_result.derivativesSummary['/derivatives/mock/'].issues
107
+ .issues as Issue[],
108
+ }),
109
+ summary: json_mock_validation_result.summary,
110
+ }
111
+
112
+ Deno.test('detectErrors properly collects errors', () => {
113
+ const errors = detectErrors(mockValidationResultBadDerivatives)
114
+ assertEquals(errors, true)
115
+ })
116
+
117
+ Deno.test('detectErrors properly collects errors from raw data', () => {
118
+ const errors = detectErrors(mockValidationResultBadRawData)
119
+ assertEquals(errors, true)
120
+ })
121
+
122
+ const mockValidationResultNoErrors: ValidationResult = {
123
+ issues: new DatasetIssues({
124
+ issues: [],
125
+ codeMessages: new Map(),
126
+ }),
127
+ summary: json_mock_validation_result.summary,
128
+ derivativesSummary: {
129
+ '/derivatives/mock/': {
130
+ issues: new DatasetIssues({
131
+ issues: [],
132
+ codeMessages: new Map(),
133
+ }),
134
+ summary: json_mock_validation_result.derivativesSummary['/derivatives/mock/'].summary,
135
+ },
136
+ },
137
+ }
138
+
139
+ Deno.test('detectErrors returns false when no errors found', () => {
140
+ const errors = detectErrors(mockValidationResultNoErrors)
141
+ assertEquals(errors, false)
142
+ })
@@ -1,6 +1,8 @@
1
1
  import { collectSubjectMetadata } from './collectSubjectMetadata.ts'
2
2
  import type { SubjectMetadata, SummaryOutput } from '../types/validation-result.ts'
3
3
  import type { BIDSContext } from '../schema/context.ts'
4
+ import type { ValidationResult } from '../types/validation-result.ts'
5
+ import type { Issue } from '../types/issues.ts'
4
6
 
5
7
  export const modalityPrettyLookup: Record<string, string> = {
6
8
  mri: 'MRI',
@@ -169,3 +171,8 @@ export class Summary {
169
171
  }
170
172
  }
171
173
  }
174
+
175
+ export function detectErrors(result: ValidationResult): boolean {
176
+ return result.issues.get({ severity: 'error' }).length > 0 ||
177
+ Object.values(result.derivativesSummary ?? {}).some((res) => detectErrors(res))
178
+ }
@@ -5,6 +5,8 @@ import { Table } from '@cliffy/table'
5
5
  import * as colors from '@std/fmt/colors'
6
6
  import { format as prettyBytes } from '@std/fmt/bytes'
7
7
  import { marked } from 'marked'
8
+ import supportsHyperlinks from 'supports-hyperlinks'
9
+ import ansiEscapes from 'ansi-escapes'
8
10
  import type { SummaryOutput, ValidationResult } from '../types/validation-result.ts'
9
11
  import type { Issue, Severity } from '../types/issues.ts'
10
12
  import type { DatasetIssues } from '../issues/datasetIssues.ts'
@@ -36,7 +38,7 @@ export function consoleFormat(
36
38
  if (result.derivativesSummary) {
37
39
  for (const [key, derivResult] of Object.entries(result.derivativesSummary)) {
38
40
  output.push(colors.blue(`Derivative: ${key}`))
39
-
41
+
40
42
  if (derivResult.issues.size === 0) {
41
43
  output.push(colors.green('\tThis derivative appears to be BIDS compatible.'))
42
44
  } else {
@@ -48,7 +50,7 @@ export function consoleFormat(
48
50
  output.push('')
49
51
  }
50
52
  }
51
-
53
+
52
54
  return output.join('\n')
53
55
  }
54
56
 
@@ -59,32 +61,35 @@ function renderTokens(tokenList: any[]): string {
59
61
  if (!tokenList) return ''
60
62
 
61
63
  return tokenList.map((token) => {
62
- if (token.type === 'paragraph') {
63
- return renderTokens(token.tokens)
64
- }
64
+ switch (token.type) {
65
+ case 'paragraph':
66
+ return renderTokens(token.tokens)
65
67
 
66
- if (token.type === 'strong') {
67
- return colors.bold(renderTokens(token.tokens))
68
- }
68
+ case 'strong':
69
+ return colors.bold(renderTokens(token.tokens))
69
70
 
70
- if (token.type === 'em') {
71
- return colors.italic(renderTokens(token.tokens))
72
- }
71
+ case 'em':
72
+ return colors.italic(renderTokens(token.tokens))
73
73
 
74
- if (token.type === 'codespan') {
75
- return colors.cyan(token.text)
76
- }
74
+ case 'codespan':
75
+ return colors.cyan(token.text)
77
76
 
78
- if (token.type === 'link') {
79
- return `${colors.blue(token.text)} (${colors.gray(token.href)})`
80
- }
77
+ case 'link':
78
+ // Using the library to check for stdout support
79
+ if (supportsHyperlinks.stdout) {
80
+ return ansiEscapes.link(token.text, token.href)
81
+ } else {
82
+ // Fallback for terminals without support
83
+ return `${colors.blue(token.text)} (${colors.gray(token.href)})`
84
+ }
81
85
 
82
- if (token.type === 'text') {
83
- return token.text
84
- }
86
+ case 'text':
87
+ return token.text
85
88
 
86
- // Render children or return raw text
87
- return renderTokens(token.tokens || []) || token.raw || ''
89
+ default:
90
+ // Render children or return raw text
91
+ return renderTokens(token.tokens || []) || token.raw || ''
92
+ }
88
93
  }).join('')
89
94
  }
90
95
 
@@ -13,7 +13,7 @@ function sidecarHasHed(sidecarData: BIDSContext['sidecar']): boolean {
13
13
  }
14
14
 
15
15
  function sidecarValueHasHed(sidecarValue: { HED?: string }): boolean {
16
- return typeof sidecarValue.HED !== 'undefined'
16
+ return typeof sidecarValue?.HED !== 'undefined'
17
17
  }
18
18
 
19
19
  async function setHedSchemas(dataset: BIDSContextDataset): Promise<HedIssue[]> {
@@ -1,15 +0,0 @@
1
- import { computeModalities, modalityPrettyLookup, Summary } from './summary.ts'
2
- import { assertEquals, type assertObjectMatch } from '@std/assert'
3
-
4
- Deno.test('Summary class and helper functions', async (t) => {
5
- await t.step('Constructor succeeds', () => {
6
- new Summary()
7
- })
8
- await t.step('computeModalities properly sorts modality counts', () => {
9
- const modalitiesIn = { eeg: 5, pet: 6, mri: 6, ieeg: 6 }
10
- const modalitiesOut = ['pet', 'ieeg', 'mri', 'eeg'].map(
11
- (x) => modalityPrettyLookup[x],
12
- )
13
- assertEquals(computeModalities(modalitiesIn), modalitiesOut)
14
- })
15
- })