convention_builder 1.4.1 → 1.4.3

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.
@@ -8434,10 +8434,15 @@ var require_schema_utilities = __commonJS({
8434
8434
  Object.assign(sharedObjectSection, acum);
8435
8435
  } else {
8436
8436
  chunks = partialPath.split(/\.|\[|\]/).filter((d) => d.length !== 0);
8437
- let lastAttr = chunks[chunks.length - 1];
8438
- let remainingPath = path.replace(new RegExp(lastAttr.concat("$")), "").replace(/\.$/, "");
8439
- let sharedObjectSection = dig(targetObject, remainingPath);
8440
- sharedObjectSection[lastAttr] = value;
8437
+ let lastAttr = chunks.length == 0 ? chunks[0] : chunks[chunks.length - 1];
8438
+ if (lastAttr) {
8439
+ let remainingPath = path.replace(new RegExp(lastAttr.concat("$")), "").replace(/\.$/, "");
8440
+ let sharedObjectSection = dig(targetObject, remainingPath);
8441
+ sharedObjectSection[lastAttr] = value;
8442
+ } else {
8443
+ targetObject[path] = value;
8444
+ }
8445
+ ;
8441
8446
  }
8442
8447
  ;
8443
8448
  return targetObject;
@@ -8483,7 +8488,6 @@ var require_schema_utilities = __commonJS({
8483
8488
  fs.mkdirSync(`${targetFolder}/${typeKey}/${bundleKey}/`, { recursive: true }, console.error);
8484
8489
  let path = `${targetFolder}/${typeKey}/${bundleKey}/schema.json`;
8485
8490
  fs.writeFileSync(path, JSON.stringify(schema, null, " "));
8486
- console.log(`writing ${typeKey}--${bundleKey}`);
8487
8491
  });
8488
8492
  });
8489
8493
  }
@@ -8539,7 +8543,6 @@ var require_schema_utilities = __commonJS({
8539
8543
  return files;
8540
8544
  }).filter((filename) => !/\./.test(filename));
8541
8545
  conventions.forEach((conventionName) => {
8542
- console.log(`Working on ${conventionName}`);
8543
8546
  try {
8544
8547
  let schema = JSON.parse(fs.readFileSync(`${conventionsFolder}/${conventionName}/schema.json`));
8545
8548
  schemasArgument.schemas.push(schema);
@@ -8774,8 +8777,52 @@ var require_schema_utilities = __commonJS({
8774
8777
  function organizeEntitiesArrayByRelationships({ entitiesArray, conventionObject }) {
8775
8778
  let attributesTree = conventionObject.getAttributesTree();
8776
8779
  let mainAttribute = Object.keys(attributesTree);
8780
+ return {
8781
+ tree: attributesTree
8782
+ };
8777
8783
  }
8778
8784
  __name(organizeEntitiesArrayByRelationships, "organizeEntitiesArrayByRelationships");
8785
+ function arrayToStructuredConvention({ entitiesArray, conventionObject }) {
8786
+ let entities = entitiesArray.map((entity) => {
8787
+ let validations = Object.keys(conventionObject.overlays).map((key) => {
8788
+ var _a;
8789
+ conventionObject.overlays[key].validate(entity);
8790
+ let errors = (_a = conventionObject.overlays[key].validate.errors) == null ? void 0 : _a.filter((d) => !/relationships/.test(d.instancePath));
8791
+ return { overlay: key, errors: errors ? errors : [] };
8792
+ });
8793
+ let passedTests = validations.filter((d) => d.errors.length == 0);
8794
+ let amountPassed = passedTests.length;
8795
+ let output2 = {
8796
+ passedTests,
8797
+ possibleOverlays: passedTests ? passedTests.map((d) => d.overlay) : void 0,
8798
+ allTests: validations,
8799
+ amountPassed,
8800
+ entity
8801
+ };
8802
+ return output2;
8803
+ });
8804
+ let output = {
8805
+ identifiedEntities: entities.filter((d) => d.amountPassed == 1),
8806
+ unrecognizedEntities: entities.filter((d) => d.amountPassed == 0),
8807
+ ambiguousEntities: entities.filter((d) => d.amountPassed > 1)
8808
+ };
8809
+ let assembledEntity = {
8810
+ id: randomUUID(),
8811
+ type: "object"
8812
+ };
8813
+ entities.filter((d) => d.possibleOverlays.length == 1).forEach((entityObj) => {
8814
+ assembledEntity[entityObj.possibleOverlays[0]] = entityObj.entity;
8815
+ });
8816
+ let assembledValidation = conventionObject.validate(assembledEntity);
8817
+ if (conventionObject.validate.errors) {
8818
+ output.errors = conventionObject.validate.errors;
8819
+ }
8820
+ ;
8821
+ output.is_valid = assembledValidation;
8822
+ output.assembled_entity = assembledEntity;
8823
+ return output;
8824
+ }
8825
+ __name(arrayToStructuredConvention, "arrayToStructuredConvention");
8779
8826
  function trimNonRequiredFields(schema, attribute = false) {
8780
8827
  let data;
8781
8828
  if (attribute) {
@@ -8934,7 +8981,14 @@ var require_schema_utilities = __commonJS({
8934
8981
  let schema = schemataTree[typeKey][bundleKey];
8935
8982
  let topLevelAttributes = new Set(Object.keys(schema.properties.attributes.properties));
8936
8983
  let objectTypeAttributes = Array.from(topLevelAttributes).filter((attr) => schema.properties.attributes.properties[attr].type == "object");
8937
- objectTypeAttributes.forEach((attr) => {
8984
+ objectTypeAttributes.flatMap((objAttr) => {
8985
+ let output2 = [];
8986
+ let subAttrs = Object.keys(schema.properties.attributes.properties[objAttr].properties);
8987
+ subAttrs.forEach((subAttr) => {
8988
+ output2.push(`${objAttr}.properties.${subAttr}`);
8989
+ });
8990
+ return output2;
8991
+ }).forEach((attr) => {
8938
8992
  let entry = output.find((attrDescription) => attrDescription.attribute == attr);
8939
8993
  if (entry) {
8940
8994
  entry.instances.push(
@@ -8962,6 +9016,42 @@ var require_schema_utilities = __commonJS({
8962
9016
  return output;
8963
9017
  }
8964
9018
  __name(findAllObjectAttributesInTree, "findAllObjectAttributesInTree");
9019
+ function findAllNonObjectAttributesInTree(schemataTree) {
9020
+ let output = [];
9021
+ Object.keys(schemataTree).forEach((typeKey) => {
9022
+ Object.keys(schemataTree[typeKey]).forEach((bundleKey) => {
9023
+ let schema = schemataTree[typeKey][bundleKey];
9024
+ let topLevelAttributes = new Set(Object.keys(schema.properties.attributes.properties));
9025
+ let objectTypeAttributes = Array.from(topLevelAttributes).filter((attr) => schema.properties.attributes.properties[attr].type == "object");
9026
+ let otherAttributes = Array.from(topLevelAttributes).filter((attr) => !objectTypeAttributes.includes(attr));
9027
+ otherAttributes.forEach((attr) => {
9028
+ let entry = output.find((attrDescription) => attrDescription.attribute == attr);
9029
+ if (entry) {
9030
+ entry.instances.push(
9031
+ {
9032
+ type: typeKey,
9033
+ bundle: bundleKey,
9034
+ schema: `${typeKey}--${bundleKey}`
9035
+ }
9036
+ );
9037
+ } else {
9038
+ output.push({
9039
+ attribute: attr,
9040
+ instances: [
9041
+ {
9042
+ type: typeKey,
9043
+ bundle: bundleKey,
9044
+ schema: `${typeKey}--${bundleKey}`
9045
+ }
9046
+ ]
9047
+ });
9048
+ }
9049
+ });
9050
+ });
9051
+ });
9052
+ return output;
9053
+ }
9054
+ __name(findAllNonObjectAttributesInTree, "findAllNonObjectAttributesInTree");
8965
9055
  exports.dig = dig;
8966
9056
  exports.bury = bury;
8967
9057
  exports.fixRelationshipDataField = fixRelationshipDataField;
@@ -8976,12 +9066,14 @@ var require_schema_utilities = __commonJS({
8976
9066
  exports.findMissingEntitiesInExample = findMissingEntitiesInExample;
8977
9067
  exports.organizeEntitiesArrayIntoConvention = organizeEntitiesArrayIntoConvention;
8978
9068
  exports.organizeEntitiesArrayByRelationships = organizeEntitiesArrayByRelationships;
9069
+ exports.arrayToStructuredConvention = arrayToStructuredConvention;
8979
9070
  exports.trimNonRequiredFields = trimNonRequiredFields;
8980
9071
  exports.reduceSchemaToRequiredFields = reduceSchemaToRequiredFields;
8981
9072
  exports.flattenObjectBranch = flattenObjectBranch;
8982
9073
  exports.flattenJSONSchema = flattenJSONSchema;
8983
9074
  exports.listAttributesAndSubAttributes = listAttributesAndSubAttributes;
8984
9075
  exports.findAllObjectAttributesInTree = findAllObjectAttributesInTree;
9076
+ exports.findAllNonObjectAttributesInTree = findAllNonObjectAttributesInTree;
8985
9077
  }
8986
9078
  });
8987
9079
 
@@ -8989,7 +9081,15 @@ var require_schema_utilities = __commonJS({
8989
9081
  var require_convention_builder = __commonJS({
8990
9082
  "src/convention_builder.js"(exports) {
8991
9083
  var fs = __require("fs");
8992
- var { buildValidator, urlToStringPair, dig, bury, listAttributesAndSubAttributes } = require_schema_utilities();
9084
+ var {
9085
+ buildValidator,
9086
+ urlToStringPair,
9087
+ dig,
9088
+ bury,
9089
+ listAttributesAndSubAttributes,
9090
+ findAllObjectAttributesInTree,
9091
+ findAllNonObjectAttributesInTree
9092
+ } = require_schema_utilities();
8993
9093
  function getAttributes(root, convention) {
8994
9094
  let branches = convention.relationships.filter((rel) => rel.containerEntity == root).map((d) => d.mentionedEntity);
8995
9095
  let output = {};
@@ -9010,7 +9110,8 @@ var require_convention_builder = __commonJS({
9010
9110
  originalSrcScript,
9011
9111
  trivial = false,
9012
9112
  baseSchemataFolder = `${__dirname}/../../../../input/collection`,
9013
- requiredFields = []
9113
+ requiredFields = [],
9114
+ modifiedAttributes
9014
9115
  }) {
9015
9116
  this.name = name;
9016
9117
  this.typeAndBundle = typeAndBundle;
@@ -9045,7 +9146,7 @@ var require_convention_builder = __commonJS({
9045
9146
  ;
9046
9147
  this.baseSchema = baseSchema;
9047
9148
  this.unmodifiedAttributes = listAttributesAndSubAttributes(this.baseSchema);
9048
- this.modifiedAttributes = /* @__PURE__ */ new Set([]);
9149
+ this.modifiedAttributes = modifiedAttributes ? modifiedAttributes : /* @__PURE__ */ new Set([]);
9049
9150
  if (!overlay) {
9050
9151
  this.overlay = {
9051
9152
  properties: {
@@ -9061,11 +9162,17 @@ var require_convention_builder = __commonJS({
9061
9162
  this.schema = baseSchema;
9062
9163
  let validatorObj = buildValidator();
9063
9164
  this.validate = validatorObj.compile(this.schema);
9064
- this.updateSchema();
9065
9165
  }
9066
9166
  storagePath() {
9067
9167
  return `${this.storageFolder}`;
9068
9168
  }
9169
+ /**
9170
+ * Given an attribute path (such as "attributes.properties.geometry.properties.value"), it will set is as required in the adequate containing attribute (for this example, "attributes.properties.geometry.required").
9171
+ * @param {string} path -- Attribute path.
9172
+ * @returns {}
9173
+ */
9174
+ requireFieldByPath(path) {
9175
+ }
9069
9176
  /**
9070
9177
  * User input only works over the overlay, the schema should always be the direct result of applying the overlay over the baseSchema.
9071
9178
  */
@@ -9075,9 +9182,11 @@ var require_convention_builder = __commonJS({
9075
9182
  Object.assign(this.schema, this.baseSchema);
9076
9183
  let allModifiedAttributes = listAttributesAndSubAttributes(this.overlay);
9077
9184
  this.modifiedAttributes = allModifiedAttributes;
9185
+ this.unmodifiedAttributes = listAttributesAndSubAttributes(this.baseSchema);
9186
+ this.modifiedAttributes.forEach((attr) => this.updateAttributeStatus(attr));
9078
9187
  Array.from(this.modifiedAttributes).forEach((attr) => {
9079
9188
  let currentValue = dig(this.overlay.properties.attributes.properties, attr);
9080
- bury(this.schema, `properties.attributes.properties.${attr}`, currentValue, true);
9189
+ bury(this.schema, `properties.attributes.properties.${attr}`, currentValue, false);
9081
9190
  });
9082
9191
  let originalRequiredFields = this.schema.properties.attributes.required ? this.schema.properties.attributes.required : [];
9083
9192
  let allRequiredSet = Array.from(/* @__PURE__ */ new Set([...originalRequiredFields, ...Array.from(this.requiredFields)]));
@@ -9119,12 +9228,18 @@ var require_convention_builder = __commonJS({
9119
9228
  this.requiredFields.add(attribute);
9120
9229
  this.updateSchema();
9121
9230
  }
9122
- setGenericSection({ attribute, section, description }) {
9231
+ /**
9232
+ * The section body "section" will replace the previous schema content in full.
9233
+ * @param {} attribute
9234
+ * @param {} section
9235
+ * @param {} description
9236
+ */
9237
+ setGenericSection({ attribute, section, description, merge = true }) {
9123
9238
  this.checkAttributeStatus(attribute);
9124
- bury(this.overlay.properties.attributes.properties, attribute, section, true);
9239
+ bury(this.overlay.properties.attributes.properties, attribute, section, merge);
9125
9240
  if (attribute.match(/\./)) {
9126
9241
  let firstLevel = attribute.split(/\./)[0];
9127
- this.overlay.properties.attributes.properties[firstLevel].type = "object";
9242
+ bury(this.overlay.properties.attributes.properties, `${firstLevel}.type`, "object", merge);
9128
9243
  }
9129
9244
  ;
9130
9245
  if (description) {
@@ -9261,6 +9376,42 @@ var require_convention_builder = __commonJS({
9261
9376
  };
9262
9377
  __name(_SchemaOverlay, "SchemaOverlay");
9263
9378
  var SchemaOverlay = _SchemaOverlay;
9379
+ var _AttributePatchingSchemaOverlay = class _AttributePatchingSchemaOverlay extends SchemaOverlay {
9380
+ constructor({
9381
+ typeAndBundle,
9382
+ attributeOverlayName,
9383
+ repoURL,
9384
+ strictEnums = true,
9385
+ baseSchemataFolder = `${__dirname}/../../../../input/collection`
9386
+ }) {
9387
+ super({
9388
+ typeAndBundle,
9389
+ repoURL,
9390
+ storageFolder: baseSchemataFolder,
9391
+ baseSchemataFolder,
9392
+ strictEnums
9393
+ });
9394
+ this.attributeOverlayName = attributeOverlayName;
9395
+ }
9396
+ store() {
9397
+ this.updateSchema();
9398
+ if (this.schema.appliedOverlays) {
9399
+ this.schema.appliedOverlays.push(this.attributeOverlayName);
9400
+ } else {
9401
+ this.schema.appliedOverlays = [this.attributeOverlayName];
9402
+ }
9403
+ ;
9404
+ let targetPath = `${this.storagePath()}/${this.typeAndBundle.split("--")[0]}/${this.typeAndBundle.split("--")[1]}/schema.json`;
9405
+ fs.writeFileSync(targetPath, JSON.stringify(this.schema, null, " "), console.error);
9406
+ let output = {
9407
+ path: targetPath,
9408
+ test: false
9409
+ };
9410
+ return output;
9411
+ }
9412
+ };
9413
+ __name(_AttributePatchingSchemaOverlay, "AttributePatchingSchemaOverlay");
9414
+ var AttributePatchingSchemaOverlay = _AttributePatchingSchemaOverlay;
9264
9415
  var _ConventionSchema = class _ConventionSchema {
9265
9416
  constructor({
9266
9417
  title,
@@ -9296,7 +9447,10 @@ var require_convention_builder = __commonJS({
9296
9447
  if (overlays) {
9297
9448
  let overlayNames = Object.keys(overlays);
9298
9449
  this.overlays = {};
9299
- overlayNames.forEach((ovrl) => this.overlays[ovrl] = new SchemaOverlay(overlays[ovrl]));
9450
+ overlayNames.forEach((ovrl) => {
9451
+ this.overlays[ovrl] = new SchemaOverlay(overlays[ovrl]);
9452
+ this.overlays[ovrl].updateSchema();
9453
+ });
9300
9454
  }
9301
9455
  ;
9302
9456
  if (relationships) {
@@ -9372,6 +9526,7 @@ var require_convention_builder = __commonJS({
9372
9526
  required: this.required
9373
9527
  };
9374
9528
  Object.keys(this.overlays).forEach((attributeName) => {
9529
+ this.overlays[attributeName].updateSchema();
9375
9530
  this.schema.properties[attributeName] = this.overlays[attributeName].schema;
9376
9531
  delete this.schema.properties[attributeName].$id;
9377
9532
  if (!this.overlays[attributeName].originalSrcScript) {
@@ -9705,17 +9860,121 @@ import TabItem from '@theme/TabItem';
9705
9860
  };
9706
9861
  __name(_ConventionSchema, "ConventionSchema");
9707
9862
  var ConventionSchema = _ConventionSchema;
9863
+ var _AttributeOverlay = class _AttributeOverlay {
9864
+ constructor({
9865
+ type,
9866
+ bundle,
9867
+ attribute,
9868
+ baseSchemataFolder = `${__dirname}/../../../../input/collection`,
9869
+ sourceSchemataFile = `${__dirname}/../../../../input/farmos.json`,
9870
+ overlayName,
9871
+ overlayDescription
9872
+ }) {
9873
+ let integralSchemataFile = JSON.parse(fs.readFileSync(sourceSchemataFile));
9874
+ this.type = type;
9875
+ this.bundle = bundle;
9876
+ this.overlayName = overlayName;
9877
+ this.overlayDescription = overlayDescription;
9878
+ this.attribute = attribute;
9879
+ this.sourceSchemata = integralSchemataFile;
9880
+ this.lexicon = [...findAllObjectAttributesInTree(this.sourceSchemata), ...findAllNonObjectAttributesInTree(this.sourceSchemata)];
9881
+ this.baseSchemataFolder = baseSchemataFolder;
9882
+ let involvedSchemata = this.lexicon.filter((entry) => this.attribute == entry.attribute).flatMap((entry) => entry.instances).filter((instance) => this.type ? instance.type == this.type : true).filter((instance) => this.bundle ? instance.bundle == this.bundle : true).map((d) => d.schema);
9883
+ this.targetSchemata = Array.from(new Set(involvedSchemata));
9884
+ this.overlays = [];
9885
+ this.targetSchemata.forEach((target) => {
9886
+ let currentOverlay = new AttributePatchingSchemaOverlay({
9887
+ typeAndBundle: target,
9888
+ attributeOverlayName: this.overlayName,
9889
+ baseSchemataFolder: this.baseSchemataFolder
9890
+ });
9891
+ this.overlays.push(currentOverlay);
9892
+ });
9893
+ }
9894
+ setRequire() {
9895
+ this.overlays.forEach((overlay) => {
9896
+ overlay.setRequiredAttribute(this.attribute);
9897
+ });
9898
+ }
9899
+ setGenericSection({
9900
+ section,
9901
+ description
9902
+ }) {
9903
+ this.overlays.forEach((overlay) => {
9904
+ overlay.setGenericSection({
9905
+ attribute: this.attribute,
9906
+ section,
9907
+ description,
9908
+ merge: false
9909
+ });
9910
+ });
9911
+ }
9912
+ setPattern({ pattern, string, description }) {
9913
+ this.overlays.forEach((overlay) => {
9914
+ overlay.setPattern({
9915
+ attribute: this.attribute,
9916
+ pattern,
9917
+ string,
9918
+ description
9919
+ });
9920
+ });
9921
+ }
9922
+ /**
9923
+ * An all involved schemata, sets the target attribute for this overlay as a constant as indicated by the given value.
9924
+ * @param {any} value -- The constant, which should be of the type allowed by the base schema for the attribute.
9925
+ * @param {string} description -- Describes the rationale behind the chosing of the value.
9926
+ */
9927
+ setConstant({ value, description }) {
9928
+ this.overlays.forEach((overlay) => {
9929
+ overlay.setConstant({
9930
+ attribute: this.attribute,
9931
+ value,
9932
+ description
9933
+ });
9934
+ });
9935
+ }
9936
+ /**
9937
+ * Sets this overlay's target attribute as a constrained to a list of possible values in all involved schemata.
9938
+ * @param {string} attribute -- Attribute name for the attribute which will be set to a constant.
9939
+ * @param {any[]} valuesArray -- The array of possible values, which should be of the type allowed by the base schema for the attribute.
9940
+ * @param {string} description -- Describes the rationale behind the chosing of the value.
9941
+ */
9942
+ setEnum({ valuesArray, description }) {
9943
+ this.overlays.forEach((overlay) => {
9944
+ overlay.setConstant({
9945
+ attribute: this.attribute,
9946
+ valuesArray,
9947
+ description
9948
+ });
9949
+ });
9950
+ }
9951
+ /**
9952
+ * Stores all involved schemas into the folder structure for `base schemata` (provided as the parameter `baseSchemataFolder`) which will be consumed by our conventions later.
9953
+ * @returns {} -- It returns objects containing all paths.
9954
+ */
9955
+ store() {
9956
+ let output = this.overlays.map((overlay) => {
9957
+ let operation = overlay.store();
9958
+ return operation;
9959
+ });
9960
+ return output;
9961
+ }
9962
+ };
9963
+ __name(_AttributeOverlay, "AttributeOverlay");
9964
+ var AttributeOverlay = _AttributeOverlay;
9708
9965
  exports.SchemaOverlay = SchemaOverlay;
9709
9966
  exports.ConventionSchema = ConventionSchema;
9967
+ exports.AttributeOverlay = AttributeOverlay;
9710
9968
  }
9711
9969
  });
9712
9970
 
9713
9971
  // src/index.js
9714
9972
  var require_src = __commonJS({
9715
9973
  "src/index.js"(exports) {
9716
- var { SchemaOverlay, ConventionSchema } = require_convention_builder();
9974
+ var { SchemaOverlay, ConventionSchema, AttributeOverlay } = require_convention_builder();
9717
9975
  var schemaUtils = require_schema_utilities();
9718
9976
  exports.SchemaOverlay = SchemaOverlay;
9977
+ exports.AttributeOverlay = AttributeOverlay;
9719
9978
  exports.ConventionSchema = ConventionSchema;
9720
9979
  exports.fixRelationshipDataField = schemaUtils.fixRelationshipDataField;
9721
9980
  exports.buildValidator = schemaUtils.buildValidator;
@@ -9728,7 +9987,7 @@ var require_src = __commonJS({
9728
9987
  exports.exampleImporter = schemaUtils.exampleImporter;
9729
9988
  exports.findMissingEntitiesInExample = schemaUtils.findMissingEntitiesInExample;
9730
9989
  exports.organizeEntitiesArrayIntoConvention = schemaUtils.organizeEntitiesArrayIntoConvention;
9731
- exports.organizeEntitiesArrayByRelationships = schemaUtils.organizeEntitiesArrayByRelationships;
9990
+ exports.arrayToStructuredConvention = schemaUtils.arrayToStructuredConvention;
9732
9991
  exports.trimNonRequiredFields = schemaUtils.trimNonRequiredFields;
9733
9992
  exports.reduceSchemaToRequiredFields = schemaUtils.reduceSchemaToRequiredFields;
9734
9993
  exports.flattenJSONSchema = schemaUtils.flattenJSONSchema;
@@ -8427,10 +8427,15 @@ var require_schema_utilities = __commonJS({
8427
8427
  Object.assign(sharedObjectSection, acum);
8428
8428
  } else {
8429
8429
  chunks = partialPath.split(/\.|\[|\]/).filter((d) => d.length !== 0);
8430
- let lastAttr = chunks[chunks.length - 1];
8431
- let remainingPath = path.replace(new RegExp(lastAttr.concat("$")), "").replace(/\.$/, "");
8432
- let sharedObjectSection = dig(targetObject, remainingPath);
8433
- sharedObjectSection[lastAttr] = value;
8430
+ let lastAttr = chunks.length == 0 ? chunks[0] : chunks[chunks.length - 1];
8431
+ if (lastAttr) {
8432
+ let remainingPath = path.replace(new RegExp(lastAttr.concat("$")), "").replace(/\.$/, "");
8433
+ let sharedObjectSection = dig(targetObject, remainingPath);
8434
+ sharedObjectSection[lastAttr] = value;
8435
+ } else {
8436
+ targetObject[path] = value;
8437
+ }
8438
+ ;
8434
8439
  }
8435
8440
  ;
8436
8441
  return targetObject;
@@ -8476,7 +8481,6 @@ var require_schema_utilities = __commonJS({
8476
8481
  fs.mkdirSync(`${targetFolder}/${typeKey}/${bundleKey}/`, { recursive: true }, console.error);
8477
8482
  let path = `${targetFolder}/${typeKey}/${bundleKey}/schema.json`;
8478
8483
  fs.writeFileSync(path, JSON.stringify(schema, null, " "));
8479
- console.log(`writing ${typeKey}--${bundleKey}`);
8480
8484
  });
8481
8485
  });
8482
8486
  }
@@ -8532,7 +8536,6 @@ var require_schema_utilities = __commonJS({
8532
8536
  return files;
8533
8537
  }).filter((filename) => !/\./.test(filename));
8534
8538
  conventions.forEach((conventionName) => {
8535
- console.log(`Working on ${conventionName}`);
8536
8539
  try {
8537
8540
  let schema = JSON.parse(fs.readFileSync(`${conventionsFolder}/${conventionName}/schema.json`));
8538
8541
  schemasArgument.schemas.push(schema);
@@ -8767,8 +8770,52 @@ var require_schema_utilities = __commonJS({
8767
8770
  function organizeEntitiesArrayByRelationships({ entitiesArray, conventionObject }) {
8768
8771
  let attributesTree = conventionObject.getAttributesTree();
8769
8772
  let mainAttribute = Object.keys(attributesTree);
8773
+ return {
8774
+ tree: attributesTree
8775
+ };
8770
8776
  }
8771
8777
  __name(organizeEntitiesArrayByRelationships, "organizeEntitiesArrayByRelationships");
8778
+ function arrayToStructuredConvention({ entitiesArray, conventionObject }) {
8779
+ let entities = entitiesArray.map((entity) => {
8780
+ let validations = Object.keys(conventionObject.overlays).map((key) => {
8781
+ var _a;
8782
+ conventionObject.overlays[key].validate(entity);
8783
+ let errors = (_a = conventionObject.overlays[key].validate.errors) == null ? void 0 : _a.filter((d) => !/relationships/.test(d.instancePath));
8784
+ return { overlay: key, errors: errors ? errors : [] };
8785
+ });
8786
+ let passedTests = validations.filter((d) => d.errors.length == 0);
8787
+ let amountPassed = passedTests.length;
8788
+ let output2 = {
8789
+ passedTests,
8790
+ possibleOverlays: passedTests ? passedTests.map((d) => d.overlay) : void 0,
8791
+ allTests: validations,
8792
+ amountPassed,
8793
+ entity
8794
+ };
8795
+ return output2;
8796
+ });
8797
+ let output = {
8798
+ identifiedEntities: entities.filter((d) => d.amountPassed == 1),
8799
+ unrecognizedEntities: entities.filter((d) => d.amountPassed == 0),
8800
+ ambiguousEntities: entities.filter((d) => d.amountPassed > 1)
8801
+ };
8802
+ let assembledEntity = {
8803
+ id: randomUUID(),
8804
+ type: "object"
8805
+ };
8806
+ entities.filter((d) => d.possibleOverlays.length == 1).forEach((entityObj) => {
8807
+ assembledEntity[entityObj.possibleOverlays[0]] = entityObj.entity;
8808
+ });
8809
+ let assembledValidation = conventionObject.validate(assembledEntity);
8810
+ if (conventionObject.validate.errors) {
8811
+ output.errors = conventionObject.validate.errors;
8812
+ }
8813
+ ;
8814
+ output.is_valid = assembledValidation;
8815
+ output.assembled_entity = assembledEntity;
8816
+ return output;
8817
+ }
8818
+ __name(arrayToStructuredConvention, "arrayToStructuredConvention");
8772
8819
  function trimNonRequiredFields(schema, attribute = false) {
8773
8820
  let data;
8774
8821
  if (attribute) {
@@ -8927,7 +8974,14 @@ var require_schema_utilities = __commonJS({
8927
8974
  let schema = schemataTree[typeKey][bundleKey];
8928
8975
  let topLevelAttributes = new Set(Object.keys(schema.properties.attributes.properties));
8929
8976
  let objectTypeAttributes = Array.from(topLevelAttributes).filter((attr) => schema.properties.attributes.properties[attr].type == "object");
8930
- objectTypeAttributes.forEach((attr) => {
8977
+ objectTypeAttributes.flatMap((objAttr) => {
8978
+ let output2 = [];
8979
+ let subAttrs = Object.keys(schema.properties.attributes.properties[objAttr].properties);
8980
+ subAttrs.forEach((subAttr) => {
8981
+ output2.push(`${objAttr}.properties.${subAttr}`);
8982
+ });
8983
+ return output2;
8984
+ }).forEach((attr) => {
8931
8985
  let entry = output.find((attrDescription) => attrDescription.attribute == attr);
8932
8986
  if (entry) {
8933
8987
  entry.instances.push(
@@ -8955,6 +9009,42 @@ var require_schema_utilities = __commonJS({
8955
9009
  return output;
8956
9010
  }
8957
9011
  __name(findAllObjectAttributesInTree, "findAllObjectAttributesInTree");
9012
+ function findAllNonObjectAttributesInTree(schemataTree) {
9013
+ let output = [];
9014
+ Object.keys(schemataTree).forEach((typeKey) => {
9015
+ Object.keys(schemataTree[typeKey]).forEach((bundleKey) => {
9016
+ let schema = schemataTree[typeKey][bundleKey];
9017
+ let topLevelAttributes = new Set(Object.keys(schema.properties.attributes.properties));
9018
+ let objectTypeAttributes = Array.from(topLevelAttributes).filter((attr) => schema.properties.attributes.properties[attr].type == "object");
9019
+ let otherAttributes = Array.from(topLevelAttributes).filter((attr) => !objectTypeAttributes.includes(attr));
9020
+ otherAttributes.forEach((attr) => {
9021
+ let entry = output.find((attrDescription) => attrDescription.attribute == attr);
9022
+ if (entry) {
9023
+ entry.instances.push(
9024
+ {
9025
+ type: typeKey,
9026
+ bundle: bundleKey,
9027
+ schema: `${typeKey}--${bundleKey}`
9028
+ }
9029
+ );
9030
+ } else {
9031
+ output.push({
9032
+ attribute: attr,
9033
+ instances: [
9034
+ {
9035
+ type: typeKey,
9036
+ bundle: bundleKey,
9037
+ schema: `${typeKey}--${bundleKey}`
9038
+ }
9039
+ ]
9040
+ });
9041
+ }
9042
+ });
9043
+ });
9044
+ });
9045
+ return output;
9046
+ }
9047
+ __name(findAllNonObjectAttributesInTree, "findAllNonObjectAttributesInTree");
8958
9048
  exports2.dig = dig;
8959
9049
  exports2.bury = bury;
8960
9050
  exports2.fixRelationshipDataField = fixRelationshipDataField;
@@ -8969,12 +9059,14 @@ var require_schema_utilities = __commonJS({
8969
9059
  exports2.findMissingEntitiesInExample = findMissingEntitiesInExample;
8970
9060
  exports2.organizeEntitiesArrayIntoConvention = organizeEntitiesArrayIntoConvention;
8971
9061
  exports2.organizeEntitiesArrayByRelationships = organizeEntitiesArrayByRelationships;
9062
+ exports2.arrayToStructuredConvention = arrayToStructuredConvention;
8972
9063
  exports2.trimNonRequiredFields = trimNonRequiredFields;
8973
9064
  exports2.reduceSchemaToRequiredFields = reduceSchemaToRequiredFields;
8974
9065
  exports2.flattenObjectBranch = flattenObjectBranch;
8975
9066
  exports2.flattenJSONSchema = flattenJSONSchema;
8976
9067
  exports2.listAttributesAndSubAttributes = listAttributesAndSubAttributes;
8977
9068
  exports2.findAllObjectAttributesInTree = findAllObjectAttributesInTree;
9069
+ exports2.findAllNonObjectAttributesInTree = findAllNonObjectAttributesInTree;
8978
9070
  }
8979
9071
  });
8980
9072
 
@@ -8982,7 +9074,15 @@ var require_schema_utilities = __commonJS({
8982
9074
  var require_convention_builder = __commonJS({
8983
9075
  "src/convention_builder.js"(exports2) {
8984
9076
  var fs = require("fs");
8985
- var { buildValidator, urlToStringPair, dig, bury, listAttributesAndSubAttributes } = require_schema_utilities();
9077
+ var {
9078
+ buildValidator,
9079
+ urlToStringPair,
9080
+ dig,
9081
+ bury,
9082
+ listAttributesAndSubAttributes,
9083
+ findAllObjectAttributesInTree,
9084
+ findAllNonObjectAttributesInTree
9085
+ } = require_schema_utilities();
8986
9086
  function getAttributes(root, convention) {
8987
9087
  let branches = convention.relationships.filter((rel) => rel.containerEntity == root).map((d) => d.mentionedEntity);
8988
9088
  let output = {};
@@ -9003,7 +9103,8 @@ var require_convention_builder = __commonJS({
9003
9103
  originalSrcScript,
9004
9104
  trivial = false,
9005
9105
  baseSchemataFolder = `${__dirname}/../../../../input/collection`,
9006
- requiredFields = []
9106
+ requiredFields = [],
9107
+ modifiedAttributes
9007
9108
  }) {
9008
9109
  this.name = name;
9009
9110
  this.typeAndBundle = typeAndBundle;
@@ -9038,7 +9139,7 @@ var require_convention_builder = __commonJS({
9038
9139
  ;
9039
9140
  this.baseSchema = baseSchema;
9040
9141
  this.unmodifiedAttributes = listAttributesAndSubAttributes(this.baseSchema);
9041
- this.modifiedAttributes = /* @__PURE__ */ new Set([]);
9142
+ this.modifiedAttributes = modifiedAttributes ? modifiedAttributes : /* @__PURE__ */ new Set([]);
9042
9143
  if (!overlay) {
9043
9144
  this.overlay = {
9044
9145
  properties: {
@@ -9054,11 +9155,17 @@ var require_convention_builder = __commonJS({
9054
9155
  this.schema = baseSchema;
9055
9156
  let validatorObj = buildValidator();
9056
9157
  this.validate = validatorObj.compile(this.schema);
9057
- this.updateSchema();
9058
9158
  }
9059
9159
  storagePath() {
9060
9160
  return `${this.storageFolder}`;
9061
9161
  }
9162
+ /**
9163
+ * Given an attribute path (such as "attributes.properties.geometry.properties.value"), it will set is as required in the adequate containing attribute (for this example, "attributes.properties.geometry.required").
9164
+ * @param {string} path -- Attribute path.
9165
+ * @returns {}
9166
+ */
9167
+ requireFieldByPath(path) {
9168
+ }
9062
9169
  /**
9063
9170
  * User input only works over the overlay, the schema should always be the direct result of applying the overlay over the baseSchema.
9064
9171
  */
@@ -9068,9 +9175,11 @@ var require_convention_builder = __commonJS({
9068
9175
  Object.assign(this.schema, this.baseSchema);
9069
9176
  let allModifiedAttributes = listAttributesAndSubAttributes(this.overlay);
9070
9177
  this.modifiedAttributes = allModifiedAttributes;
9178
+ this.unmodifiedAttributes = listAttributesAndSubAttributes(this.baseSchema);
9179
+ this.modifiedAttributes.forEach((attr) => this.updateAttributeStatus(attr));
9071
9180
  Array.from(this.modifiedAttributes).forEach((attr) => {
9072
9181
  let currentValue = dig(this.overlay.properties.attributes.properties, attr);
9073
- bury(this.schema, `properties.attributes.properties.${attr}`, currentValue, true);
9182
+ bury(this.schema, `properties.attributes.properties.${attr}`, currentValue, false);
9074
9183
  });
9075
9184
  let originalRequiredFields = this.schema.properties.attributes.required ? this.schema.properties.attributes.required : [];
9076
9185
  let allRequiredSet = Array.from(/* @__PURE__ */ new Set([...originalRequiredFields, ...Array.from(this.requiredFields)]));
@@ -9112,12 +9221,18 @@ var require_convention_builder = __commonJS({
9112
9221
  this.requiredFields.add(attribute);
9113
9222
  this.updateSchema();
9114
9223
  }
9115
- setGenericSection({ attribute, section, description }) {
9224
+ /**
9225
+ * The section body "section" will replace the previous schema content in full.
9226
+ * @param {} attribute
9227
+ * @param {} section
9228
+ * @param {} description
9229
+ */
9230
+ setGenericSection({ attribute, section, description, merge = true }) {
9116
9231
  this.checkAttributeStatus(attribute);
9117
- bury(this.overlay.properties.attributes.properties, attribute, section, true);
9232
+ bury(this.overlay.properties.attributes.properties, attribute, section, merge);
9118
9233
  if (attribute.match(/\./)) {
9119
9234
  let firstLevel = attribute.split(/\./)[0];
9120
- this.overlay.properties.attributes.properties[firstLevel].type = "object";
9235
+ bury(this.overlay.properties.attributes.properties, `${firstLevel}.type`, "object", merge);
9121
9236
  }
9122
9237
  ;
9123
9238
  if (description) {
@@ -9254,6 +9369,42 @@ var require_convention_builder = __commonJS({
9254
9369
  };
9255
9370
  __name(_SchemaOverlay, "SchemaOverlay");
9256
9371
  var SchemaOverlay2 = _SchemaOverlay;
9372
+ var _AttributePatchingSchemaOverlay = class _AttributePatchingSchemaOverlay extends SchemaOverlay2 {
9373
+ constructor({
9374
+ typeAndBundle,
9375
+ attributeOverlayName,
9376
+ repoURL,
9377
+ strictEnums = true,
9378
+ baseSchemataFolder = `${__dirname}/../../../../input/collection`
9379
+ }) {
9380
+ super({
9381
+ typeAndBundle,
9382
+ repoURL,
9383
+ storageFolder: baseSchemataFolder,
9384
+ baseSchemataFolder,
9385
+ strictEnums
9386
+ });
9387
+ this.attributeOverlayName = attributeOverlayName;
9388
+ }
9389
+ store() {
9390
+ this.updateSchema();
9391
+ if (this.schema.appliedOverlays) {
9392
+ this.schema.appliedOverlays.push(this.attributeOverlayName);
9393
+ } else {
9394
+ this.schema.appliedOverlays = [this.attributeOverlayName];
9395
+ }
9396
+ ;
9397
+ let targetPath = `${this.storagePath()}/${this.typeAndBundle.split("--")[0]}/${this.typeAndBundle.split("--")[1]}/schema.json`;
9398
+ fs.writeFileSync(targetPath, JSON.stringify(this.schema, null, " "), console.error);
9399
+ let output = {
9400
+ path: targetPath,
9401
+ test: false
9402
+ };
9403
+ return output;
9404
+ }
9405
+ };
9406
+ __name(_AttributePatchingSchemaOverlay, "AttributePatchingSchemaOverlay");
9407
+ var AttributePatchingSchemaOverlay = _AttributePatchingSchemaOverlay;
9257
9408
  var _ConventionSchema = class _ConventionSchema {
9258
9409
  constructor({
9259
9410
  title,
@@ -9289,7 +9440,10 @@ var require_convention_builder = __commonJS({
9289
9440
  if (overlays) {
9290
9441
  let overlayNames = Object.keys(overlays);
9291
9442
  this.overlays = {};
9292
- overlayNames.forEach((ovrl) => this.overlays[ovrl] = new SchemaOverlay2(overlays[ovrl]));
9443
+ overlayNames.forEach((ovrl) => {
9444
+ this.overlays[ovrl] = new SchemaOverlay2(overlays[ovrl]);
9445
+ this.overlays[ovrl].updateSchema();
9446
+ });
9293
9447
  }
9294
9448
  ;
9295
9449
  if (relationships) {
@@ -9365,6 +9519,7 @@ var require_convention_builder = __commonJS({
9365
9519
  required: this.required
9366
9520
  };
9367
9521
  Object.keys(this.overlays).forEach((attributeName) => {
9522
+ this.overlays[attributeName].updateSchema();
9368
9523
  this.schema.properties[attributeName] = this.overlays[attributeName].schema;
9369
9524
  delete this.schema.properties[attributeName].$id;
9370
9525
  if (!this.overlays[attributeName].originalSrcScript) {
@@ -9698,15 +9853,119 @@ import TabItem from '@theme/TabItem';
9698
9853
  };
9699
9854
  __name(_ConventionSchema, "ConventionSchema");
9700
9855
  var ConventionSchema2 = _ConventionSchema;
9856
+ var _AttributeOverlay = class _AttributeOverlay {
9857
+ constructor({
9858
+ type,
9859
+ bundle,
9860
+ attribute,
9861
+ baseSchemataFolder = `${__dirname}/../../../../input/collection`,
9862
+ sourceSchemataFile = `${__dirname}/../../../../input/farmos.json`,
9863
+ overlayName,
9864
+ overlayDescription
9865
+ }) {
9866
+ let integralSchemataFile = JSON.parse(fs.readFileSync(sourceSchemataFile));
9867
+ this.type = type;
9868
+ this.bundle = bundle;
9869
+ this.overlayName = overlayName;
9870
+ this.overlayDescription = overlayDescription;
9871
+ this.attribute = attribute;
9872
+ this.sourceSchemata = integralSchemataFile;
9873
+ this.lexicon = [...findAllObjectAttributesInTree(this.sourceSchemata), ...findAllNonObjectAttributesInTree(this.sourceSchemata)];
9874
+ this.baseSchemataFolder = baseSchemataFolder;
9875
+ let involvedSchemata = this.lexicon.filter((entry) => this.attribute == entry.attribute).flatMap((entry) => entry.instances).filter((instance) => this.type ? instance.type == this.type : true).filter((instance) => this.bundle ? instance.bundle == this.bundle : true).map((d) => d.schema);
9876
+ this.targetSchemata = Array.from(new Set(involvedSchemata));
9877
+ this.overlays = [];
9878
+ this.targetSchemata.forEach((target) => {
9879
+ let currentOverlay = new AttributePatchingSchemaOverlay({
9880
+ typeAndBundle: target,
9881
+ attributeOverlayName: this.overlayName,
9882
+ baseSchemataFolder: this.baseSchemataFolder
9883
+ });
9884
+ this.overlays.push(currentOverlay);
9885
+ });
9886
+ }
9887
+ setRequire() {
9888
+ this.overlays.forEach((overlay) => {
9889
+ overlay.setRequiredAttribute(this.attribute);
9890
+ });
9891
+ }
9892
+ setGenericSection({
9893
+ section,
9894
+ description
9895
+ }) {
9896
+ this.overlays.forEach((overlay) => {
9897
+ overlay.setGenericSection({
9898
+ attribute: this.attribute,
9899
+ section,
9900
+ description,
9901
+ merge: false
9902
+ });
9903
+ });
9904
+ }
9905
+ setPattern({ pattern, string, description }) {
9906
+ this.overlays.forEach((overlay) => {
9907
+ overlay.setPattern({
9908
+ attribute: this.attribute,
9909
+ pattern,
9910
+ string,
9911
+ description
9912
+ });
9913
+ });
9914
+ }
9915
+ /**
9916
+ * An all involved schemata, sets the target attribute for this overlay as a constant as indicated by the given value.
9917
+ * @param {any} value -- The constant, which should be of the type allowed by the base schema for the attribute.
9918
+ * @param {string} description -- Describes the rationale behind the chosing of the value.
9919
+ */
9920
+ setConstant({ value, description }) {
9921
+ this.overlays.forEach((overlay) => {
9922
+ overlay.setConstant({
9923
+ attribute: this.attribute,
9924
+ value,
9925
+ description
9926
+ });
9927
+ });
9928
+ }
9929
+ /**
9930
+ * Sets this overlay's target attribute as a constrained to a list of possible values in all involved schemata.
9931
+ * @param {string} attribute -- Attribute name for the attribute which will be set to a constant.
9932
+ * @param {any[]} valuesArray -- The array of possible values, which should be of the type allowed by the base schema for the attribute.
9933
+ * @param {string} description -- Describes the rationale behind the chosing of the value.
9934
+ */
9935
+ setEnum({ valuesArray, description }) {
9936
+ this.overlays.forEach((overlay) => {
9937
+ overlay.setConstant({
9938
+ attribute: this.attribute,
9939
+ valuesArray,
9940
+ description
9941
+ });
9942
+ });
9943
+ }
9944
+ /**
9945
+ * Stores all involved schemas into the folder structure for `base schemata` (provided as the parameter `baseSchemataFolder`) which will be consumed by our conventions later.
9946
+ * @returns {} -- It returns objects containing all paths.
9947
+ */
9948
+ store() {
9949
+ let output = this.overlays.map((overlay) => {
9950
+ let operation = overlay.store();
9951
+ return operation;
9952
+ });
9953
+ return output;
9954
+ }
9955
+ };
9956
+ __name(_AttributeOverlay, "AttributeOverlay");
9957
+ var AttributeOverlay2 = _AttributeOverlay;
9701
9958
  exports2.SchemaOverlay = SchemaOverlay2;
9702
9959
  exports2.ConventionSchema = ConventionSchema2;
9960
+ exports2.AttributeOverlay = AttributeOverlay2;
9703
9961
  }
9704
9962
  });
9705
9963
 
9706
9964
  // src/index.js
9707
- var { SchemaOverlay, ConventionSchema } = require_convention_builder();
9965
+ var { SchemaOverlay, ConventionSchema, AttributeOverlay } = require_convention_builder();
9708
9966
  var schemaUtils = require_schema_utilities();
9709
9967
  exports.SchemaOverlay = SchemaOverlay;
9968
+ exports.AttributeOverlay = AttributeOverlay;
9710
9969
  exports.ConventionSchema = ConventionSchema;
9711
9970
  exports.fixRelationshipDataField = schemaUtils.fixRelationshipDataField;
9712
9971
  exports.buildValidator = schemaUtils.buildValidator;
@@ -9719,7 +9978,7 @@ exports.apiComposeTaxonomiesTransformation = schemaUtils.apiComposeTaxonomiesTra
9719
9978
  exports.exampleImporter = schemaUtils.exampleImporter;
9720
9979
  exports.findMissingEntitiesInExample = schemaUtils.findMissingEntitiesInExample;
9721
9980
  exports.organizeEntitiesArrayIntoConvention = schemaUtils.organizeEntitiesArrayIntoConvention;
9722
- exports.organizeEntitiesArrayByRelationships = schemaUtils.organizeEntitiesArrayByRelationships;
9981
+ exports.arrayToStructuredConvention = schemaUtils.arrayToStructuredConvention;
9723
9982
  exports.trimNonRequiredFields = schemaUtils.trimNonRequiredFields;
9724
9983
  exports.reduceSchemaToRequiredFields = schemaUtils.reduceSchemaToRequiredFields;
9725
9984
  exports.flattenJSONSchema = schemaUtils.flattenJSONSchema;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "convention_builder",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "description": "Helper tools that offer a high level interface that transforms a convention description into it's json schema.",
5
5
  "main": "./dist/node/index.js",
6
6
  "browser": "./dist/browser/index.js",