Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import bids from './src/bids'
export * from './src/bids'

export { bids }

export default {
bids,
}
export { IssueError } from './src/issues/issues'
14 changes: 1 addition & 13 deletions src/bids/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,13 @@ import { buildBidsSchemas } from './schema'
import { BidsJsonFile, BidsSidecar } from './types/json'
import { BidsTsvFile } from './types/tsv'
import { BidsHedIssue } from './types/issues'
import BidsHedSidecarValidator from './validator/sidecarValidator'
import BidsHedTsvValidator from './validator/tsvValidator'

export {
BidsTsvFile,
BidsJsonFile,
BidsSidecar,
BidsHedIssue,
BidsHedSidecarValidator,
BidsHedTsvValidator,
buildBidsSchemas,
}
export { BidsTsvFile, BidsJsonFile, BidsSidecar, BidsHedIssue, buildBidsSchemas }

export default {
BidsTsvFile,
BidsJsonFile,
BidsSidecar,
BidsHedIssue,
BidsHedSidecarValidator,
BidsHedTsvValidator,
buildBidsSchemas,
}
20 changes: 4 additions & 16 deletions src/bids/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ const alphabeticRegExp = new RegExp('^[a-zA-Z]+$')
* Build a HED schema collection based on the defined BIDS schemas.
*
* @param {BidsJsonFile} datasetDescription The description of the BIDS dataset being validated.
* @param {SchemasSpec} schemaDefinition The version spec override for the schema to be loaded.
* @returns {Promise} A Promise with the schema collection, or null if the specification is missing.
* @throws {IssueError} If the schema specification is invalid.
*/
export async function buildBidsSchemas(datasetDescription, schemaDefinition) {
const schemasSpec = buildSchemasSpec(datasetDescription, schemaDefinition)
export async function buildBidsSchemas(datasetDescription) {
const schemasSpec = buildSchemasSpec(datasetDescription)
if (schemasSpec === null) {
return null
}
Expand All @@ -27,28 +26,17 @@ export async function buildBidsSchemas(datasetDescription, schemaDefinition) {
* Build a HED schema specification based on the defined BIDS schemas.
*
* @param {BidsJsonFile} datasetDescription The description of the BIDS dataset being validated.
* @param {SchemasSpec} schemaDefinition The version spec override for the schema to be loaded.
* @returns {SchemasSpec|null} The schema specification to be used to build the schemas, or null if the specification is missing.
* @throws {IssueError} If the schema specification is invalid.
*/
export function buildSchemasSpec(datasetDescription, schemaDefinition) {
if (schemaDefinition) {
return validateSchemasSpec(schemaDefinition)
} else if (datasetDescription.jsonData?.HEDVersion) {
export function buildSchemasSpec(datasetDescription) {
if (datasetDescription.jsonData?.HEDVersion) {
return parseSchemasSpec(datasetDescription.jsonData.HEDVersion)
} else {
return null
}
}

function validateSchemasSpec(schemasSpec) {
if (schemasSpec instanceof SchemasSpec) {
return schemasSpec
} else {
IssueError.generateAndThrow('invalidSchemaSpecification', { spec: JSON.stringify(schemasSpec) })
}
}

export function parseSchemasSpec(hedVersion) {
const schemasSpec = new SchemasSpec()
const processVersion = castArray(hedVersion)
Expand Down
2 changes: 1 addition & 1 deletion src/bids/types/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class BidsFile {
* Validate this validator's tsv file.
*
* @param {Schemas} schemas - The HED schemas used to validate this file.
* @returns {BidsHedIssue[], BidsHedIssue[]} - Any issues found during validation of this TSV file.
* @returns {BidsHedIssue[]} - Any issues found during validation of this TSV file.
*/
validate(schemas) {
if (!this.hasHedData) {
Expand Down
99 changes: 45 additions & 54 deletions src/bids/types/issues.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,48 @@
import groupBy from 'lodash/groupBy'

import { generateIssue, IssueError } from '../../issues/issues'

export class BidsHedIssue {
/**
* The file associated with this issue.
* @type {Object}
*/
file
/**
* The HED Issue object corresponding to this object.
* @type {Issue}
*/
hedIssue
/**
* The BIDS issue code.
* @type {string}
*/
bidsCode
code
/**
* The file associated with this issue.
* @type {Object}
* The HED spec code for this issue.
* @type {string}
*/
file
subCode
/**
* The evidence for this issue.
* The severity of this issue.
* @type {string}
*/
message
severity
/**
* The HED Issue object corresponding to this object.
* @type {Issue}
* The issue message for this issue.
* @type {string}
*/
hedIssue
issueMessage
/**
* The line at which the issue was found.
* @type {number}
*/
line
/**
* The location of the file at which the issue was found.
* @type {string}
*/
location

/**
* Constructor.
Expand All @@ -30,60 +52,29 @@ export class BidsHedIssue {
*/
constructor(hedIssue, file) {
this.hedIssue = hedIssue
this.bidsCode = BidsHedIssue._determineBidsIssueCode(hedIssue)
this.message = hedIssue.message
this.file = file
}

/**
* The HED spec code for this issue.
*
* @returns {string}
*/
get hedCode() {
return this.hedIssue.hedCode
}

/**
* Whether this issue is an error.
*
* @returns {boolean}
*/
get isError() {
return this.hedIssue.level === 'error'
// BIDS fields
if (hedIssue.level === 'warning') {
this.code = 'HED_WARNING'
} else {
this.code = 'HED_ERROR'
}
this.subCode = hedIssue.hedCode
this.severity = hedIssue.level
this.issueMessage = hedIssue.message
this.line = hedIssue.parameters?.tsvLine
this.location = file?.path
}

/**
* Determine if any of the passed issues are errors.
* Split a list of issues into errors and warnings.
*
* @param {BidsHedIssue[]} issues A list of issues.
* @returns {boolean} Whether any of the passed issues are errors (rather than warnings).
* @returns {Object<string, BidsHedIssue[]>} The list of issues divided into errors and warnings.
*/
static anyAreErrors(issues) {
return issues.some((issue) => issue.isError)
}

static splitErrors(issues) {
const errors = issues.filter((item) => item.isError)
const warnings = issues.filter((item) => !item.isError)
return [errors, warnings]
}

/**
* Determine the BIDS issue code for this issue.
*
* @param {Issue} hedIssue The HED issue object to be wrapped.
* @returns {string} The BIDS issue code for this issue.
* @private
*/
static _determineBidsIssueCode(hedIssue) {
if (hedIssue.internalCode === 'internalError') {
return 'HED_INTERNAL_ERROR'
}
if (hedIssue.level === 'warning') {
return 'HED_WARNING'
}
return 'HED_ERROR'
return groupBy(issues, (issue) => issue.severity)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/bids/types/tsv.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class BidsTsvFile extends BidsFile {
if (typeof tsvData === 'string') {
this.parsedTsv = parseTSV(tsvData)
} else if (tsvData instanceof Map) {
this.parsedTsv = tsvData
this.parsedTsv = new Map(tsvData)
} else if (isPlainObject(tsvData)) {
this.parsedTsv = convertParsedTSVData(tsvData)
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/bids/validator/tsvValidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ export class BidsHedTsvValidator extends BidsValidator {
// Validate the BIDS bidsFile if it exists and return if there are errors
if (this.bidsFile.mergedSidecar) {
const issues = this.bidsFile.mergedSidecar.validate(this.hedSchemas)
const [errorIssues, warningIssues] = BidsHedIssue.splitErrors(issues)
this.errors.push(...errorIssues)
this.warnings.push(...warningIssues)
const splitErrors = BidsHedIssue.splitErrors(issues)
this.errors.push(...(splitErrors.error ?? []))
this.warnings.push(...(splitErrors.warning ?? []))
if (this.errors.length > 0) {
return
}
Expand Down
51 changes: 6 additions & 45 deletions src/schema/containers.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import lt from 'semver/functions/lt'

import { IssueError } from '../issues/issues'
import { getGenerationForSchemaVersion } from '../utils/hedData'

/**
* An imported HED 3 schema.
Expand All @@ -10,11 +11,6 @@ export class Schema {
* @type {string}
*/
version
/**
* The HED generation of this schema.
* @type {Number}
*/
generation
/**
* The HED library schema name.
* @type {string}
Expand Down Expand Up @@ -47,10 +43,10 @@ export class Schema {
this.version = rootElement?.$?.version
this.library = rootElement?.$?.library ?? ''

if (this.library) {
this.generation = 3
} else if (this.version) {
this.generation = getGenerationForSchemaVersion(this.version)
if (!this.library && this.version && lt(this.version, '8.0.0')) {
IssueError.generateAndThrow('deprecatedStandardSchemaVersion', {
version: this.version,
})
}

if (!this.library) {
Expand Down Expand Up @@ -93,7 +89,6 @@ export class PartneredSchema extends Schema {
this.actualSchemas = actualSchemas
this.withStandard = actualSchemas[0].withStandard
this.library = undefined
this.generation = 3
}
}

Expand Down Expand Up @@ -186,38 +181,4 @@ export class Schemas {
return null
}
}

/**
* The HED generation of this schema.
*
* If baseSchema is null, generation is set to 0.
* @type {Number}
*/
get generation() {
if (this.schemas === null || this.schemas.size === 0) {
return 0
} else if (this.librarySchemas.size > 0) {
return 3
} else if (this.baseSchema) {
return this.baseSchema.generation
} else {
return 0
}
}

/**
* Whether this schema collection is for syntactic validation only.
* @returns {boolean}
*/
get isSyntaxOnly() {
return this.generation === 0
}

/**
* Whether this schema collection comprises HED 3 schemas.
* @returns {boolean}
*/
get isHed3() {
return this.generation === 3
}
}
4 changes: 0 additions & 4 deletions src/schema/schemaMerger.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ export default class PartneredSchemaMerger {
* @private
*/
_validate() {
if (!this.sourceSchemas.every((schema) => schema.generation === 3)) {
IssueError.generateAndThrowInternalError('Partnered schemas must be HED-3G schemas')
}

for (const schema of this.sourceSchemas.slice(1)) {
if (schema.withStandard !== this.destination.withStandard) {
IssueError.generateAndThrow('differentWithStandard', {
Expand Down
17 changes: 0 additions & 17 deletions src/utils/hedData.js

This file was deleted.

Loading
Loading