jedison 1.19.0 → 1.20.0

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.
@@ -1910,7 +1910,7 @@ class Instance extends EventEmitter {
1910
1910
  }
1911
1911
  }
1912
1912
  /**
1913
- * Return the last part of the instance path
1913
+ * Return the last part of the instance JSON Pointer
1914
1914
  */
1915
1915
  getKey() {
1916
1916
  return this.key;
@@ -1922,7 +1922,7 @@ class Instance extends EventEmitter {
1922
1922
  return this.schema;
1923
1923
  }
1924
1924
  /**
1925
- * Adds a child instance pointer to the instance list
1925
+ * Adds a child instance reference to the instance list
1926
1926
  */
1927
1927
  register() {
1928
1928
  this.jedison.register(this);
@@ -1936,7 +1936,7 @@ class Instance extends EventEmitter {
1936
1936
  this.children.forEach(registerChildRecursive);
1937
1937
  }
1938
1938
  /**
1939
- * Deletes a child instance pointer from the instance list
1939
+ * Deletes a child instance reference from the instance list
1940
1940
  */
1941
1941
  unregister() {
1942
1942
  this.jedison.unregister(this);
@@ -2230,7 +2230,7 @@ class Editor {
2230
2230
  this.purifyEnabled = getSchemaXOption(this.instance.schema, "purifyHtml") ?? this.instance.jedison.getOption("purifyHtml");
2231
2231
  }
2232
2232
  /**
2233
- * Gets the json path level by counting how many "/" it has
2233
+ * Gets the JSON Pointer level by counting how many "/" it has
2234
2234
  */
2235
2235
  getLevel() {
2236
2236
  return (this.instance.path.match(/\//g) || []).length;
@@ -3883,6 +3883,10 @@ class EditorStringAwesomplete extends EditorString {
3883
3883
  this.theme.adaptForHorizontalInputControl(this.control, labelCol, inputCol);
3884
3884
  }
3885
3885
  addEventListeners() {
3886
+ const eventType = this.getValidationEventType();
3887
+ this.control.input.addEventListener(eventType, () => {
3888
+ this.instance.setValue(this.control.input.value, true, "user");
3889
+ });
3886
3890
  this.control.input.addEventListener("awesomplete-selectcomplete", () => {
3887
3891
  this.instance.setValue(this.control.input.value, true, "user");
3888
3892
  });
@@ -5672,6 +5676,121 @@ class EditorArrayChoices extends Editor {
5672
5676
  super.destroy();
5673
5677
  }
5674
5678
  }
5679
+ class EditorArrayTomSelect extends Editor {
5680
+ static resolves(schema) {
5681
+ const hasTomSelectFormat = getSchemaXOption(schema, "format") === "tom-select";
5682
+ const tomSelectInstalled = window.TomSelect;
5683
+ const schemaType = getSchemaType(schema);
5684
+ const schemaItems = getSchemaItems(schema);
5685
+ const schemaItemsType = isSet(schemaItems) && getSchemaType(schemaItems);
5686
+ const isArrayType = isSet(schemaType) && schemaType === "array";
5687
+ const isUniqueItems = getSchemaUniqueItems(schema) === true;
5688
+ const hasTypes = isSet(schemaItems) && isSet(schemaItemsType);
5689
+ const validTypes = ["string", "number", "integer"];
5690
+ const hasValidItemType = isSet(schemaItems) && isSet(schemaItemsType) && (validTypes.includes(schemaItemsType) || isArray(schemaItemsType) && schemaItemsType.some((type2) => validTypes.includes(type2)));
5691
+ return hasTomSelectFormat && tomSelectInstalled && isArrayType && isUniqueItems && hasTypes && hasValidItemType;
5692
+ }
5693
+ init() {
5694
+ super.init();
5695
+ this.setupEnumSource();
5696
+ }
5697
+ setupEnumSource() {
5698
+ const enumSourceRaw = getSchemaXOption(this.instance.schema, "enumSource");
5699
+ if (!isSet(enumSourceRaw)) return;
5700
+ const enumSource = resolveInstancePath(this.instance.path, enumSourceRaw);
5701
+ const src = this.instance.jedison.getInstance(enumSource);
5702
+ if (src) this.enumSourceValues = src.getValue();
5703
+ this.instance.jedison.watch(enumSource, () => {
5704
+ if (!this.control) return;
5705
+ const s = this.instance.jedison.getInstance(enumSource);
5706
+ if (s) {
5707
+ this.enumSourceValues = s.getValue();
5708
+ this.refreshOptions();
5709
+ }
5710
+ });
5711
+ }
5712
+ getEnumSourceValues() {
5713
+ if (this.enumSourceValues !== void 0) {
5714
+ if (isArray(this.enumSourceValues)) return this.enumSourceValues;
5715
+ if (isObject$1(this.enumSourceValues)) return Object.keys(this.enumSourceValues);
5716
+ return [];
5717
+ }
5718
+ return this.instance.schema.items && this.instance.schema.items.enum || [];
5719
+ }
5720
+ refreshOptions() {
5721
+ if (!this.tomSelectInstance) return;
5722
+ const values = this.getEnumSourceValues();
5723
+ const currentValue = this.instance.getValue();
5724
+ const itemEnumTitles = getSchemaXOption(this.instance.schema.items || {}, "enumTitles") || [];
5725
+ const options = values.map((item, index2) => ({
5726
+ value: item,
5727
+ text: itemEnumTitles[index2] || item
5728
+ }));
5729
+ this.tomSelectInstance.clearOptions();
5730
+ this.tomSelectInstance.addOptions(options);
5731
+ this.tomSelectInstance.setValue(isArray(currentValue) ? currentValue : [], true);
5732
+ }
5733
+ build() {
5734
+ this.control = this.theme.getSelectControl({
5735
+ title: this.getTitle(),
5736
+ description: this.getDescription(),
5737
+ values: [],
5738
+ titles: [],
5739
+ id: this.getIdFromPath(this.instance.path),
5740
+ titleIconClass: getSchemaXOption(this.instance.schema, "titleIconClass"),
5741
+ titleHidden: getSchemaXOption(this.instance.schema, "titleHidden"),
5742
+ info: this.getInfo()
5743
+ });
5744
+ this.control.input.setAttribute("multiple", "");
5745
+ try {
5746
+ const value = this.instance.getValue();
5747
+ const itemEnum = this.getEnumSourceValues();
5748
+ const itemEnumTitles = getSchemaXOption(this.instance.schema.items || {}, "enumTitles") || [];
5749
+ const tomSelectOptions = getSchemaXOption(this.instance.schema, "tomSelectOptions") ?? {};
5750
+ if (this.tomSelectInstance) {
5751
+ this.tomSelectInstance.destroy();
5752
+ }
5753
+ this.options = itemEnum.map((item, index2) => ({
5754
+ value: item,
5755
+ text: itemEnumTitles[index2] || item
5756
+ }));
5757
+ this.tomSelectInstance = new window.TomSelect(this.control.input, {
5758
+ plugins: ["drag_drop", "remove_button", "caret_position"],
5759
+ options: this.options,
5760
+ items: isArray(value) ? value : [],
5761
+ ...tomSelectOptions
5762
+ });
5763
+ } catch (e) {
5764
+ console.error("Tom Select is not available or not loaded correctly.", e);
5765
+ }
5766
+ }
5767
+ adaptForHorizontal(labelCol, inputCol) {
5768
+ this.theme.adaptForHorizontalSelectControl(this.control, labelCol, inputCol);
5769
+ }
5770
+ addEventListeners() {
5771
+ this.tomSelectInstance.on("change", (value) => {
5772
+ if (JSON.stringify(value) !== JSON.stringify(this.instance.getValue())) {
5773
+ this.instance.setValue(value, true, "user");
5774
+ }
5775
+ });
5776
+ }
5777
+ refreshDisabledState() {
5778
+ if (this.disabled || this.readOnly) {
5779
+ this.tomSelectInstance.disable();
5780
+ } else {
5781
+ this.tomSelectInstance.enable();
5782
+ }
5783
+ }
5784
+ refreshUI() {
5785
+ super.refreshUI();
5786
+ const value = this.instance.getValue();
5787
+ this.tomSelectInstance.setValue(isArray(value) ? value : [], true);
5788
+ }
5789
+ destroy() {
5790
+ this.tomSelectInstance.destroy();
5791
+ super.destroy();
5792
+ }
5793
+ }
5675
5794
  class EditorArrayNav extends EditorArray {
5676
5795
  static resolves(schema) {
5677
5796
  const format2 = getSchemaXOption(schema, "format");
@@ -6973,6 +7092,7 @@ class UiResolver {
6973
7092
  EditorObjectRadios,
6974
7093
  EditorObject,
6975
7094
  EditorArrayChoices,
7095
+ EditorArrayTomSelect,
6976
7096
  EditorArrayCheckboxes,
6977
7097
  EditorArrayTuple,
6978
7098
  EditorArrayTableObject,
@@ -7519,13 +7639,13 @@ class Jedison extends EventEmitter {
7519
7639
  this.hiddenInput.value = JSON.stringify(this.getValue());
7520
7640
  }
7521
7641
  /**
7522
- * Adds a child instance pointer to the instances list
7642
+ * Adds a child instance reference to the instances list
7523
7643
  */
7524
7644
  register(instance) {
7525
7645
  this.instances.set(instance.path, instance);
7526
7646
  }
7527
7647
  /**
7528
- * Deletes a child instance pointer from the instances list
7648
+ * Deletes a child instance reference from the instances list
7529
7649
  */
7530
7650
  unregister(instance) {
7531
7651
  this.instances.delete(instance.path);
@@ -7681,7 +7801,7 @@ class Jedison extends EventEmitter {
7681
7801
  this.updateInstancesWatchedData();
7682
7802
  }
7683
7803
  /**
7684
- * Returns an instance by path
7804
+ * Returns an instance by JSON Pointer
7685
7805
  * @return {*}
7686
7806
  */
7687
7807
  getInstance(path) {
@@ -7700,8 +7820,8 @@ class Jedison extends EventEmitter {
7700
7820
  return this.options[canonical];
7701
7821
  }
7702
7822
  /**
7703
- * Navigates to a specific instance by path, activating any ancestor nav/categories tabs as needed.
7704
- * @param {string} path - The instance path (e.g. '#/address/street')
7823
+ * Navigates to a specific instance by JSON Pointer, activating any ancestor nav/categories tabs as needed.
7824
+ * @param {string} path - The instance JSON Pointer (e.g. '#/address/street')
7705
7825
  */
7706
7826
  navigateTo(path) {
7707
7827
  if (!this.isEditor) return;
@@ -7798,7 +7918,9 @@ class Jedison extends EventEmitter {
7798
7918
  class RefParser {
7799
7919
  constructor(options = {}) {
7800
7920
  this.options = Object.assign({
7801
- detectRecursion: true
7921
+ detectRecursion: true,
7922
+ fetch: typeof fetch === "function" ? fetch.bind(globalThis) : void 0,
7923
+ fetchOptions: {}
7802
7924
  }, options);
7803
7925
  this.refs = {};
7804
7926
  this.data = {};
@@ -7832,7 +7954,7 @@ class RefParser {
7832
7954
  }
7833
7955
  /**
7834
7956
  * Traverses the given schema recursively and for each schema with $ref
7835
- * add a new property in the this.refs object with key being the json path to that schema.
7957
+ * add a new property in the this.refs object with key being the JSON Pointer to that schema.
7836
7958
  * If the ref has no value in data will be given a value of null. This value will be later
7837
7959
  * replaced in a future iteration. At that time the data will be available
7838
7960
  * @param schema
@@ -7938,13 +8060,15 @@ class RefParser {
7938
8060
  }
7939
8061
  }
7940
8062
  /**
7941
- * Loads a schema with a synchronous http request
8063
+ * Loads a schema over HTTP. Uses options.fetch (defaults to the global fetch) and
8064
+ * options.fetchOptions, so callers needing auth (e.g. forwarding a session cookie
8065
+ * server-side) can supply headers/credentials, or swap in a custom fetch entirely.
7942
8066
  * @param uri
7943
8067
  * @returns {any}
7944
8068
  */
7945
8069
  async load(uri) {
7946
8070
  try {
7947
- const response = await fetch(uri);
8071
+ const response = await this.options.fetch(uri, this.options.fetchOptions);
7948
8072
  if (!response.ok) {
7949
8073
  throw new Error("Network response was not ok");
7950
8074
  }
@@ -11996,6 +12120,7 @@ const index = {
11996
12120
  EditorObjectRadios,
11997
12121
  EditorObject,
11998
12122
  EditorArrayChoices,
12123
+ EditorArrayTomSelect,
11999
12124
  EditorArrayNav,
12000
12125
  EditorArray,
12001
12126
  EditorMultiple,