diff --git a/.github/workflows/commit_gate.yml b/.github/workflows/commit_gate.yml new file mode 100644 index 0000000..392c028 --- /dev/null +++ b/.github/workflows/commit_gate.yml @@ -0,0 +1,33 @@ +name: Commit Gate + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' # Or any other version you need + + - name: Install dependencies + run: npm ci --prefix src/ + + - name: Build + run: npm run build --prefix src/ + + - name: Install test dependencies + run: npm ci --prefix tests/ + + - name: Run tests + run: npm run test --prefix tests/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a6661d4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,45 @@ +name: Publish npm package + +on: + push: + tags: v* + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - name: Get version from tag + id: get_version + # "refs/tags/v" is 11 characters + run: | + versionNumber=${GITHUB_REF:11} + echo "::set-output name=version_number::$versionNumber" + + - name: checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + registry-url: 'https://registry.npmjs.org' + + - name: Create npm package + run: | + cd src + npm version ${{ steps.get_version.outputs.version_number }} + npm ci + npm run build + npm pack + + - name: Publish package + run: | + cd src + npm publish --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index c988b00..6df729b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ _* -**/node_modules \ No newline at end of file +**/node_modules +**/built \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index c1854bb..8741231 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,6 +14,23 @@ ], "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" + }, + { + "name": "Debug Multifile", + "type": "node", + "request": "launch", + "program": "${workspaceRoot}/src/built/index.js", + "args": [ + "-r", + "./samples/multiFile/invalid/duplicatePropertyname/sample/", + "-s", + "schemas/multiFile.relations.json", + "-o", + "_out/validationErrors.json" + ], + "preLaunchTask": "npm: build - src", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" } ] -} \ No newline at end of file +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d24ef48..d9e0f08 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,14 +1,23 @@ { - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "test", - "path": "tests", - "group": "test", - "problemMatcher": [], - "label": "npm: test - tests", - "detail": "jest" - } - ] + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "test", + "path": "tests", + "group": "test", + "problemMatcher": [], + "label": "npm: test - tests", + "detail": "jest" + }, + { + "type": "npm", + "script": "build", + "path": "src", + "group": "build", + "problemMatcher": [], + "label": "npm: build - src", + "detail": "tsc" + } + ] } \ No newline at end of file diff --git a/src/built/validateRels.js b/src/built/validateRels.js deleted file mode 100644 index 2fe844e..0000000 --- a/src/built/validateRels.js +++ /dev/null @@ -1,414 +0,0 @@ -var __assign = (this && this.__assign) || function () { - __assign = Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (g && (g = 0, op[0] && (_ = 0)), _) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; -var __asyncValues = (this && this.__asyncValues) || function (o) { - if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator], i; - return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); - function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } - function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } -}; -import { createRequire as _createRequire } from "module"; -var __require = _createRequire(import.meta.url); -import { glob } from 'glob'; -var jp = __require("jsonpath-plus"); -var fs = __require("fs"); -function query(obj, query) { - return jp.JSONPath({ path: query, resultType: 'all', json: obj }); -} -function validateMultiFileRels(rootFolder, relationsSpec) { - return __awaiter(this, void 0, void 0, function () { - var _a, scope, selector, allDiagnostics, fileContextIterator, _b, fileContextIterator_1, fileContextIterator_1_1, fileContext, fullPath, fullPosixPath, fileNames, relObjs, _c, fileNames_1, fileNames_1_1, fileName, content, obj, e_1_1, diagnostics, e_2_1; - var _d, e_2, _e, _f, _g, e_1, _h, _j; - return __generator(this, function (_k) { - switch (_k.label) { - case 0: - _a = relationsSpec.multiFile, scope = _a.scope, selector = _a.selector; - allDiagnostics = new Array(); - fileContextIterator = glob.iterate(scope, { cwd: rootFolder, posix: true, withFileTypes: true }); - _k.label = 1; - case 1: - _k.trys.push([1, 20, 21, 26]); - _b = true, fileContextIterator_1 = __asyncValues(fileContextIterator); - _k.label = 2; - case 2: return [4 /*yield*/, fileContextIterator_1.next()]; - case 3: - if (!(fileContextIterator_1_1 = _k.sent(), _d = fileContextIterator_1_1.done, !_d)) return [3 /*break*/, 19]; - _f = fileContextIterator_1_1.value; - _b = false; - fileContext = _f; - fullPath = fileContext.fullpath(); - fullPosixPath = fullPath.replace(/\\/g, '/'); - return [4 /*yield*/, glob.glob(selector, { cwd: fileContext.toString(), posix: true })]; - case 4: - fileNames = _k.sent(); - relObjs = new Array(fileNames.length); - _k.label = 5; - case 5: - _k.trys.push([5, 11, 12, 17]); - _c = true, fileNames_1 = (e_1 = void 0, __asyncValues(fileNames)); - _k.label = 6; - case 6: return [4 /*yield*/, fileNames_1.next()]; - case 7: - if (!(fileNames_1_1 = _k.sent(), _g = fileNames_1_1.done, !_g)) return [3 /*break*/, 10]; - _j = fileNames_1_1.value; - _c = false; - fileName = _j; - return [4 /*yield*/, fs.promises.readFile(fileName, { encoding: 'utf-8' })]; - case 8: - content = _k.sent(); - obj = JSON.parse(content); - relObjs.push({ name: fileName, value: obj }); - _k.label = 9; - case 9: - _c = true; - return [3 /*break*/, 6]; - case 10: return [3 /*break*/, 17]; - case 11: - e_1_1 = _k.sent(); - e_1 = { error: e_1_1 }; - return [3 /*break*/, 17]; - case 12: - _k.trys.push([12, , 15, 16]); - if (!(!_c && !_g && (_h = fileNames_1.return))) return [3 /*break*/, 14]; - return [4 /*yield*/, _h.call(fileNames_1)]; - case 13: - _k.sent(); - _k.label = 14; - case 14: return [3 /*break*/, 16]; - case 15: - if (e_1) throw e_1.error; - return [7 /*endfinally*/]; - case 16: return [7 /*endfinally*/]; - case 17: - diagnostics = validateTreeRels(relObjs, relationsSpec); - allDiagnostics = allDiagnostics.concat(diagnostics); - _k.label = 18; - case 18: - _b = true; - return [3 /*break*/, 2]; - case 19: return [3 /*break*/, 26]; - case 20: - e_2_1 = _k.sent(); - e_2 = { error: e_2_1 }; - return [3 /*break*/, 26]; - case 21: - _k.trys.push([21, , 24, 25]); - if (!(!_b && !_d && (_e = fileContextIterator_1.return))) return [3 /*break*/, 23]; - return [4 /*yield*/, _e.call(fileContextIterator_1)]; - case 22: - _k.sent(); - _k.label = 23; - case 23: return [3 /*break*/, 25]; - case 24: - if (e_2) throw e_2.error; - return [7 /*endfinally*/]; - case 25: return [7 /*endfinally*/]; - case 26: return [2 /*return*/, allDiagnostics]; - } - }); - }); -} -function validateRels(objToValidate, relationsSpec) { - return validateTreeRels([{ name: '', value: objToValidate }], relationsSpec); -} -function validateTreeRels(objs, relationsSpec) { - var relations = relationsSpec.relations; - var relationIds = Object.keys(relations); - var uniqueIds = relationIds.filter(function (id) { return relations[id].unique; }); - var keyIds = relationIds.filter(function (id) { return relations[id].key; }); - var keyrefIds = relationIds.filter(function (id) { return relations[id].keyRef; }); - var uniqueContextInfos = uniqueIds.map(function (id) { - var constraint = getIdentityConstraint(id, relations[id]); - return { - id: id, - constraint: constraint, - contexts: objs.flatMap(function (o) { return collectContexts(o, constraint); }) - }; - }); - var uniqueDiagnostics = uniqueContextInfos.flatMap(function (i) { return validateUniqueContexts(i.contexts, i.constraint); }); - var keyContextInfos = keyIds.map(function (id) { - var constraint = getIdentityConstraint(id, relations[id]); - return { - id: id, - constraint: constraint, - contexts: objs.flatMap(function (o) { return collectContexts(o, constraint); }) - }; - }); - var keyDiagnostics = keyContextInfos.flatMap(function (i) { return getKeyDiagnostics(i.contexts, i.constraint); }); - var qualifiedReferNodesById = new Map(uniqueContextInfos.concat(keyContextInfos) - .map(function (ci) { return [ci.id, ci.contexts.flatMap(function (c) { return c.nodes.filter(isQualified); })]; })); - var keyRefContextInfos = keyrefIds.map(function (id) { - var constraint = getIdentityConstraint(id, relations[id]); - return { - id: id, - constraint: constraint, - contexts: objs.flatMap(function (o) { return collectContexts(o, constraint); }) - }; - }); - var keyrefDiagnostics = keyRefContextInfos.flatMap(function (i) { return validateKeyrefContexts(i.contexts, qualifiedReferNodesById.get(relations[i.id].keyRef.refer), i.constraint); }); - return keyDiagnostics.concat(uniqueDiagnostics).concat(keyrefDiagnostics); -} -function getIdentityConstraint(id, relation) { - var _a, _b, _c; - if (relation.key) { - return { - id: id, - contextNodeSelector: (_a = relation.key.scope) !== null && _a !== void 0 ? _a : "$.", - selector: relation.key.selector, - fieldSelectors: typeof relation.key.field === 'string' ? [relation.key.field] : relation.key.field - }; - } - if (relation.unique) { - return { - id: id, - contextNodeSelector: (_b = relation.unique.scope) !== null && _b !== void 0 ? _b : "$.", - selector: relation.unique.selector, - fieldSelectors: typeof relation.unique.field === 'string' ? [relation.unique.field] : relation.unique.field - }; - } - if (relation.keyRef) { - return { - id: id, - contextNodeSelector: (_c = relation.keyRef.scope) !== null && _c !== void 0 ? _c : "$.", - selector: relation.keyRef.selector, - fieldSelectors: typeof relation.keyRef.field === 'string' ? [relation.keyRef.field] : relation.keyRef.field - }; - } - throw new Error("unknown relation ".concat(id, ": ").concat(relation)); -} -function validateKeyrefContexts(contexts, referNodes, constraint) { - return contexts.flatMap(function (_a) { - var nodes = _a.nodes; - return validateKeyRef(constraint, referNodes, nodes.filter(isQualified)); - }); -} -function validateKeyRef(constraint, referNodes, keyrefNodes) { - // use a separator that guarantees that different key sequences end up as different strings - var separator = "°#@"; - var toKeySequenceId = function (ks) { return ks.join(separator); }; - var keySequenceIds = new Set(referNodes.map(function (n) { return toKeySequenceId(n.keySequence.evaluated); })); - var invalidRefNodes = keyrefNodes.filter(function (n) { return !keySequenceIds.has(toKeySequenceId(n.keySequence.evaluated)); }); - return invalidRefNodes.map(function (n) { - return { - instancePath: n.contextNode.pointer + n.targetNode.pointer, - keyword: "keyRef", - message: "invalid keyRef '".concat(n.keySequence.evaluated.join(', '), "'"), - params: { - relationId: constraint.id, - invalidRef: n.keySequence.evaluated.length === 1 ? n.keySequence.evaluated[0] : n.keySequence.evaluated - } - }; - }); -} -function validateUniqueContexts(contexts, constraint) { - return contexts.flatMap(function (_a) { - var nodes = _a.nodes; - return validateUnique(nodes, constraint); - }); -} -function validateUnique(nodes, constraint) { - var qualifiedNodes = nodes.filter(isQualified); - var diagnostics = getUniqueDiagnostics(qualifiedNodes, constraint, "unique"); - return diagnostics; -} -function getKeyDiagnostics(contexts, constraint) { - return contexts.flatMap(function (_a) { - var contextNode = _a.contextNode, nodes = _a.nodes; - var unqualifiedNodes = nodes.filter(function (n) { return !isQualified(n); }); - var missingKeyDiagnostics = unqualifiedNodes.map(function (node) { - var missingFields = node.keySequence.nodes - .map(function (n, index) { return ({ field: n, fieldSelector: constraint.fieldSelectors[index] }); }) - .filter(function (x) { return !x.field; }); - var missingFieldPointers = missingFields.map(function (x) { return jp.JSONPath.toPointer(jp.JSONPath.toPathArray(x.fieldSelector)); }); - // remove the leading '/' - var missingFieldRelativePointers = missingFieldPointers.map(function (p) { return p.substring(1); }); - var missingFieldDescription = missingFieldRelativePointers.map(function (p) { return "'".concat(p, "'"); }).join(", "); - var message = missingFieldRelativePointers.length === 1 - ? "property ".concat(missingFieldDescription, " is required") - : "properties ".concat(missingFieldDescription, " are required"); - return { - instancePath: node.contextNode.pointer + node.targetNode.pointer, - keyword: "key", - message: message, - params: { - relationId: constraint.id, - missingProperties: missingFieldPointers - } - }; - }); - var qualifiedNodes = nodes.filter(isQualified); - var uniqueDiagnostics = getUniqueDiagnostics(qualifiedNodes, constraint, "key"); - return missingKeyDiagnostics.concat(uniqueDiagnostics); - }); -} -function isQualified(node) { - return !!node.qualifiedNode && - node.keySequence.nodes.every(function (k) { return k; }) && - node.keySequence.evaluated.every(function (v) { return v !== null; }); -} -function getUniqueDiagnostics(nodes, constraint, keyword) { - // when there is no value, the key is assumed to be a property name - var groups = groupByArray(nodes, function (n) { return n.keySequence.evaluated; }, tupleEquals); - var duplicateGroups = groups.filter(function (_a) { - var values = _a.values; - return values.length > 1; - }); - var duplicateDiagnostics = duplicateGroups.map(function (_a) { - var key = _a.key, nodes = _a.values; - var node = nodes[0]; - var fields = node.keySequence.nodes; - var nodeIsPropertyName = false; - var message; - if (fields.length === 1 && fields[0]) { - var field = fields[0]; - var pointerSegments = node.targetNode.pointer.split('/').concat(field.pointer.split('/')).filter(function (segment) { return segment; }); - var lastSegment = pointerSegments[pointerSegments.length - 1]; - nodeIsPropertyName = lastSegment === node.targetNode.parentProperty; - if (nodeIsPropertyName) { - var parentSegment = pointerSegments[pointerSegments.length - 2]; - message = "duplicate ".concat(parentSegment, " property '").concat(node.targetNode.parentProperty, "', property names in ").concat(parentSegment, " must be unique"); - } - } - if (!message) { - var fieldDescription = toFieldDescription(node.keySequence.nodes); - var keyDescription = toValueDescription(key); - message = "duplicate ".concat(fieldDescription, " ").concat(keyDescription, ", ").concat(fieldDescription, " must be unique"); - } - return { - instancePath: node.contextNode.pointer, - keyword: keyword, - message: message, - params: { - relationId: constraint.id, - duplicateValue: key.length === 1 ? key[0] : key, - duplicates: nodes.map(function (n) { return n.contextNode.pointer + n.targetNode.pointer; }) - } - }; - }); - return duplicateDiagnostics; -} -function collectContexts(obj, constraint) { - var contextNodes = query(obj, constraint.contextNodeSelector); - var nodeInfos = contextNodes - .map(function (contextNode) { - var targetNodes = query(contextNode.value, constraint.selector); - return { - contextNode: contextNode, - nodes: targetNodes.map(function (t) { - var keySequenceNodes = constraint.fieldSelectors.map(function (s) { return queryField(t.value, s); }); - var maybeQualifiedNode = keySequenceNodes.every(function (f) { return f; }) - ? __assign(__assign({}, t), { keySequenceNodes: keySequenceNodes.filter(function (f) { return f !== null; }) }) : null; - return { - contextNode: contextNode, - targetNode: t, - qualifiedNode: maybeQualifiedNode, - keySequence: { - nodes: keySequenceNodes, - evaluated: keySequenceNodes.map(function (n) { return n === null ? null : !n.parentProperty ? t.parentProperty : n.value; }) - } - }; - }) - }; - }); - return nodeInfos; -} -function queryField(obj, fieldSelector) { - var results = jp.JSONPath({ path: fieldSelector, resultType: 'all', json: obj }); - if (results.length > 1) { - // see https://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions - throw new Error("A field selector must identify a single node. \"".concat(fieldSelector, "\" identified ").concat(results.map(function (r) { return r.pointer; }).join(", "), ".")); - } - if (results.length === 1) { - return results[0]; - } - return null; -} -function groupByArray(xs, getKey, keyEquals) { - return xs.reduce(function (rv, x) { - var v = getKey(x); - var el = rv.find(function (r) { return r && keyEquals(r.key, v); }); - if (el) { - el.values.push(x); - } - else { - rv.push({ key: v, values: [x] }); - } - return rv; - }, []); -} -function tupleEquals(t1, t2) { - if (t1.length !== t2.length) { - return false; - } - for (var index = 0; index < t1.length; index++) { - if (t1[index] !== t2[index]) { - return false; - } - } - return true; -} -function toFieldDescription(fields) { - return fields.length === 1 - ? toSingleFieldDescription(fields[0]) - : "composite (".concat(fields.map(function (f) { return toSingleFieldDescription(f); }).join(', '), ")"); -} -function toSingleFieldDescription(field) { - return "'".concat(field.parentProperty, "'"); -} -function toValueDescription(value) { - return value.length === 1 - ? toSingleValueDescription(value[0]) - : "(".concat(value.map(function (k) { return toSingleValueDescription(k); }).join(', '), ")"); -} -function toSingleValueDescription(value) { - return typeof value === 'string' - ? "'".concat(value, "'") - : value; -} -module.exports = { validateMultiFileRels: validateMultiFileRels, validateRels: validateRels }; -//# sourceMappingURL=validateRels.js.map \ No newline at end of file diff --git a/src/built/validateRels.js.map b/src/built/validateRels.js.map deleted file mode 100644 index 97713a3..0000000 --- a/src/built/validateRels.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"validateRels.js","sourceRoot":"","sources":["../validateRels.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..e25c4ce --- /dev/null +++ b/src/index.ts @@ -0,0 +1,47 @@ +#!/usr/bin/env node + +import { validateMultiFileRels } from './validateRels.js' +import { Command } from 'commander' +import fs from 'fs-extra' + +try { + const program = new Command(); + + program + .requiredOption('-r, --root ', 'The root directory for relative paths and globs') + .requiredOption('-s, --settings ', 'The JSON relations definition file') + + program.parse(); + const options = program.opts(); + + const settingsFilePath = (options.settings) + const rootPath = (options.root) + + let relationDefinition + + try { + const relationsFileContent = await fs.readFile(settingsFilePath) + relationDefinition = JSON.parse(relationsFileContent.toString()) + } + catch (error) { + process.exitCode = 1 + console.error(`could not read file ${settingsFilePath}: ${error.message}` ) + } + + if (!(await fs.exists(rootPath))) { + process.exitCode = 1 + console.error(`directory ${rootPath} does not exist`) + } + + const diagnostics = await validateMultiFileRels(rootPath, relationDefinition) + + process.stdout.write(JSON.stringify(diagnostics, null, 2)) + + if (diagnostics.length > 0) { + process.exitCode = 4 + } +} +catch (error) { + console.error(error.message) + process.exitCode = 1 +} \ No newline at end of file diff --git a/src/package-lock.json b/src/package-lock.json index 7637ca0..05d4eaf 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -1,24 +1,44 @@ { - "name": "validate_rels", - "version": "1.0.0", + "name": "json-keyref", + "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "validate_rels", - "version": "1.0.0", + "name": "json-keyref", + "version": "0.0.1", "license": "MIT", "dependencies": { + "commander": "^12.1.0", + "fs-extra": "^11.2.0", "glob": "^10.3.14", - "jsonpath-plus": "^8.1.0" + "jsonpath-plus": "^10.1.0" + }, + "bin": { + "json-keyref": "built/index.js" }, "devDependencies": { - "@types/glob": "^8.1.0", + "@types/fs-extra": "^11.0.4", "@types/jsonpath-plus": "^5.0.5", "@types/node": "^20.12.8", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", "typescript": "^5.4.5" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -35,6 +55,58 @@ "node": ">=12" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@jsep-plugin/assignment": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.2.1.tgz", + "integrity": "sha512-gaHqbubTi29aZpVbBlECRpmdia+L5/lh2BwtIJTmtxdbecEyyX/ejAOg7eQDGNvGOUmPY7Z2Yxdy9ioyH/VJeA==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsep-plugin/regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", + "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -44,13 +116,52 @@ "node": ">=14" } }, - "node_modules/@types/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/fs-extra": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", + "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/jsonfile": "*", + "@types/node": "*" + } + }, + "node_modules/@types/jsonfile": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", + "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/minimatch": "^5.1.2", "@types/node": "*" } }, @@ -60,12 +171,6 @@ "integrity": "sha512-aaqqDf5LcGOtAfEntO5qKZS6ixT0MpNhUXNwbVPdLf7ET9hKsufJq+buZr7eXSnWoLRyGzVj2Yz2hbjVSK3wsA==", "dev": true }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, "node_modules/@types/node": { "version": "20.12.8", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz", @@ -75,6 +180,32 @@ "undici-types": "~5.26.4" } }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -97,6 +228,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -126,6 +264,22 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -139,6 +293,16 @@ "node": ">= 8" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -164,6 +328,20 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/glob": { "version": "10.3.14", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.14.tgz", @@ -185,6 +363,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -215,16 +399,56 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jsep": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.9.tgz", + "integrity": "sha512-i1rBX5N7VPl0eYb6+mHNp52sEuaS2Wi8CDYx1X5sn9naevL78+265XJqy1qENEk7mRKwS06NHpUqiBwR7qeodw==", + "license": "MIT", + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsonpath-plus": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-8.1.0.tgz", - "integrity": "sha512-qVTiuKztFGw0dGhYi3WNqvddx3/SHtyDT0xJaeyz4uP0d1tkpG+0y5uYQ4OcIo1TLAz3PE/qDOW9F0uDt3+CTw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.1.0.tgz", + "integrity": "sha512-gHfV1IYqH8uJHYVTs8BJX1XKy2/rR93+f8QQi0xhx95aCiXn1ettYAd5T+7FU6wfqyDoX/wy0pm/fL3jOKJ9Lg==", + "license": "MIT", + "dependencies": { + "@jsep-plugin/assignment": "^1.2.1", + "@jsep-plugin/regex": "^1.0.3", + "jsep": "^1.3.9" + }, "bin": { "jsonpath": "bin/jsonpath-cli.js", "jsonpath-plus": "bin/jsonpath-cli.js" }, "engines": { - "node": ">=14.0.0" + "node": ">=18.0.0" } }, "node_modules/lru-cache": { @@ -235,6 +459,13 @@ "node": "14 || >=16.14" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, "node_modules/minimatch": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", @@ -249,6 +480,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", @@ -398,6 +639,75 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/typescript": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", @@ -417,6 +727,22 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -514,6 +840,16 @@ "engines": { "node": ">=8" } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } } } } diff --git a/src/package.json b/src/package.json index 2bc7802..be081ec 100644 --- a/src/package.json +++ b/src/package.json @@ -1,22 +1,44 @@ { - "name": "validate_rels", + "name": "json-keyref", + "version": "0.0.1", "type": "module", - "version": "1.0.0", - "description": "Validates relations in JSON documents", - "main": "validate_rels.js", + "description": "Validates relations within one or multiple JSON files, such as key, keyref, uniqueness", + "repository": { + "type": "git", + "url": "git+https://github.com/shuebner/json_keyref.git" + }, + "files": [ + "built/" + ], + "bin": { + "json-keyref": "./built/index.js" + }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "tsc", + "start": "node ./built/index.js" }, - "author": "", + "keywords": [ + "json", + "key", + "keyref", + "unique", + "validation", + "relations" + ], + "author": "Sven Hübner", "license": "MIT", "dependencies": { + "commander": "^12.1.0", + "fs-extra": "^11.2.0", "glob": "^10.3.14", - "jsonpath-plus": "^8.1.0" + "jsonpath-plus": "^10.1.0" }, "devDependencies": { - "@types/glob": "^8.1.0", + "@types/fs-extra": "^11.0.4", "@types/jsonpath-plus": "^5.0.5", "@types/node": "^20.12.8", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", "typescript": "^5.4.5" } } diff --git a/src/tsconfig.json b/src/tsconfig.json index 4a417d7..5ac2a94 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -1,13 +1,18 @@ { "compilerOptions": { "outDir": "./built", - "allowJs": true, - "target": "es5", - "lib": ["es2015"], - "module": "nodenext", + "target": "ES2020", + "lib": ["es2020"], + "esModuleInterop": true, + "module": "ESNext", + "moduleResolution": "Node", "sourceMap": true, "strictNullChecks": true, - "noImplicitAny": true + "noImplicitAny": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, }, "include": ["./**/*"] } \ No newline at end of file diff --git a/src/validateRels.ts b/src/validateRels.ts index 0137667..792dcd4 100644 --- a/src/validateRels.ts +++ b/src/validateRels.ts @@ -1,7 +1,7 @@ import { glob } from 'glob' -import jp = require('jsonpath-plus') -import fs = require('fs') -import path from 'path' +import * as jp from 'jsonpath-plus' +import * as fs from 'fs' +import * as path from 'path' type JSONPathQueryResult = { @@ -93,7 +93,7 @@ type FileContextInfo = { name: string, } -async function validateMultiFileRels(rootFolder: string, relationsSpec: any): Promise { +export async function validateMultiFileRels(rootFolder: string, relationsSpec: any): Promise { const { multiFile: { scope, selector } } = relationsSpec let allDiagnostics = new Array(); @@ -128,7 +128,7 @@ async function validateMultiFileRels(rootFolder: string, relationsSpec: any): Pr return allDiagnostics } -function validateRels(objToValidate: object, relationsSpec: any): Diagnostic[] { +export function validateRels(objToValidate: object, relationsSpec: any): Diagnostic[] { return validateTreeRels([{ fileContextInfo: null, value: objToValidate }], relationsSpec); } @@ -388,7 +388,7 @@ function queryField(obj: any, fieldSelector: string): JSONPathQueryResult | null if (results.length > 1) { // see https://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions - throw new Error(`A field selector must identify a single node. "${fieldSelector}" identified ${results.map(r => r.pointer).join(", ")}.`) + throw new Error(`A field selector must identify a single node. "${fieldSelector}" identified ${results.length} nodes: ${results.map(r => r.pointer).join(", ")}.`) } if (results.length === 1) { @@ -447,6 +447,4 @@ function toSingleValueDescription(value: any[]) { return typeof value === 'string' ? `'${value}'` : value -} - -module.exports = { validateMultiFileRels, validateRels } \ No newline at end of file +} \ No newline at end of file diff --git a/tests/jest.config.js b/tests/jest.config.js index b413e10..6c1e9ae 100644 --- a/tests/jest.config.js +++ b/tests/jest.config.js @@ -1,5 +1,5 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ -module.exports = { +export default { preset: 'ts-jest', testEnvironment: 'node', }; \ No newline at end of file diff --git a/tests/package.json b/tests/package.json index 2f4fb74..45f819f 100644 --- a/tests/package.json +++ b/tests/package.json @@ -6,6 +6,7 @@ "scripts": { "test": "jest" }, + "type": "module", "keywords": [], "author": "", "license": "ISC",