@matdata/yasgui 5.5.0 → 5.6.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.
@@ -34,6 +34,9 @@ const AcceptHeaderGraphMap: { key: string; value: string }[] = [
34
34
  { key: "TSV", value: "text/tab-separated-values,*/*;q=0.9" },
35
35
  ];
36
36
 
37
+ // Default API Key header name
38
+ const DEFAULT_API_KEY_HEADER = "X-API-Key";
39
+
37
40
  export default class TabSettingsModal {
38
41
  private tab: Tab;
39
42
  private modalOverlay!: HTMLElement;
@@ -423,7 +426,10 @@ export default class TabSettingsModal {
423
426
  const snippetsBarCheckbox = document.createElement("input");
424
427
  snippetsBarCheckbox.type = "checkbox";
425
428
  snippetsBarCheckbox.id = "showSnippetsBar";
426
- snippetsBarCheckbox.checked = yasqe.getSnippetsBarVisible();
429
+ // Read from global config
430
+ const persistedValue = this.tab.yasgui.persistentConfig.getShowSnippetsBar();
431
+ snippetsBarCheckbox.checked =
432
+ persistedValue !== undefined ? persistedValue : this.tab.yasgui.config.showSnippetsBar !== false;
427
433
 
428
434
  const snippetsBarLabel = document.createElement("label");
429
435
  snippetsBarLabel.htmlFor = "showSnippetsBar";
@@ -689,22 +695,42 @@ export default class TabSettingsModal {
689
695
  const body = document.createElement("div");
690
696
  addClass(body, "authModalBody");
691
697
 
692
- // Auth type (for now only basic, but designed for future)
698
+ // Auth type
693
699
  const typeSection = document.createElement("div");
694
700
  addClass(typeSection, "authModalSection");
695
701
  const typeLabel = document.createElement("label");
696
702
  typeLabel.textContent = "Authentication Type";
697
703
  const typeSelect = document.createElement("select");
704
+
698
705
  const basicOption = document.createElement("option");
699
706
  basicOption.value = "basic";
700
707
  basicOption.textContent = "HTTP Basic Authentication";
701
708
  typeSelect.appendChild(basicOption);
702
- // Future: Add OAuth, Bearer Token, etc.
709
+
710
+ const bearerOption = document.createElement("option");
711
+ bearerOption.value = "bearer";
712
+ bearerOption.textContent = "Bearer Token";
713
+ typeSelect.appendChild(bearerOption);
714
+
715
+ const apiKeyOption = document.createElement("option");
716
+ apiKeyOption.value = "apiKey";
717
+ apiKeyOption.textContent = "API Key (Custom Header)";
718
+ typeSelect.appendChild(apiKeyOption);
719
+
720
+ // Set the current auth type
721
+ if (existingAuth) {
722
+ typeSelect.value = existingAuth.type;
723
+ }
724
+
703
725
  typeSection.appendChild(typeLabel);
704
726
  typeSection.appendChild(typeSelect);
705
727
  body.appendChild(typeSection);
706
728
 
707
- // Username
729
+ // Basic Auth Fields
730
+ const basicAuthFields = document.createElement("div");
731
+ basicAuthFields.id = "basicAuthFields";
732
+ addClass(basicAuthFields, "authFieldsContainer");
733
+
708
734
  const usernameSection = document.createElement("div");
709
735
  addClass(usernameSection, "authModalSection");
710
736
  const usernameLabel = document.createElement("label");
@@ -712,13 +738,12 @@ export default class TabSettingsModal {
712
738
  const usernameInput = document.createElement("input");
713
739
  usernameInput.type = "text";
714
740
  usernameInput.placeholder = "Enter username";
715
- usernameInput.value = existingAuth?.username || "";
741
+ usernameInput.value = existingAuth?.type === "basic" ? existingAuth.username : "";
716
742
  usernameInput.autocomplete = "username";
717
743
  usernameSection.appendChild(usernameLabel);
718
744
  usernameSection.appendChild(usernameInput);
719
- body.appendChild(usernameSection);
745
+ basicAuthFields.appendChild(usernameSection);
720
746
 
721
- // Password
722
747
  const passwordSection = document.createElement("div");
723
748
  addClass(passwordSection, "authModalSection");
724
749
  const passwordLabel = document.createElement("label");
@@ -726,11 +751,81 @@ export default class TabSettingsModal {
726
751
  const passwordInput = document.createElement("input");
727
752
  passwordInput.type = "password";
728
753
  passwordInput.placeholder = "Enter password";
729
- passwordInput.value = existingAuth?.password || "";
754
+ passwordInput.value = existingAuth?.type === "basic" ? existingAuth.password : "";
730
755
  passwordInput.autocomplete = "current-password";
731
756
  passwordSection.appendChild(passwordLabel);
732
757
  passwordSection.appendChild(passwordInput);
733
- body.appendChild(passwordSection);
758
+ basicAuthFields.appendChild(passwordSection);
759
+
760
+ body.appendChild(basicAuthFields);
761
+
762
+ // Bearer Token Fields
763
+ const bearerAuthFields = document.createElement("div");
764
+ bearerAuthFields.id = "bearerAuthFields";
765
+ addClass(bearerAuthFields, "authFieldsContainer");
766
+ bearerAuthFields.style.display = "none";
767
+
768
+ const tokenSection = document.createElement("div");
769
+ addClass(tokenSection, "authModalSection");
770
+ const tokenLabel = document.createElement("label");
771
+ tokenLabel.textContent = "Bearer Token";
772
+ const tokenInput = document.createElement("input");
773
+ tokenInput.type = "password";
774
+ tokenInput.placeholder = "Enter bearer token";
775
+ tokenInput.autocomplete = "off";
776
+ tokenInput.value = existingAuth?.type === "bearer" ? existingAuth.token : "";
777
+ tokenSection.appendChild(tokenLabel);
778
+ tokenSection.appendChild(tokenInput);
779
+ bearerAuthFields.appendChild(tokenSection);
780
+
781
+ body.appendChild(bearerAuthFields);
782
+
783
+ // API Key Fields
784
+ const apiKeyAuthFields = document.createElement("div");
785
+ apiKeyAuthFields.id = "apiKeyAuthFields";
786
+ addClass(apiKeyAuthFields, "authFieldsContainer");
787
+ apiKeyAuthFields.style.display = "none";
788
+
789
+ const headerNameSection = document.createElement("div");
790
+ addClass(headerNameSection, "authModalSection");
791
+ const headerNameLabel = document.createElement("label");
792
+ headerNameLabel.textContent = "Header Name";
793
+ const headerNameInput = document.createElement("input");
794
+ headerNameInput.type = "text";
795
+ headerNameInput.placeholder = `e.g., ${DEFAULT_API_KEY_HEADER}`;
796
+ headerNameInput.value = existingAuth?.type === "apiKey" ? existingAuth.headerName : DEFAULT_API_KEY_HEADER;
797
+ headerNameSection.appendChild(headerNameLabel);
798
+ headerNameSection.appendChild(headerNameInput);
799
+ apiKeyAuthFields.appendChild(headerNameSection);
800
+
801
+ const apiKeySection = document.createElement("div");
802
+ addClass(apiKeySection, "authModalSection");
803
+ const apiKeyLabel = document.createElement("label");
804
+ apiKeyLabel.textContent = "API Key";
805
+ const apiKeyInput = document.createElement("input");
806
+ apiKeyInput.type = "password";
807
+ apiKeyInput.placeholder = "Enter API key";
808
+ apiKeyInput.autocomplete = "off";
809
+ apiKeyInput.value = existingAuth?.type === "apiKey" ? existingAuth.apiKey : "";
810
+ apiKeySection.appendChild(apiKeyLabel);
811
+ apiKeySection.appendChild(apiKeyInput);
812
+ apiKeyAuthFields.appendChild(apiKeySection);
813
+
814
+ body.appendChild(apiKeyAuthFields);
815
+
816
+ // Function to toggle fields based on auth type
817
+ const toggleAuthFields = () => {
818
+ const authType = typeSelect.value;
819
+ basicAuthFields.style.display = authType === "basic" ? "block" : "none";
820
+ bearerAuthFields.style.display = authType === "bearer" ? "block" : "none";
821
+ apiKeyAuthFields.style.display = authType === "apiKey" ? "block" : "none";
822
+ };
823
+
824
+ // Set initial visibility
825
+ toggleAuthFields();
826
+
827
+ // Update visibility when auth type changes
828
+ typeSelect.onchange = toggleAuthFields;
734
829
 
735
830
  // Security notice
736
831
  const securityNotice = document.createElement("div");
@@ -778,22 +873,60 @@ export default class TabSettingsModal {
778
873
  saveButton.type = "button";
779
874
  addClass(saveButton, "authSaveButton");
780
875
  saveButton.onclick = () => {
781
- const username = usernameInput.value.trim();
782
- const password = passwordInput.value;
783
-
784
- if (username && password) {
785
- this.tab.yasgui.persistentConfig.addOrUpdateEndpoint(endpoint, {
786
- authentication: {
787
- type: "basic",
788
- username,
789
- password,
790
- },
791
- });
792
- authModalOverlay.remove();
793
- const endpointsList = this.modalContent.querySelector(".endpointsTable");
794
- if (endpointsList) this.renderEndpointsList(endpointsList as HTMLElement);
795
- } else {
796
- alert("Please enter both username and password.");
876
+ const authType = typeSelect.value;
877
+
878
+ if (authType === "basic") {
879
+ const username = usernameInput.value.trim();
880
+ const password = passwordInput.value;
881
+
882
+ if (username && password) {
883
+ this.tab.yasgui.persistentConfig.addOrUpdateEndpoint(endpoint, {
884
+ authentication: {
885
+ type: "basic",
886
+ username,
887
+ password,
888
+ },
889
+ });
890
+ authModalOverlay.remove();
891
+ const endpointsList = this.modalContent.querySelector(".endpointsTable");
892
+ if (endpointsList) this.renderEndpointsList(endpointsList as HTMLElement);
893
+ } else {
894
+ alert("Please enter both username and password.");
895
+ }
896
+ } else if (authType === "bearer") {
897
+ const token = tokenInput.value.trim();
898
+
899
+ if (token) {
900
+ this.tab.yasgui.persistentConfig.addOrUpdateEndpoint(endpoint, {
901
+ authentication: {
902
+ type: "bearer",
903
+ token,
904
+ },
905
+ });
906
+ authModalOverlay.remove();
907
+ const endpointsList = this.modalContent.querySelector(".endpointsTable");
908
+ if (endpointsList) this.renderEndpointsList(endpointsList as HTMLElement);
909
+ } else {
910
+ alert("Please enter a bearer token.");
911
+ }
912
+ } else if (authType === "apiKey") {
913
+ const headerName = headerNameInput.value.trim();
914
+ const apiKey = apiKeyInput.value.trim();
915
+
916
+ if (headerName && apiKey) {
917
+ this.tab.yasgui.persistentConfig.addOrUpdateEndpoint(endpoint, {
918
+ authentication: {
919
+ type: "apiKey",
920
+ headerName,
921
+ apiKey,
922
+ },
923
+ });
924
+ authModalOverlay.remove();
925
+ const endpointsList = this.modalContent.querySelector(".endpointsTable");
926
+ if (endpointsList) this.renderEndpointsList(endpointsList as HTMLElement);
927
+ } else {
928
+ alert("Please enter both header name and API key.");
929
+ }
797
930
  }
798
931
  };
799
932
 
@@ -927,7 +1060,23 @@ export default class TabSettingsModal {
927
1060
  }
928
1061
  const snippetsBarCheckbox = document.getElementById("showSnippetsBar") as HTMLInputElement;
929
1062
  if (snippetsBarCheckbox) {
930
- yasqe.setSnippetsBarVisible(snippetsBarCheckbox.checked);
1063
+ // Save globally to config and persistent storage
1064
+ this.tab.yasgui.config.showSnippetsBar = snippetsBarCheckbox.checked;
1065
+ this.tab.yasgui.persistentConfig.setShowSnippetsBar(snippetsBarCheckbox.checked);
1066
+
1067
+ // Apply to all tabs by updating each Yasqe instance's config and refreshing
1068
+ this.tab.yasgui.persistentConfig.getTabs().forEach((tabId: string) => {
1069
+ const tab = this.tab.yasgui.getTab(tabId);
1070
+ if (tab) {
1071
+ const tabYasqe = tab.getYasqe();
1072
+ if (tabYasqe) {
1073
+ // Update the individual Yasqe instance's config
1074
+ tabYasqe.config.showSnippetsBar = snippetsBarCheckbox.checked;
1075
+ // Refresh the snippets bar to reflect the change
1076
+ tabYasqe.refreshSnippetsBar();
1077
+ }
1078
+ }
1079
+ });
931
1080
  }
932
1081
  yasqe.saveQuery();
933
1082
  }
package/src/defaults.ts CHANGED
@@ -22,7 +22,6 @@ export default function initialize(): Config<CatalogueItem> {
22
22
  return "yagui_" + id;
23
23
  },
24
24
  tabName: "Query",
25
- corsProxy: undefined,
26
25
  persistencyExpire: 60 * 60 * 24 * 30,
27
26
  persistenceLabelResponse: "response",
28
27
  persistenceLabelConfig: "config",
@@ -31,6 +30,7 @@ export default function initialize(): Config<CatalogueItem> {
31
30
  theme: undefined,
32
31
  showThemeToggle: true,
33
32
  orientation: "vertical",
33
+ showSnippetsBar: true,
34
34
  endpointButtons: undefined,
35
35
  endpointCatalogueOptions: {
36
36
  getData: () => {
@@ -4,6 +4,7 @@
4
4
  margin: 4px 0px;
5
5
  border: 2px solid #ccc;
6
6
  width: 100%;
7
+ min-width: 200px;
7
8
  &:hover {
8
9
  border-color: #bbb;
9
10
  }
@@ -125,6 +126,11 @@
125
126
  align-items: center;
126
127
  gap: 4px;
127
128
  margin-left: 4px;
129
+
130
+ // Hide on small screens (mobile)
131
+ @media (max-width: 768px) {
132
+ display: none;
133
+ }
128
134
  }
129
135
 
130
136
  .endpointButton {
@@ -152,5 +158,11 @@
152
158
  outline: 2px solid var(--yasgui-endpoint-button-focus, #5cb3fd);
153
159
  outline-offset: 2px;
154
160
  }
161
+
162
+ // Reduce padding on medium screens
163
+ @media (max-width: 1024px) {
164
+ padding: 4px 8px;
165
+ font-size: 12px;
166
+ }
155
167
  }
156
168
  }
package/src/index.ts CHANGED
@@ -38,13 +38,23 @@ export interface EndpointButton {
38
38
 
39
39
  export interface EndpointConfig {
40
40
  endpoint: string;
41
- label?: string; // Optional label for the endpoint
42
- showAsButton?: boolean; // Whether to show as a quick-switch button (requires label)
43
- authentication?: {
44
- type: 'basic'; // For now only basic, but designed for future auth types
45
- username: string;
46
- password: string;
47
- };
41
+ label?: string; // Optional label for the endpoint
42
+ showAsButton?: boolean; // Whether to show as a quick-switch button (requires label)
43
+ authentication?:
44
+ | {
45
+ type: "basic";
46
+ username: string;
47
+ password: string;
48
+ }
49
+ | {
50
+ type: "bearer";
51
+ token: string;
52
+ }
53
+ | {
54
+ type: "apiKey";
55
+ headerName: string;
56
+ apiKey: string;
57
+ };
48
58
  }
49
59
  export interface Config<EndpointObject extends CatalogueItem = CatalogueItem> {
50
60
  /**
@@ -54,7 +64,6 @@ export interface Config<EndpointObject extends CatalogueItem = CatalogueItem> {
54
64
  endpointInfo: ((tab?: Tab) => Element) | undefined;
55
65
  copyEndpointOnNewTab: boolean;
56
66
  tabName: string;
57
- corsProxy: string | undefined;
58
67
  endpointCatalogueOptions: EndpointSelectConfig<EndpointObject>;
59
68
  endpointButtons?: EndpointButton[];
60
69
  //The function allows us to modify the config before we pass it on to a tab
@@ -68,7 +77,6 @@ export interface Config<EndpointObject extends CatalogueItem = CatalogueItem> {
68
77
  yasr: YasrConfig;
69
78
  requestConfig: YasguiRequestConfig;
70
79
  contextMenuContainer: HTMLElement | undefined;
71
- nonSslDomain?: string;
72
80
  theme?: Theme;
73
81
  showThemeToggle?: boolean;
74
82
  /**
@@ -77,6 +85,10 @@ export interface Config<EndpointObject extends CatalogueItem = CatalogueItem> {
77
85
  * 'horizontal': YASQE on left, YASR on right
78
86
  */
79
87
  orientation?: "vertical" | "horizontal";
88
+ /**
89
+ * Show code snippets bar in all tabs (global setting)
90
+ */
91
+ showSnippetsBar?: boolean;
80
92
  }
81
93
  export type PartialConfig = {
82
94
  [P in keyof Config]?: Config[P] extends object ? Partial<Config[P]> : Config[P];
@@ -141,6 +153,12 @@ export class Yasgui extends EventEmitter {
141
153
  this.themeManager.listenToSystemTheme();
142
154
  this.persistentConfig = new PersistentConfig(this);
143
155
 
156
+ // Load persisted showSnippetsBar if available
157
+ const persistedShowSnippetsBar = this.persistentConfig.getShowSnippetsBar();
158
+ if (persistedShowSnippetsBar !== undefined) {
159
+ this.config.showSnippetsBar = persistedShowSnippetsBar;
160
+ }
161
+
144
162
  this.tabElements = new TabElements(this);
145
163
  this.tabPanelsEl = document.createElement("div");
146
164
 
@@ -416,7 +434,6 @@ export class Yasgui extends EventEmitter {
416
434
  public static Yasr = Yasr;
417
435
  public static Yasqe = Yasqe;
418
436
  public static defaults = initializeDefaults();
419
- public static corsEnabled: { [endpoint: string]: boolean } = {};
420
437
  }
421
438
 
422
439
  export function getRandomId() {
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // Version information for YASGUI
2
2
  // This file is auto-generated during build - do not edit manually
3
- export const VERSION = "4.6.1";
3
+ export const VERSION = "5.6.0";