mirror of
https://github.com/rooyca/obsidian-api-request.git
synced 2026-07-22 07:50:27 +00:00
update(ref): clear and typed code
This commit is contained in:
parent
c25996d2a1
commit
da1b264d69
7 changed files with 495 additions and 484 deletions
|
|
@ -40,7 +40,7 @@ Este plugin se puede instalar desde Obsidian.
|
|||
- [ ] Consultas inline de la respuesta de una solicitud
|
||||
- [ ] Solicitudes predefinidas
|
||||
- [ ] GUI para bloques de código
|
||||
- [ ] Traducir la documentación
|
||||
- [x] Traducir la documentación
|
||||
|
||||
## ❤️ Patrocinadores
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ The plugin can be installed from within Obsidian.
|
|||
- [ ] Inline query from response
|
||||
- [ ] Predefined requests
|
||||
- [ ] GUI for code-blocks
|
||||
- [ ] Translate documentation
|
||||
- [x] Translate documentation
|
||||
|
||||
## ❤️ Sponsors
|
||||
|
||||
|
|
|
|||
|
|
@ -6,21 +6,20 @@ The `codeblock` is a versatile block that can be used to write code in different
|
|||
|
||||
Flags are the way to specify the parameters of our request and also the format in which we want our response.
|
||||
|
||||
| Flag | Default|
|
||||
| ---| ---------|
|
||||
| url | |
|
||||
| method | GET |
|
||||
| body | |
|
||||
| headers | |
|
||||
| show | ALL |
|
||||
| format | `{}` |
|
||||
| res-type | json |
|
||||
| req-id | req-general |
|
||||
| disabled | |
|
||||
| req-repeat | 1t@1s |
|
||||
| notify-if | |
|
||||
| save-to | |
|
||||
| properties | |
|
||||
| Flag | Default |
|
||||
| ------------| ---------|
|
||||
| [url](#url) | |
|
||||
| [method](#method) | GET |
|
||||
| [body](#body) | |
|
||||
| [headers](#headers) | |
|
||||
| [show](#show) | ALL |
|
||||
| [format](#format) | `{}` |
|
||||
| [req-id](#req-id) | req-general |
|
||||
| [disabled](#disabled) | |
|
||||
| [req-repeat](#req-repeat) | 1t@1s |
|
||||
| [notify-if](#notify-if) | |
|
||||
| [save-to](#save-to) | |
|
||||
| [properties](#properties) | |
|
||||
|
||||
### url
|
||||
|
||||
|
|
@ -140,24 +139,6 @@ format: <h1>{}</h1> <p>{}</p>
|
|||
!!! note "In this example, first `{}` will be replaced by the title, and second `{}` will be replaced by the body."
|
||||
|
||||
|
||||
### res-type
|
||||
|
||||
Specifies the type of response we are getting. The default value is `json`. The available values are:
|
||||
|
||||
- json
|
||||
- other
|
||||
|
||||
When the response type is `other`, the response will be displayed as is. If the response is markdown, it will be rendered as markdown, if it's a raw text, it will be displayed as a text, and so on.
|
||||
|
||||
!!! danger "Be carefull with `html` responses, it can break the page."
|
||||
|
||||
~~~markdown
|
||||
```req
|
||||
url: https://raw.githubusercontent.com/Rooyca/Rooyca/main/README.md
|
||||
res-type: other
|
||||
```
|
||||
~~~
|
||||
|
||||
### req-id
|
||||
|
||||
Specifies the id of the request. The default value is `req-general`. This is useful when we want to store the response in `localStorage` and use it in other blocks or notes.
|
||||
|
|
|
|||
|
|
@ -7,19 +7,19 @@ El `bloque de código` es un bloque versátil que se puede usar para escribir c
|
|||
Las banderas son la forma de especificar los parámetros de nuestra solicitud y también el formato en el que queremos nuestra respuesta.
|
||||
|
||||
| Bandera | Valor predeterminado |
|
||||
| --- | --------- |
|
||||
| url | |
|
||||
| method | GET |
|
||||
| body | |
|
||||
| headers | |
|
||||
| show | ALL |
|
||||
| format | `{}` |
|
||||
| res-type | json |
|
||||
| req-id | req-general |
|
||||
| disabled | |
|
||||
| req-repeat | 1t@1s |
|
||||
| notify-if | |
|
||||
| save-to | |
|
||||
| ------------| ---------|
|
||||
| [url](#url) | |
|
||||
| [method](#method) | GET |
|
||||
| [body](#body) | |
|
||||
| [headers](#headers) | |
|
||||
| [show](#show) | ALL |
|
||||
| [format](#format) | `{}` |
|
||||
| [req-id](#req-id) | req-general |
|
||||
| [disabled](#disabled) | |
|
||||
| [req-repeat](#req-repeat) | 1t@1s |
|
||||
| [notify-if](#notify-if) | |
|
||||
| [save-to](#save-to) | |
|
||||
| [properties](#properties) | |
|
||||
|
||||
### url
|
||||
|
||||
|
|
@ -138,25 +138,6 @@ format: <h1>{}</h1> <p>{}</p>
|
|||
|
||||
!!! note "En este ejemplo, primero `{}` será reemplazado por el título, y segundo `{}` será reemplazado por el cuerpo."
|
||||
|
||||
|
||||
### res-type
|
||||
|
||||
Especifica el tipo de respuesta que estamos obteniendo. El valor predeterminado es `json`. Los valores disponibles son:
|
||||
|
||||
- json
|
||||
- other
|
||||
|
||||
Cuando el tipo de respuesta es `other`, la respuesta se mostrará tal como **está**; si es markdown, se renderizará como markdown, si es un texto, se mostrará como texto, y así sucesivamente.
|
||||
|
||||
!!! danger "Ten cuidado con las respuestas `html`, pueden romper la página."
|
||||
|
||||
~~~markdown
|
||||
```req
|
||||
url: https://raw.githubusercontent.com/Rooyca/Rooyca/main/README.md
|
||||
res-type: other
|
||||
```
|
||||
~~~
|
||||
|
||||
### req-id
|
||||
|
||||
Especifica el ID con la que se almacenará la solicitud. El valor predeterminado es `req-general`. Esto es útil cuando queremos almacenar la respuesta en `localStorage` y usarla en otros bloques o notas.
|
||||
|
|
|
|||
103
src/functions.ts
103
src/functions.ts
|
|
@ -1,51 +1,53 @@
|
|||
import { Notice, requestUrl, Editor } from 'obsidian';
|
||||
|
||||
// Saves the response to the localStorage
|
||||
export function saveToID(reqID: any, reqText: any) {
|
||||
export function saveToID(reqID: string, reqText: string) {
|
||||
localStorage.setItem(reqID, reqText);
|
||||
}
|
||||
|
||||
// Adds the copy button to the code block
|
||||
// Take from: https://github.com/jdbrice/obsidian-code-block-copy/
|
||||
export function addBtnCopy(el: any, copyThis: string) {
|
||||
const btnCopy = el.createEl("button", {cls: "copy-req", text: "copy"});
|
||||
export function addBtnCopy(el: HTMLElement, copyThis: string) {
|
||||
const btnCopy = el.createEl("button", { cls: "copy-req", text: "copy" });
|
||||
btnCopy.addEventListener('click', function () {
|
||||
navigator.clipboard.writeText(copyThis).then(function () {
|
||||
btnCopy.blur();
|
||||
btnCopy.innerText = 'copied!';
|
||||
setTimeout(function () {
|
||||
btnCopy.innerText = 'copy';
|
||||
}, 2000);
|
||||
}, function (error) {
|
||||
btnCopy.innerText = 'Error';
|
||||
});
|
||||
navigator.clipboard.writeText(copyThis).then(function () {
|
||||
btnCopy.blur();
|
||||
btnCopy.innerText = 'copied!';
|
||||
setTimeout(function () {
|
||||
btnCopy.innerText = 'copy';
|
||||
}, 2000);
|
||||
}, function () {
|
||||
btnCopy.innerText = 'Error';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// When more than one {} is defined in "format"
|
||||
// it will loop through the responses and replace the {} with the respective value
|
||||
export function replaceOrder(stri, val) {
|
||||
let index = 0;
|
||||
let replaced = stri.replace(/{}/g, function(match) {
|
||||
return val[index++];
|
||||
});
|
||||
export function replaceOrder(stri: string, val: []) {
|
||||
let index = 0;
|
||||
let replaced = stri.replace(/{}/g, function () {
|
||||
return val[index++];
|
||||
});
|
||||
|
||||
while (val.length > index) {
|
||||
if (val[index] === undefined) break;
|
||||
replaced += "\n"+stri.replace(/{}/g, val[index++]);
|
||||
}
|
||||
while (val.length > index) {
|
||||
if (val[index] === undefined) break;
|
||||
replaced += "\n" + stri.replace(/{}/g, val[index++]);
|
||||
}
|
||||
|
||||
return replaced;
|
||||
return replaced;
|
||||
}
|
||||
|
||||
// Check if the user wants a nested response
|
||||
// In other words, if "->" is present in "show"
|
||||
export function nestedValue(data: any, key: string) {
|
||||
export function nestedValue(data, key: string) {
|
||||
const keySplit: string[] = key.split("->").map((item) => item.trim());
|
||||
var value: any = "";
|
||||
for (let i: number = 0; i < keySplit.length; i++) {
|
||||
let value = "";
|
||||
for (let i = 0; i < keySplit.length; i++) {
|
||||
if (i === 0) {
|
||||
value = data.json[keySplit[i]];
|
||||
} else {
|
||||
value = value[keySplit[i]];
|
||||
} else {
|
||||
value = value[keySplit[i]];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -59,32 +61,31 @@ export function nestedValue(data: any, key: string) {
|
|||
// Paste the response to the editor
|
||||
export function toDocument(settings: any, editor: Editor) {
|
||||
requestUrl({
|
||||
url: settings.URL,
|
||||
method: settings.MethodRequest,
|
||||
body: settings.DataRequest,
|
||||
url: settings.URL,
|
||||
method: settings.MethodRequest,
|
||||
body: settings.DataRequest,
|
||||
})
|
||||
.then((data) => {
|
||||
if (settings.DataResponse !== "") {
|
||||
const DataResponseArray = settings.DataResponse.split(",");
|
||||
for (let i = 0; i < DataResponseArray.length; i++) {
|
||||
const key = DataResponseArray[i].trim();
|
||||
.then((data) => {
|
||||
if (settings.DataResponse !== "") {
|
||||
const DataResponseArray = settings.DataResponse.split(",");
|
||||
for (let i = 0; i < DataResponseArray.length; i++) {
|
||||
const key = DataResponseArray[i].trim();
|
||||
|
||||
var value = JSON.stringify(data.json[key]);
|
||||
let value = JSON.stringify(data.json[key]);
|
||||
|
||||
if (key.includes("->")) {
|
||||
value = nestedValue(data, key);
|
||||
value = JSON.stringify(value);
|
||||
}
|
||||
if (key.includes("->")) {
|
||||
value = nestedValue(data, key);
|
||||
value = JSON.stringify(value);
|
||||
}
|
||||
|
||||
editor.replaceSelection("```markdown\n" + `${key.split("->").pop()} : ${value}\n` + "```\n\n");
|
||||
}
|
||||
} else {
|
||||
console.log(data.text)
|
||||
editor.replaceSelection("<code>\n" + `${data.text}\n` + "</code>\n");
|
||||
}
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
console.error(error);
|
||||
new Notice("Error: " + error.message);
|
||||
});
|
||||
editor.replaceSelection("```markdown\n" + `${key.split("->").pop()} : ${value}\n` + "```\n\n");
|
||||
}
|
||||
} else {
|
||||
editor.replaceSelection("<code>\n" + `${data.text}\n` + "</code>\n");
|
||||
}
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
console.error(error);
|
||||
new Notice("Error: " + error.message);
|
||||
});
|
||||
}
|
||||
773
src/main.ts
773
src/main.ts
|
|
@ -1,7 +1,7 @@
|
|||
import { App, Editor, MarkdownView, Modal, Plugin, PluginSettingTab, Setting, Notice } from 'obsidian';
|
||||
import { App, Editor, MarkdownView, Modal, Plugin, PluginSettingTab, Setting, Notice, requestUrl } from 'obsidian';
|
||||
import { readFrontmatter, parseFrontmatter } from './frontmatterUtils';
|
||||
import { MarkdownParser } from './mdparse';
|
||||
import { checkFrontmatter, saveToID, addBtnCopy, replaceOrder, nestedValue, toDocument } from './functions';
|
||||
import { saveToID, addBtnCopy, replaceOrder, nestedValue, toDocument } from './functions';
|
||||
import { num_braces_regx, num_hyphen_regx, nums_rex, in_braces_regx, varname_regx, no_varname_regx } from './regx';
|
||||
|
||||
const parser = new MarkdownParser();
|
||||
|
|
@ -12,8 +12,9 @@ interface LoadAPIRSettings {
|
|||
DataRequest: string;
|
||||
HeaderRequest: string;
|
||||
DataResponse: string;
|
||||
URLs: string[];
|
||||
URLs: object[];
|
||||
Name: string;
|
||||
DisabledReq: string;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: LoadAPIRSettings = {
|
||||
|
|
@ -24,6 +25,7 @@ const DEFAULT_SETTINGS: LoadAPIRSettings = {
|
|||
DataResponse: '',
|
||||
URLs: [],
|
||||
Name: '',
|
||||
DisabledReq: 'This request is disabled',
|
||||
}
|
||||
|
||||
// Checks if the frontmatter is present in the request property
|
||||
|
|
@ -52,10 +54,10 @@ export function checkFrontmatter(req_prop: string) {
|
|||
console.error(e.message);
|
||||
new Notice("Error: " + e.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return req_prop;
|
||||
}
|
||||
return req_prop;
|
||||
}
|
||||
|
||||
export default class MainAPIR extends Plugin {
|
||||
|
|
@ -74,238 +76,270 @@ export default class MainAPIR extends Plugin {
|
|||
});
|
||||
|
||||
try {
|
||||
this.registerMarkdownCodeBlockProcessor("req", async (source, el, ctx) => {
|
||||
const sourceLines = source.split("\n");
|
||||
let method = "GET", allowedMethods = ["GET", "POST", "PUT", "DELETE"], URL = "", show = "",
|
||||
headers = {}, body = {}, format = "{}", responseType = "json", responseAllow = ["json", "other"], reqID = "req-general",
|
||||
reqRepeat = { "times": 1, "every": 1000 }, notifyIf = "", saveTo = "", properties = "";
|
||||
this.registerMarkdownCodeBlockProcessor("req", async (source, el, ctx) => {
|
||||
const sourceLines = source.split("\n");
|
||||
let [URL, show, saveTo, reqID] = [String(), String(), String(), String()];
|
||||
let [notifyIf, properties] = [[String()], [String()]];
|
||||
// 'format' is not and empty objet, is a string that will be replaced by the response
|
||||
let [method, format] = ["GET", "{}"];
|
||||
let [headers, body, reqRepeat] = [Object(), Object(), { "times": 1, "every": 1000 }];
|
||||
const allowedMethods = ["GET", "POST", "PUT", "DELETE"];
|
||||
|
||||
for (const line of sourceLines) {
|
||||
const lowercaseLine = line.toLowerCase();
|
||||
if (lowercaseLine.includes("method:")) {
|
||||
method = line.replace(/method:/i, "").toUpperCase();
|
||||
method = method.trim();
|
||||
if (!allowedMethods.includes(method)) {
|
||||
el.createEl("strong", { text: `Error: Method ${method} not supported` });
|
||||
return;
|
||||
}
|
||||
} else if (lowercaseLine.includes("notify-if:")) {
|
||||
notifyIf = line.replace(/notify-if:/i, "");
|
||||
notifyIf = notifyIf.split(" ");
|
||||
} else if (lowercaseLine.includes("req-repeat:")) {
|
||||
let repeat_values = line.replace(/req-repeat:/i, "");
|
||||
repeat_values = repeat_values.split("@");
|
||||
|
||||
// check if there are two values and they are numbers
|
||||
if (repeat_values.length === 2 && !isNaN(repeat_values[0]) && !isNaN(repeat_values[1])) {
|
||||
reqRepeat = {"times": parseInt(repeat_values[0]), "every": parseInt(repeat_values[1])*1000};
|
||||
} else {
|
||||
el.createEl("strong", { text: "Error: req-repeat format is not valid (use Nt@Ns)" });
|
||||
for (const line of sourceLines) {
|
||||
const lowercaseLine = line.toLowerCase();
|
||||
if (lowercaseLine.includes("method:")) {
|
||||
method = line.replace(/method:/i, "").toUpperCase();
|
||||
method = method.trim();
|
||||
if (!allowedMethods.includes(method)) {
|
||||
el.createEl("strong", { text: `Error: Method ${method} not supported` });
|
||||
return;
|
||||
}
|
||||
} else if (lowercaseLine.includes("url:")) {
|
||||
URL = checkFrontmatter(line.replace(/url:/i, ""));
|
||||
if (!URL.includes("http")) {
|
||||
URL = "https://" + URL;
|
||||
}
|
||||
} else if (lowercaseLine.includes("res-type:")) {
|
||||
responseType = line.replace(/res-type:/i, "").toLowerCase();
|
||||
responseType = responseType.trim();
|
||||
if (!responseAllow.includes(responseType)) {
|
||||
el.createEl("strong", { text: `Error: Response type ${responseType} not supported` });
|
||||
return;
|
||||
}
|
||||
} else if (lowercaseLine.includes("show:")) {
|
||||
show = line.replace(/show:/i, "");
|
||||
} else if (lowercaseLine.includes("headers:")) {
|
||||
headers = JSON.parse(checkFrontmatter(line.replace(/headers:/i, "")));
|
||||
} else if (lowercaseLine.includes("body:")) {
|
||||
body = checkFrontmatter(line.replace(/body:/i, ""));
|
||||
} else if (lowercaseLine.includes("format:")) {
|
||||
format = line.replace(/format:/i, "");
|
||||
if (!format.includes("{}")) {
|
||||
el.createEl("strong", { text: "Error: Use {} to show response in the document." });
|
||||
return;
|
||||
}
|
||||
} else if (lowercaseLine.includes("req-id:")) {
|
||||
reqID = line.replace(/id:/i, "");
|
||||
} else if (lowercaseLine.includes("notify-if:")) {
|
||||
const tempNotifyIf = line.replace(/notify-if:/i, "");
|
||||
notifyIf = tempNotifyIf.trim().split(" ");
|
||||
} else if (lowercaseLine.includes("req-repeat:")) {
|
||||
const repeat_values: string[] = line.replace(/req-repeat:/i, "").trim().split("@");
|
||||
|
||||
if (sourceLines.includes("disabled")) {
|
||||
const idExists = localStorage.getItem(reqID);
|
||||
if (idExists) {
|
||||
el.innerHTML += parser.parse(idExists);
|
||||
return;
|
||||
} else {
|
||||
sourceLines.splice(sourceLines.indexOf("disabled"), 1);
|
||||
}
|
||||
}
|
||||
} else if (lowercaseLine.includes("save-to:")) {
|
||||
saveTo = line.replace(/save-to:/i, "");
|
||||
if (saveTo === "") {
|
||||
el.createEl("strong", { text: "Error: save-to value is empty. Please provide a filename" });
|
||||
return;
|
||||
}
|
||||
} else if (lowercaseLine.includes("properties:")) {
|
||||
properties = line.replace(/properties:/i, "");
|
||||
properties = properties.replace(/\s/g, "");
|
||||
properties = properties.split(",");
|
||||
}
|
||||
if (URL === "") {
|
||||
el.createEl("strong", { text: "Error: URL not found" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Function to check if a string is a valid integer
|
||||
const isValidNumber = (value: string): boolean => {
|
||||
return /^\d+$/.test(value);
|
||||
};
|
||||
|
||||
if (sourceLines.includes("disabled")) {
|
||||
el.createEl("strong", { text: "This request is disabled." });
|
||||
return;
|
||||
}
|
||||
// Check if there are two values and they are valid numbers
|
||||
if (repeat_values.length === 2 && isValidNumber(repeat_values[0]) && isValidNumber(repeat_values[1])) {
|
||||
reqRepeat = { "times": parseInt(repeat_values[0]), "every": parseInt(repeat_values[1]) * 1000 };
|
||||
} else {
|
||||
el.createEl("strong", { text: "Error: req-repeat format is not valid (use T@S)" });
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < reqRepeat.times; i++) {
|
||||
try {
|
||||
const responseData = await requestUrl({ url: URL, method, headers, body });
|
||||
// Save to File
|
||||
if (saveTo) {
|
||||
try {
|
||||
await this.app.vault.create(saveTo, responseData.text);
|
||||
new Notice("Saved to " + saveTo);
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
new Notice("Error: " + e.message);
|
||||
}
|
||||
}
|
||||
} else if (lowercaseLine.includes("url:")) {
|
||||
URL = checkFrontmatter(line.replace(/url:/i, "").trim()) ?? "";
|
||||
if (!URL) {
|
||||
el.createEl("strong", { text: "Error: URL not found" });
|
||||
return;
|
||||
}
|
||||
if (URL && !URL.startsWith("http")) {
|
||||
URL = "https://" + URL;
|
||||
}
|
||||
} else if (lowercaseLine.includes("show:")) {
|
||||
show = line.replace(/show:/i, "").trim();
|
||||
if (!show) {
|
||||
el.createEl("strong", { text: "Error: show value is empty" });
|
||||
return;
|
||||
}
|
||||
} else if (lowercaseLine.includes("headers:")) {
|
||||
const tempHeaders = checkFrontmatter(line.replace(/headers:/i, "")) ?? "";
|
||||
if (tempHeaders) {
|
||||
try {
|
||||
headers = JSON.parse(tempHeaders);
|
||||
} catch (e) {
|
||||
el.createEl("strong", { text: "Error: Headers format is not valid" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (lowercaseLine.includes("body:")) {
|
||||
body = checkFrontmatter(line.replace(/body:/i, ""));
|
||||
} else if (lowercaseLine.includes("format:")) {
|
||||
format = line.replace(/format:/i, "");
|
||||
if (!format.includes("{}")) {
|
||||
el.createEl("strong", { text: "Error: Use {} to show response in the document." });
|
||||
return;
|
||||
}
|
||||
} else if (lowercaseLine.includes("req-id:")) {
|
||||
reqID = line.replace(/id:/i, "").trim();
|
||||
|
||||
if (responseType !== "json") {
|
||||
try {
|
||||
el.innerHTML += parser.parse(responseData.text);
|
||||
} catch (e) {
|
||||
new Notice("Error: " + e.message);
|
||||
el.createEl("strong", { text: responseData.text });
|
||||
}
|
||||
saveToID(reqID, responseData.text);
|
||||
addBtnCopy(el, responseData.text);
|
||||
return;
|
||||
}
|
||||
if (sourceLines.includes("disabled")) {
|
||||
const idExists = localStorage.getItem(reqID);
|
||||
if (idExists) {
|
||||
el.createDiv({ text: parser.parse(idExists) });
|
||||
return;
|
||||
} else {
|
||||
sourceLines.splice(sourceLines.indexOf("disabled"), 1);
|
||||
}
|
||||
}
|
||||
} else if (lowercaseLine.includes("save-to:")) {
|
||||
saveTo = line.replace(/save-to:/i, "").trim();
|
||||
if (!saveTo) {
|
||||
el.createEl("strong", { text: "Error: save-to value is empty. Please provide a filename with extension" });
|
||||
return;
|
||||
}
|
||||
} else if (lowercaseLine.includes("properties:")) {
|
||||
// remove all spaces and split by comma
|
||||
properties = line.replace(/properties:/i, "").replace(/\s/g, "").split(",");
|
||||
}
|
||||
}
|
||||
|
||||
if (notifyIf) {
|
||||
const jsonPath = notifyIf[0];
|
||||
const symbol = notifyIf[1];
|
||||
const value = notifyIf[2]
|
||||
const int_value = parseInt(value);
|
||||
if (sourceLines.includes("disabled")) {
|
||||
el.createEl("strong", { text: this.settings.DisabledReq });
|
||||
return;
|
||||
}
|
||||
|
||||
const jsonPathValue = jsonPath.split(".").reduce((acc, cv) => acc[cv], responseData.json);
|
||||
const lastValue = jsonPath.split(".").pop();
|
||||
if (symbol === ">" && jsonPathValue > int_value) {
|
||||
new Notice("APIR: " + lastValue + " is greater than " + int_value);
|
||||
} else if (symbol === "<" && jsonPathValue < int_value) {
|
||||
new Notice("APIR: " + lastValue + " is less than " + int_value);
|
||||
} else if (symbol === "=" && jsonPathValue === value) {
|
||||
new Notice("APIR: " + lastValue + " is equal to " + value);
|
||||
} else if (symbol === ">=" && jsonPathValue >= int_value) {
|
||||
new Notice("APIR: " + lastValue + " is greater than or equal to " + int_value);
|
||||
} else if (symbol === "<=" && jsonPathValue <= int_value) {
|
||||
new Notice("APIR: " + lastValue + " is less than or equal to " + int_value);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < reqRepeat.times; i++) {
|
||||
try {
|
||||
const responseData = await requestUrl({ url: URL, method, headers, body });
|
||||
// Save to a file
|
||||
if (saveTo) {
|
||||
try {
|
||||
await this.app.vault.create(saveTo, responseData.text);
|
||||
new Notice("Saved to: " + saveTo);
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
new Notice("Error: " + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the response is not JSON
|
||||
if (!responseData.headers["content-type"].includes("application/json")) {
|
||||
try {
|
||||
el.innerHTML = parser.parse(responseData.text);
|
||||
} catch (e) {
|
||||
new Notice("Error: " + e.message);
|
||||
el.innerHTML = "<pre>" + responseData.text + "</pre>";
|
||||
}
|
||||
|
||||
if (reqID) saveToID(reqID, responseData.text);
|
||||
addBtnCopy(el, responseData.text);
|
||||
return;
|
||||
}
|
||||
|
||||
if (notifyIf) {
|
||||
const jsonPath = notifyIf[0];
|
||||
const symbol = notifyIf[1];
|
||||
const value = notifyIf[2]
|
||||
const int_value = parseInt(value);
|
||||
|
||||
const jsonPathValue = jsonPath.split(".").reduce((acc, cv) => acc[cv], responseData.json);
|
||||
const lastValue = jsonPath.split(".").pop();
|
||||
if (symbol === ">" && jsonPathValue > int_value) {
|
||||
new Notice("APIR: " + lastValue + " is greater than " + int_value);
|
||||
} else if (symbol === "<" && jsonPathValue < int_value) {
|
||||
new Notice("APIR: " + lastValue + " is less than " + int_value);
|
||||
} else if (symbol === "=" && jsonPathValue === value) {
|
||||
new Notice("APIR: " + lastValue + " is equal to " + value);
|
||||
} else if (symbol === ">=" && jsonPathValue >= int_value) {
|
||||
new Notice("APIR: " + lastValue + " is greater than or equal to " + int_value);
|
||||
} else if (symbol === "<=" && jsonPathValue <= int_value) {
|
||||
new Notice("APIR: " + lastValue + " is less than or equal to " + int_value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!show) {
|
||||
el.innerHTML = "<pre>" + JSON.stringify(responseData.json, null, 2) + "</pre>";
|
||||
saveToID(reqID, el.innerText);
|
||||
addBtnCopy(el, el.innerText);
|
||||
} else {
|
||||
if (show.match(in_braces_regx)) {
|
||||
if (properties.length > 0 && properties[0] !== '') {
|
||||
el.createEl("strong", { text: "Error: Properties are not allowed without SHOW" });
|
||||
return;
|
||||
}
|
||||
el.innerHTML = "<pre>" + JSON.stringify(responseData.json, null, 2) + "</pre>";
|
||||
if (reqID) saveToID(reqID, el.innerText);
|
||||
addBtnCopy(el, el.innerText);
|
||||
} else {
|
||||
const checkBracesRegex = show.match(in_braces_regx);
|
||||
if (checkBracesRegex) {
|
||||
if (show.includes(",")) {
|
||||
el.createEl("strong", { text: "Error: comma is not allowed when using {}" });
|
||||
return;
|
||||
}
|
||||
|
||||
let temp_show = "";
|
||||
let range = Object();
|
||||
|
||||
if (show.match(num_braces_regx)) {
|
||||
const range = show.match(nums_rex).map(Number);
|
||||
try {
|
||||
range = show.match(nums_rex)!.map(Number)
|
||||
if (range[0] > range[1]) {
|
||||
el.createEl("strong", { text: "Error: range is not valid" });
|
||||
return;
|
||||
}
|
||||
for (let i = range[0]; i <= range[1]; i++) {
|
||||
temp_show += show.replace(show.match(num_braces_regx)[0], i) + ", ";
|
||||
} catch (e) {
|
||||
console.error(e.message)
|
||||
}
|
||||
|
||||
const numberBracesRegex = show.match(num_braces_regx)
|
||||
|
||||
if (numberBracesRegex) {
|
||||
for (let i: number = range[0]; i <= range[1]; i++) {
|
||||
temp_show += show.replace(numberBracesRegex![0], i.toString()) + ", ";
|
||||
}
|
||||
show = temp_show;
|
||||
} else if (show.match(num_hyphen_regx)) {
|
||||
const numbers = show.match(nums_rex).map(Number);
|
||||
show = show.replace(in_braces_regx, "-");
|
||||
for (let i = 0; i < numbers.length; i++) {
|
||||
temp_show += show.replace("-", numbers[i]) + ", ";
|
||||
}
|
||||
show = temp_show;
|
||||
show = show.replace(in_braces_regx, "-");
|
||||
for (let i = 0; i < range.length; i++) {
|
||||
temp_show += show.replace("-", range[i].toString()) + ", ";
|
||||
}
|
||||
show = temp_show;
|
||||
} else {
|
||||
for (let i = 0; i < responseData.json.length; i++) {
|
||||
temp_show += show.replace("{..}", i) + ", ";
|
||||
}
|
||||
show = temp_show;
|
||||
}
|
||||
for (let i = 0; i < responseData.json.length; i++) {
|
||||
temp_show += show.replace("{..}", i.toString()) + ", ";
|
||||
}
|
||||
show = temp_show;
|
||||
}
|
||||
}
|
||||
|
||||
// adding properties to frontmatter
|
||||
if (properties) {
|
||||
if (properties.length > 0 && properties[0] !== '') {
|
||||
const showArray = show.split(",");
|
||||
const propertiesArray = properties;
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
const file = activeView.file;
|
||||
const file: TFile = activeView!.file;
|
||||
|
||||
showArray.forEach(async (key, index) => {
|
||||
await Promise.all(showArray.map(async (key, index) => {
|
||||
const trimmedKey = key.trim();
|
||||
let val = "";
|
||||
if (key.includes("->")) {
|
||||
val = nestedValue(responseData, key);
|
||||
} else if (responseData.json && responseData.json[key.trim()]) {
|
||||
val = responseData.json[key.trim()];
|
||||
|
||||
if (trimmedKey.includes("->")) {
|
||||
val = nestedValue(responseData, trimmedKey);
|
||||
} else if (responseData.json && responseData.json[trimmedKey]) {
|
||||
val = responseData.json[trimmedKey];
|
||||
}
|
||||
|
||||
const propertyName = propertiesArray[index].trim();
|
||||
if (propertyName) {
|
||||
await this.app.fileManager.processFrontMatter(file, (existingFrontmatter) => {
|
||||
existingFrontmatter[propertyName] = val;
|
||||
existingFrontmatter[propertyName] = val;
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
const values = show.includes(",") ? show.split(",").map(key => {
|
||||
let value = responseData.json[key.trim()];
|
||||
if (key.includes("->")) value = nestedValue(responseData, key);
|
||||
return value;
|
||||
}) : [show.trim().includes("->") ? nestedValue(responseData, show.trim()) : responseData.json[show.trim()]];
|
||||
const replacedText = replaceOrder(format, values);
|
||||
el.innerHTML = parser.parse(replacedText);
|
||||
|
||||
saveToID(reqID, replacedText);
|
||||
addBtnCopy(el, replacedText);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
el.createEl("strong", { text: "Error: " + error.message });
|
||||
new Notice("Error: " + error.message);
|
||||
}
|
||||
await sleep(reqRepeat.every);
|
||||
}
|
||||
return;
|
||||
});
|
||||
const trimAndProcessKey = (key: string) => {
|
||||
const trimmedKey = key.trim();
|
||||
return trimmedKey.includes("->")
|
||||
? nestedValue(responseData, trimmedKey)
|
||||
: JSON.stringify(responseData.json[trimmedKey]);
|
||||
};
|
||||
|
||||
const values = show.split(",").map(trimAndProcessKey);
|
||||
const replacedText = replaceOrder(format, values);
|
||||
|
||||
el.innerHTML = parser.parse(replacedText);
|
||||
if (reqID) saveToID(reqID, replacedText);
|
||||
addBtnCopy(el, replacedText);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
el.createEl("strong", { text: "Error: " + error.message });
|
||||
new Notice("Error: " + error.message);
|
||||
}
|
||||
await sleep(reqRepeat.every);
|
||||
}
|
||||
return;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
el.createEl("strong", { text: "Error: " + error.message });
|
||||
new Notice("Error: " + e.message);
|
||||
console.error(e.message);
|
||||
new Notice("Error: " + e.message);
|
||||
}
|
||||
|
||||
this.addCommand({
|
||||
id: 'response-in-document',
|
||||
name: 'Paste response in current document',
|
||||
editorCallback: (editor: Editor, view: MarkdownView) => {
|
||||
editorCallback: (editor: Editor) => {
|
||||
toDocument(this.settings, editor);
|
||||
}
|
||||
});
|
||||
|
||||
for (let i = 0; i < this.settings.URLs.length; i++) {
|
||||
this.addCommand({
|
||||
id: 'response-in-document-' + this.settings.URLs[i].Name,
|
||||
name: 'Response for api: ' + this.settings.URLs[i].Name,
|
||||
id: 'response-in-document-' + this.settings.URLs[i]["Name"],
|
||||
name: 'Response for api: ' + this.settings.URLs[i]["Name"],
|
||||
editorCallback: (editor: Editor, view: MarkdownView) => {
|
||||
const rea = this.settings.URLs[i];
|
||||
toDocument(rea, editor);
|
||||
|
|
@ -318,12 +352,12 @@ export default class MainAPIR extends Plugin {
|
|||
|
||||
onunload() {
|
||||
console.log('unloading APIR');
|
||||
// Clean up localStorage
|
||||
Object.keys(localStorage).forEach(key => {
|
||||
if (key.startsWith("req-")) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
});
|
||||
// Clean up localStorage
|
||||
// Object.keys(localStorage).forEach(key => {
|
||||
// if (key.startsWith("req-")) {
|
||||
// localStorage.removeItem(key);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
|
|
@ -336,55 +370,54 @@ export default class MainAPIR extends Plugin {
|
|||
}
|
||||
|
||||
class ShowOutputModal extends Modal {
|
||||
constructor(app: App, URL: string, MethodRequest: string, DataRequest: string, HeaderRequest: string, DataResponse: string) {
|
||||
super(app);
|
||||
this.props = {
|
||||
URL,
|
||||
MethodRequest,
|
||||
DataRequest,
|
||||
HeaderRequest,
|
||||
DataResponse,
|
||||
};
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
const { contentEl } = this;
|
||||
const { URL, MethodRequest, DataRequest, HeaderRequest, DataResponse } = this.props;
|
||||
|
||||
const handleError = (error) => {
|
||||
console.error(error);
|
||||
new Notice("Error: " + error.message);
|
||||
};
|
||||
|
||||
const parseAndCreate = (data) => (key) => {
|
||||
const json = data.json;
|
||||
const value = DataResponse.includes("->") ? nestedValue(data, key) : json[key];
|
||||
contentEl.createEl('b', { text: key + " : " + JSON.stringify(value, null, 2) });
|
||||
};
|
||||
|
||||
const requestOptions = {
|
||||
url: URL,
|
||||
method: MethodRequest,
|
||||
headers: JSON.parse(HeaderRequest),
|
||||
...(MethodRequest !== "GET" && { body: DataRequest })
|
||||
};
|
||||
|
||||
requestUrl(requestOptions)
|
||||
.then((data) => {
|
||||
if (DataResponse !== "") {
|
||||
const DataResponseArray = DataResponse.split(",");
|
||||
DataResponseArray.forEach(parseAndCreate(data));
|
||||
} else {
|
||||
contentEl.createEl('b', { text: JSON.stringify(data.json, null, 2) });
|
||||
}
|
||||
})
|
||||
.catch(handleError);
|
||||
constructor(app: App, URL: string, MethodRequest: string, DataRequest: string, HeaderRequest: string, DataResponse: string) {
|
||||
super(app);
|
||||
this.props = {
|
||||
URL,
|
||||
MethodRequest,
|
||||
DataRequest,
|
||||
HeaderRequest,
|
||||
DataResponse,
|
||||
};
|
||||
}
|
||||
|
||||
onClose() {
|
||||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
onOpen() {
|
||||
const { contentEl } = this;
|
||||
const { URL, MethodRequest, DataRequest, HeaderRequest, DataResponse } = this.props;
|
||||
|
||||
const handleError = (error: Error) => {
|
||||
console.error(error);
|
||||
new Notice("Error: " + error.message);
|
||||
};
|
||||
|
||||
const parseAndCreate = (data: object) => (key: string) => {
|
||||
const value = DataResponse.includes("->") ? nestedValue(data, key) : data[key];
|
||||
contentEl.createEl('b', { text: key + " : " + JSON.stringify(value, null, 2) });
|
||||
};
|
||||
|
||||
const requestOptions = {
|
||||
url: URL,
|
||||
method: MethodRequest,
|
||||
headers: JSON.parse(HeaderRequest),
|
||||
...(MethodRequest !== "GET" && { body: DataRequest })
|
||||
};
|
||||
|
||||
requestUrl(requestOptions)
|
||||
.then((data) => {
|
||||
if (DataResponse !== "") {
|
||||
const DataResponseArray = DataResponse.split(",");
|
||||
DataResponseArray.forEach(parseAndCreate(data));
|
||||
} else {
|
||||
contentEl.createEl('b', { text: JSON.stringify(data.json, null, 2) });
|
||||
}
|
||||
})
|
||||
.catch(handleError);
|
||||
}
|
||||
|
||||
onClose() {
|
||||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
||||
class APRSettings extends PluginSettingTab {
|
||||
|
|
@ -396,10 +429,10 @@ class APRSettings extends PluginSettingTab {
|
|||
}
|
||||
|
||||
display(): void {
|
||||
const {containerEl} = this;
|
||||
const { containerEl } = this;
|
||||
|
||||
containerEl.empty();
|
||||
containerEl.createEl('h2', { text: "Add Request" });
|
||||
containerEl.createEl('h2', { text: "Add New Request" });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName('Name')
|
||||
|
|
@ -424,90 +457,104 @@ class APRSettings extends PluginSettingTab {
|
|||
this.plugin.settings.URL = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.setName('Method')
|
||||
.setDesc("Select the desired method")
|
||||
.addDropdown(dropDown => {
|
||||
dropDown.addOption("GET", "GET");
|
||||
dropDown.addOption("POST", "POST");
|
||||
dropDown.addOption("POST", "PUT");
|
||||
dropDown.addOption("DELETE", "DELETE");
|
||||
dropDown.setValue(this.plugin.settings.MethodRequest)
|
||||
dropDown.onChange(async value => {
|
||||
this.plugin.settings.MethodRequest = value;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
new Setting(containerEl)
|
||||
.setName('Body')
|
||||
.setDesc("Data to send in the body")
|
||||
.addTextArea(text => text
|
||||
.setPlaceholder('{"data":"data"}')
|
||||
.setValue(this.plugin.settings.DataRequest)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.DataRequest = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.setName('Headers')
|
||||
.setDesc("The headers of the request")
|
||||
.addTextArea(text => text
|
||||
.setPlaceholder('{"Content-Type": "application/json"}')
|
||||
.setValue(this.plugin.settings.HeaderRequest)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.HeaderRequest = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.setName('What to display')
|
||||
.setDesc("Write the name of the variables you want to show (spaced by comma)")
|
||||
.addTextArea(text => text
|
||||
.setPlaceholder('varname')
|
||||
.setValue(this.plugin.settings.DataResponse)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.DataResponse = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.addButton(button => {
|
||||
button.setClass('btn-add-apir');
|
||||
button.setButtonText('ADD').onClick(async () => {
|
||||
const {Name} = this.plugin.settings;
|
||||
if (Name === "") {
|
||||
new Notice("Name is empty");
|
||||
return;
|
||||
}
|
||||
const {URL, MethodRequest, DataResponse, DataRequest, HeaderRequest} = this.plugin.settings;
|
||||
const {URLs} = this.plugin.settings;
|
||||
URLs.push({
|
||||
'URL': URL,
|
||||
'Name': Name,
|
||||
'MethodRequest': MethodRequest,
|
||||
'DataRequest': DataRequest,
|
||||
'HeaderRequest': HeaderRequest,
|
||||
'DataResponse': DataResponse
|
||||
});
|
||||
await this.plugin.saveSettings();
|
||||
this.display();
|
||||
this.plugin.addCommand({
|
||||
id: 'response-in-document-' + Name,
|
||||
name: 'Response for api: ' + Name,
|
||||
editorCallback: (editor: Editor, view: MarkdownView) => {
|
||||
const rea = URLs[URLs.length - 1];
|
||||
toDocument(rea, editor);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
new Setting(containerEl)
|
||||
.setName('Method')
|
||||
.setDesc("Select the desired method")
|
||||
.addDropdown(dropDown => {
|
||||
dropDown.addOption("GET", "GET");
|
||||
dropDown.addOption("POST", "POST");
|
||||
dropDown.addOption("POST", "PUT");
|
||||
dropDown.addOption("DELETE", "DELETE");
|
||||
dropDown.setValue(this.plugin.settings.MethodRequest)
|
||||
dropDown.onChange(async value => {
|
||||
this.plugin.settings.MethodRequest = value;
|
||||
await this.plugin.saveSettings();
|
||||
});
|
||||
});
|
||||
new Setting(containerEl)
|
||||
.setName('Body')
|
||||
.setDesc("Data to send in the body")
|
||||
.addTextArea(text => text
|
||||
.setPlaceholder('{"data":"data"}')
|
||||
.setValue(this.plugin.settings.DataRequest)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.DataRequest = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.setName('Headers')
|
||||
.setDesc("The headers of the request")
|
||||
.addTextArea(text => text
|
||||
.setPlaceholder('{"Content-Type": "application/json"}')
|
||||
.setValue(this.plugin.settings.HeaderRequest)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.HeaderRequest = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.setName('What to display')
|
||||
.setDesc("Write the name of the variables you want to show (spaced by comma)")
|
||||
.addText(text => text
|
||||
.setPlaceholder('varname')
|
||||
.setValue(this.plugin.settings.DataResponse)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.DataResponse = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
new Setting(containerEl)
|
||||
.addButton(button => {
|
||||
button.setClass('btn-add-apir');
|
||||
button.setButtonText('ADD').onClick(async () => {
|
||||
const { Name } = this.plugin.settings;
|
||||
if (Name === "") {
|
||||
new Notice("Name is empty");
|
||||
return;
|
||||
}
|
||||
const { URL, MethodRequest, DataResponse, DataRequest, HeaderRequest } = this.plugin.settings;
|
||||
const { URLs } = this.plugin.settings;
|
||||
URLs.push({
|
||||
'URL': URL,
|
||||
'Name': Name,
|
||||
'MethodRequest': MethodRequest,
|
||||
'DataRequest': DataRequest,
|
||||
'HeaderRequest': HeaderRequest,
|
||||
'DataResponse': DataResponse
|
||||
});
|
||||
await this.plugin.saveSettings();
|
||||
this.display();
|
||||
this.plugin.addCommand({
|
||||
id: 'response-in-document-' + Name,
|
||||
name: 'Response for api: ' + Name,
|
||||
editorCallback: (editor: Editor) => {
|
||||
const rea = URLs[URLs.length - 1];
|
||||
toDocument(rea, editor);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
containerEl.createEl('hr');
|
||||
containerEl.createEl('hr');
|
||||
|
||||
containerEl.createEl('h2', { text: 'Codeblock Settings' });
|
||||
new Setting(containerEl)
|
||||
.setName('Text when request is Disabled')
|
||||
.setDesc("What to show when a request is disabled")
|
||||
.addText(text => text
|
||||
.setPlaceholder('This request is disabled')
|
||||
.setValue(this.plugin.settings.DisabledReq)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.DisabledReq = value;
|
||||
await this.plugin.saveSettings();
|
||||
}));
|
||||
|
||||
containerEl.createEl('hr');
|
||||
|
||||
containerEl.createEl('h2', { text: 'Manage Requests' });
|
||||
this.displayInfoApirs(containerEl);
|
||||
|
||||
new Setting(containerEl)
|
||||
.addButton(button => {
|
||||
button.setClass('btn-clear-apir');
|
||||
new Setting(containerEl)
|
||||
.addButton(button => {
|
||||
button.setClass('btn-clear-apir');
|
||||
button.setButtonText("Clear localStorage").onClick(async () => {
|
||||
Object.keys(localStorage).forEach(key => {
|
||||
if (key.startsWith("req-")) {
|
||||
|
|
@ -516,62 +563,62 @@ class APRSettings extends PluginSettingTab {
|
|||
});
|
||||
this.display();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
displayInfoApirs(containerEl: HTMLElement) {
|
||||
displayInfoApirs(containerEl: HTMLElement) {
|
||||
// Render URL table
|
||||
const { URLs } = this.plugin.settings;
|
||||
const ct = containerEl.createEl('div', { cls: 'cocontainer' });
|
||||
if (URLs.length > 0) {
|
||||
const tableContainer = ct.createEl('div', { cls: 'table-container' });
|
||||
const { URLs } = this.plugin.settings;
|
||||
const ct = containerEl.createEl('div', { cls: 'cocontainer' });
|
||||
if (URLs.length > 0) {
|
||||
const tableContainer = ct.createEl('div', { cls: 'table-container' });
|
||||
|
||||
const table = tableContainer.createEl('table', { cls: 'api-table' });
|
||||
const thead = table.createEl('thead');
|
||||
const headerRow = thead.createEl('tr');
|
||||
headerRow.createEl('th', { text: 'Name' });
|
||||
headerRow.createEl('th', { text: 'URL' });
|
||||
const table = tableContainer.createEl('table', { cls: 'api-table' });
|
||||
const thead = table.createEl('thead');
|
||||
const headerRow = thead.createEl('tr');
|
||||
headerRow.createEl('th', { text: 'Name' });
|
||||
headerRow.createEl('th', { text: 'URL' });
|
||||
|
||||
const tbody = table.createEl('tbody');
|
||||
URLs.forEach((url) => {
|
||||
const row = tbody.createEl('tr');
|
||||
const tbody = table.createEl('tbody');
|
||||
URLs.forEach((url) => {
|
||||
const row = tbody.createEl('tr');
|
||||
|
||||
row.createEl('td', { text: url.Name });
|
||||
row.createEl('td', { text: url.Name });
|
||||
|
||||
const urlCell = row.createEl('td');
|
||||
urlCell.createEl('a', { text: url.URL.length > 50 ? url.URL.substring(0, 50) + "..." : url.URL, cls: 'api-url' });
|
||||
const urlCell = row.createEl('td');
|
||||
urlCell.createEl('a', { text: url.URL.length > 50 ? url.URL.substring(0, 50) + "..." : url.URL, cls: 'api-url' });
|
||||
|
||||
urlCell.addEventListener('click', async () => {
|
||||
const index = URLs.indexOf(url);
|
||||
URLs.splice(index, 1);
|
||||
await this.plugin.saveSettings();
|
||||
this.display();
|
||||
});
|
||||
});
|
||||
}
|
||||
urlCell.addEventListener('click', async () => {
|
||||
const index = URLs.indexOf(url);
|
||||
URLs.splice(index, 1);
|
||||
await this.plugin.saveSettings();
|
||||
this.display();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Render localStorage table
|
||||
const tableContainer = containerEl.createEl('div', { cls: 'table-container full-width' });
|
||||
const table = ct.createEl('table', { cls: 'api-table full-width' });
|
||||
const thead = table.createEl('thead');
|
||||
const headerRow = thead.createEl('tr');
|
||||
let hr = headerRow.createEl('th', { text: 'ID' });
|
||||
// Render localStorage table
|
||||
containerEl.createEl('div', { cls: 'table-container full-width' });
|
||||
const table = ct.createEl('table', { cls: 'api-table full-width' });
|
||||
const thead = table.createEl('thead');
|
||||
const headerRow = thead.createEl('tr');
|
||||
const hr = headerRow.createEl('th', { text: 'ID' });
|
||||
|
||||
const tbody = table.createEl('tbody');
|
||||
Object.keys(localStorage).forEach(key => {
|
||||
if (key.startsWith("req-")) {
|
||||
const row = tbody.createEl('tr');
|
||||
const idCell = row.createEl('td', { text: key });
|
||||
const tbody = table.createEl('tbody');
|
||||
Object.keys(localStorage).forEach(key => {
|
||||
if (key.startsWith("req-")) {
|
||||
const row = tbody.createEl('tr');
|
||||
const idCell = row.createEl('td', { text: key });
|
||||
|
||||
idCell.addEventListener('click', async () => {
|
||||
localStorage.removeItem(key);
|
||||
this.display();
|
||||
});
|
||||
}
|
||||
});
|
||||
// if table is empty
|
||||
if (tbody.children.length === 0) {
|
||||
hr.innerText = 'No response saved';
|
||||
idCell.addEventListener('click', async () => {
|
||||
localStorage.removeItem(key);
|
||||
this.display();
|
||||
});
|
||||
}
|
||||
});
|
||||
// if table is empty
|
||||
if (tbody.children.length === 0) {
|
||||
hr.innerText = 'No response saved';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
export class MarkdownParser {
|
||||
parse(text) {
|
||||
// Remove all <script> tags
|
||||
text = text.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
|
||||
|
||||
// Headers
|
||||
text = text.replace(/^(#{1,6})\s*(.*)$/gm, (match, p1, p2) => `<h${p1.length}>${p2}</h${p1.length}>`);
|
||||
|
||||
|
|
@ -24,7 +27,7 @@ export class MarkdownParser {
|
|||
text = text.replace(/\*(.*?)\*/g, '<em>$1</em>');
|
||||
|
||||
// Images
|
||||
text = text.replace(/\!\[([^\]]+)\]\(([^)]+)\)/g, '<img src="$2" alt="$1">');
|
||||
text = text.replace(/!\[([^\]]+)\]\(([^)]+)\)/g, '<img src="$2" alt="$1">');
|
||||
|
||||
// Links
|
||||
text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
|
||||
|
|
@ -57,8 +60,6 @@ export class MarkdownParser {
|
|||
let bodyEnd = '</tbody>\n';
|
||||
let rowStart = '<tr>\n';
|
||||
let rowEnd = '</tr>\n';
|
||||
let cellStart = '<td>';
|
||||
let cellEnd = '</td>\n';
|
||||
let headerRow = rowStart + headerCells.map(cell => `<th>${cell}</th>`).join('\n') + rowEnd;
|
||||
let bodyRows = rows.map(row => {
|
||||
let cells = row.split('|').map(cell => cell.trim()).filter(cell => cell);
|
||||
|
|
|
|||
Loading…
Reference in a new issue