Skip to content

Schema 8 #106

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
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
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"cSpell.words": [
"anonymisation"
]
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@codaco/protocol-validation",
"version": "3.0.0",
"version": "3.1.0-alpha.1",
"main": "dist/index.js",
"license": "GPL-3.0-or-later",
"repository": {
Expand Down
3 changes: 3 additions & 0 deletions src/migrations/migrations/8.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ const migration = (protocol) => protocol;

// Markdown format
const notes = `
- New interface: "geospatial interface". Allows the participant to select a location on a map based on a geojson shapefile.
- New interface: "anonymisation interface". Allows the participant to encrypt sensitive/identifiable information, so that it cannot be read by the researcher.
- New interface: "one-to-many dyad-census". Allows the participant to link multiple alters at a time.
- Add new validation options for form fields: \`greaterThanVariable\` and \`lessThanVariable\`.
- Add new comparator options for skip logic and filter: \`contains\` and \`does not contain\`.
- Amplify comparator options \`includes\` and \`excludes\` for ordinal and categorical variables to allow multiple selections.
Expand Down
149 changes: 146 additions & 3 deletions src/schemas/8.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,77 @@
},
"AssetManifest": {
"type": "object",
"title": "AssetManifest"
"title": "AssetManifest",
"additionalProperties": {
"$ref": "#/definitions/Asset"
}
},
"Asset": {
"type": "object",
"oneOf": [
{
"$ref": "#/definitions/FileAsset"
},
{
"$ref": "#/definitions/ApiKeyAsset"
}
]
},
"BaseAsset": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string",
"enum": ["image", "video", "network", "geojson", "apikey"]
},
"name": {
"type": "string"
}
},
"required": ["id", "type", "name"]
},
"FileAsset": {
"allOf": [
{
"$ref": "#/definitions/BaseAsset"
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["image", "video", "network", "geojson"]
},
"source": {
"type": "string"
}
},
"required": ["source"]
}
]
},
"ApiKeyAsset": {
"allOf": [
{
"$ref": "#/definitions/BaseAsset"
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["apikey"]
},
"value": {
"type": "string"
}
},
"required": ["value"]
}
]
},
"Form": {
"type": ["object", "null"],
Expand Down Expand Up @@ -95,7 +165,11 @@
"TieStrengthCensus",
"Information",
"OrdinalBin",
"CategoricalBin"
"CategoricalBin",
"Anonymisation",
"OneToManyDyadCensus",
"FamilyTreeCensus",
"Geospatial"
]
},
"label": {
Expand Down Expand Up @@ -177,6 +251,9 @@
},
"filter": {
"$ref": "#/definitions/Filter"
},
"mapOptions": {
"$ref": "#/definitions/MapOptions"
}
},
"required": ["id", "label", "type"],
Expand Down Expand Up @@ -248,11 +325,22 @@
"Sociogram",
"OrdinalBin",
"CategoricalBin",
"DyadCensus"
"DyadCensus",
"Anonymisation",
"OneToManyDyadCensus",
"FamilyTreeCensus"
]
}
},
"required": ["prompts"]
},
{
"properties": {
"type": {
"const": "Geospatial"
}
},
"required": ["mapOptions", "prompts"]
}
]
},
Expand Down Expand Up @@ -1030,6 +1118,61 @@
"type": "string",
"enum": ["desc", "asc"],
"title": "Direction"
},
"MapOptions": {
"type": "object",
"additionalProperties": false,
"properties": {
"tokenAssetId": {
"type": "string"
},
"style": {
"type": "string",
"enum": [
"mapbox://styles/mapbox/standard",
"mapbox://styles/mapbox/standard-satellite",
"mapbox://styles/mapbox/streets-v12",
"mapbox://styles/mapbox/outdoors-v12",
"mapbox://styles/mapbox/light-v11",
"mapbox://styles/mapbox/dark-v11",
"mapbox://styles/mapbox/satellite-v9",
"mapbox://styles/mapbox/satellite-streets-v12",
"mapbox://styles/mapbox/navigation-day-v1",
"mapbox://styles/mapbox/navigation-night-v1"
]
},
"center": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
},
"initialZoom": {
"type": "number",
"minimum": 0,
"maximum": 22
},
"dataSourceAssetId": {
"type": "string"
},
"color": {
"type": "string"
},
"targetFeatureProperty": {
"type": "string"
}
},
"required": [
"tokenAssetId",
"style",
"center",
"initialZoom",
"dataSourceAssetId",
"color",
"targetFeatureProperty"
]
}
}
}
37 changes: 37 additions & 0 deletions src/validation/validateExternalData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Variables and option values must respect NMTOKEN rules so that
// they are compatable with XML export formats
const allowedVariableName = (value) => {
if (!/^[a-zA-Z0-9._\-:]+$/.test(value)) {
return 'Not a valid variable name. Only letters, numbers and the symbols ._-: are supported.';
}
return undefined;
};

const getUniqueAttributes = (items) => {
const uniqueSet = items.reduce(
(acc, node) => {
Object.keys(node['attributes'])
.forEach(key => acc.add(key));
return acc;
},
new Set([]),
);

return Array.from(uniqueSet);
};

const getVariableNamesFromNetwork = network =>
['nodes', 'edges'].flatMap(
entity => getUniqueAttributes(network[entity] || []),
);

const validateNames = (items = []) => {
const errors = items
.filter(item => allowedVariableName(item) !== undefined);

if (errors.length === 0) { return false; }

return `Variable name not allowed ("${errors.join('", "')}"). Only letters, numbers and the symbols ._-: are supported.`;
};

module.exports = { validateNames, getVariableNamesFromNetwork };