Merge branch 'master' into feature/fast-url
This commit is contained in:
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"trailingComma": "es5",
|
|
||||||
"semi": false,
|
|
||||||
"singleQuote": false,
|
|
||||||
"printWidth": 100
|
|
||||||
}
|
|
||||||
@@ -5,26 +5,26 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.show-if-initialized {
|
.show-if-initialized {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
&.initialized {
|
&.initialized {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
|
||||||
|
|
||||||
& > * {
|
|
||||||
transition: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const DEFAULT_THEME = "twilight"
|
const DEFAULT_THEME = "twilight"
|
||||||
|
|
||||||
import ace from "ace-builds";
|
import ace from "ace-builds"
|
||||||
import "ace-builds/webpack-resolver";
|
import "ace-builds/webpack-resolver"
|
||||||
import jsonParse from '../functions/jsonParse';
|
import jsonParse from "../functions/jsonParse"
|
||||||
import debounce from '../functions/utils/debounce';
|
import debounce from "../functions/utils/debounce"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@@ -40,6 +40,11 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: "json",
|
default: "json",
|
||||||
},
|
},
|
||||||
|
lint: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
options: {
|
options: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
@@ -57,19 +62,18 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
value(value) {
|
value(value) {
|
||||||
if (value !== this.cacheValue) {
|
if (value !== this.cacheValue) {
|
||||||
this.editor.session.setValue(value, 1);
|
this.editor.session.setValue(value, 1)
|
||||||
this.cacheValue = value;
|
this.cacheValue = value
|
||||||
|
if (this.lint) this.provideLinting(value)
|
||||||
this.provideLinting(value);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
theme() {
|
theme() {
|
||||||
this.initialized = false;
|
this.initialized = false
|
||||||
this.editor.setTheme(`ace/theme/${this.defineTheme()}`, () => {
|
this.editor.setTheme(`ace/theme/${this.defineTheme()}`, () => {
|
||||||
this.$nextTick().then(() => {
|
this.$nextTick().then(() => {
|
||||||
this.initialized = true;
|
this.initialized = true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
lang(value) {
|
lang(value) {
|
||||||
this.editor.getSession().setMode("ace/mode/" + value)
|
this.editor.getSession().setMode("ace/mode/" + value)
|
||||||
@@ -88,23 +92,24 @@ export default {
|
|||||||
// Set the theme and show the editor only after it's been set to prevent FOUC.
|
// Set the theme and show the editor only after it's been set to prevent FOUC.
|
||||||
editor.setTheme(`ace/theme/${this.defineTheme()}`, () => {
|
editor.setTheme(`ace/theme/${this.defineTheme()}`, () => {
|
||||||
this.$nextTick().then(() => {
|
this.$nextTick().then(() => {
|
||||||
this.initialized = true;
|
this.initialized = true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
if (this.value) editor.setValue(this.value, 1);
|
if (this.value) editor.setValue(this.value, 1)
|
||||||
|
|
||||||
this.editor = editor
|
this.editor = editor
|
||||||
this.cacheValue = this.value
|
this.cacheValue = this.value
|
||||||
|
|
||||||
editor.on("change", () => {
|
editor.on("change", () => {
|
||||||
const content = editor.getValue();
|
const content = editor.getValue()
|
||||||
this.$emit("input", content);
|
this.$emit("input", content)
|
||||||
this.cacheValue = content;
|
this.cacheValue = content
|
||||||
this.provideLinting(content);
|
if (this.lint) this.provideLinting(content)
|
||||||
});
|
})
|
||||||
|
|
||||||
this.provideLinting(this.value);
|
// Disable linting, if lint prop is false
|
||||||
|
if (this.lint) this.provideLinting(this.value)
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -112,33 +117,31 @@ export default {
|
|||||||
if (this.theme) {
|
if (this.theme) {
|
||||||
return this.theme
|
return this.theme
|
||||||
}
|
}
|
||||||
return (
|
return this.$store.state.postwoman.settings.THEME_ACE_EDITOR || DEFAULT_THEME
|
||||||
this.$store.state.postwoman.settings.THEME_ACE_EDITOR || DEFAULT_THEME
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
provideLinting: debounce(function (code) {
|
provideLinting: debounce(function(code) {
|
||||||
if (this.lang === "json") {
|
if (this.lang === "json") {
|
||||||
try {
|
try {
|
||||||
jsonParse(code);
|
jsonParse(code)
|
||||||
this.editor.session.setAnnotations([]);
|
this.editor.session.setAnnotations([])
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const pos = this.editor.session.getDocument().indexToPosition(e.start, 0);
|
const pos = this.editor.session.getDocument().indexToPosition(e.start, 0)
|
||||||
this.editor.session.setAnnotations([
|
this.editor.session.setAnnotations([
|
||||||
{
|
{
|
||||||
row: pos.row,
|
row: pos.row,
|
||||||
column: pos.column,
|
column: pos.column,
|
||||||
text: e.message,
|
text: e.message,
|
||||||
type: "error"
|
type: "error",
|
||||||
}
|
},
|
||||||
]);
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 2000)
|
}, 2000),
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyed() {
|
destroyed() {
|
||||||
this.editor.destroy();
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
<legend @click.prevent="collapse">
|
<legend @click.prevent="collapse">
|
||||||
<span>{{ label }}</span>
|
<span>{{ label }}</span>
|
||||||
<i class="material-icons">
|
<i class="material-icons">
|
||||||
{{ isCollapsed ? "expand_more" : "expand_less" }}
|
{{ isCollapsed(label) ? "expand_more" : "expand_less" }}
|
||||||
</i>
|
</i>
|
||||||
</legend>
|
</legend>
|
||||||
<div class="collapsible" :class="{ hidden: collapsed }">
|
<div class="collapsible" :class="{ hidden: isCollapsed(label.toLowerCase()) }">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -24,12 +24,9 @@ export default {
|
|||||||
frameColorsEnabled() {
|
frameColorsEnabled() {
|
||||||
return this.$store.state.postwoman.settings.FRAME_COLORS_ENABLED || false
|
return this.$store.state.postwoman.settings.FRAME_COLORS_ENABLED || false
|
||||||
},
|
},
|
||||||
},
|
sectionString() {
|
||||||
|
return `${this.$route.path.replace(/\/+$/, "")}/${this.label}`
|
||||||
data() {
|
},
|
||||||
return {
|
|
||||||
isCollapsed: false,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
@@ -46,7 +43,12 @@ export default {
|
|||||||
collapse({ target }) {
|
collapse({ target }) {
|
||||||
const parent = target.parentNode.parentNode
|
const parent = target.parentNode.parentNode
|
||||||
parent.querySelector(".collapsible").classList.toggle("hidden")
|
parent.querySelector(".collapsible").classList.toggle("hidden")
|
||||||
this.isCollapsed = !this.isCollapsed
|
|
||||||
|
// Save collapsed section into the collapsedSections array
|
||||||
|
this.$store.commit("setCollapsedSection", this.sectionString)
|
||||||
|
},
|
||||||
|
isCollapsed(label) {
|
||||||
|
return this.$store.state.theme.collapsedSections.includes(this.sectionString) || false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,152 +20,152 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export default function jsonParse(str) {
|
export default function jsonParse(str) {
|
||||||
string = str;
|
string = str
|
||||||
strLen = str.length;
|
strLen = str.length
|
||||||
start = end = lastEnd = -1;
|
start = end = lastEnd = -1
|
||||||
ch();
|
ch()
|
||||||
lex();
|
lex()
|
||||||
const ast = parseObj();
|
const ast = parseObj()
|
||||||
expect('EOF');
|
expect("EOF")
|
||||||
return ast;
|
return ast
|
||||||
}
|
}
|
||||||
|
|
||||||
let string;
|
let string
|
||||||
let strLen;
|
let strLen
|
||||||
let start;
|
let start
|
||||||
let end;
|
let end
|
||||||
let lastEnd;
|
let lastEnd
|
||||||
let code;
|
let code
|
||||||
let kind;
|
let kind
|
||||||
|
|
||||||
function parseObj() {
|
function parseObj() {
|
||||||
const nodeStart = start;
|
const nodeStart = start
|
||||||
const members = [];
|
const members = []
|
||||||
expect('{');
|
expect("{")
|
||||||
if (!skip('}')) {
|
if (!skip("}")) {
|
||||||
do {
|
do {
|
||||||
members.push(parseMember());
|
members.push(parseMember())
|
||||||
} while (skip(','));
|
} while (skip(","))
|
||||||
expect('}');
|
expect("}")
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
kind: 'Object',
|
kind: "Object",
|
||||||
start: nodeStart,
|
start: nodeStart,
|
||||||
end: lastEnd,
|
end: lastEnd,
|
||||||
members,
|
members,
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseMember() {
|
function parseMember() {
|
||||||
const nodeStart = start;
|
const nodeStart = start
|
||||||
const key = kind === 'String' ? curToken() : null;
|
const key = kind === "String" ? curToken() : null
|
||||||
expect('String');
|
expect("String")
|
||||||
expect(':');
|
expect(":")
|
||||||
const value = parseVal();
|
const value = parseVal()
|
||||||
return {
|
return {
|
||||||
kind: 'Member',
|
kind: "Member",
|
||||||
start: nodeStart,
|
start: nodeStart,
|
||||||
end: lastEnd,
|
end: lastEnd,
|
||||||
key,
|
key,
|
||||||
value,
|
value,
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseArr() {
|
function parseArr() {
|
||||||
const nodeStart = start;
|
const nodeStart = start
|
||||||
const values = [];
|
const values = []
|
||||||
expect('[');
|
expect("[")
|
||||||
if (!skip(']')) {
|
if (!skip("]")) {
|
||||||
do {
|
do {
|
||||||
values.push(parseVal());
|
values.push(parseVal())
|
||||||
} while (skip(','));
|
} while (skip(","))
|
||||||
expect(']');
|
expect("]")
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
kind: 'Array',
|
kind: "Array",
|
||||||
start: nodeStart,
|
start: nodeStart,
|
||||||
end: lastEnd,
|
end: lastEnd,
|
||||||
values,
|
values,
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseVal() {
|
function parseVal() {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case '[':
|
case "[":
|
||||||
return parseArr();
|
return parseArr()
|
||||||
case '{':
|
case "{":
|
||||||
return parseObj();
|
return parseObj()
|
||||||
case 'String':
|
case "String":
|
||||||
case 'Number':
|
case "Number":
|
||||||
case 'Boolean':
|
case "Boolean":
|
||||||
case 'Null':
|
case "Null":
|
||||||
const token = curToken();
|
const token = curToken()
|
||||||
lex();
|
lex()
|
||||||
return token;
|
return token
|
||||||
}
|
}
|
||||||
return expect('Value');
|
return expect("Value")
|
||||||
}
|
}
|
||||||
|
|
||||||
function curToken() {
|
function curToken() {
|
||||||
return { kind, start, end, value: JSON.parse(string.slice(start, end)) };
|
return { kind, start, end, value: JSON.parse(string.slice(start, end)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
function expect(str) {
|
function expect(str) {
|
||||||
if (kind === str) {
|
if (kind === str) {
|
||||||
lex();
|
lex()
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let found;
|
let found
|
||||||
if (kind === 'EOF') {
|
if (kind === "EOF") {
|
||||||
found = '[end of file]';
|
found = "[end of file]"
|
||||||
} else if (end - start > 1) {
|
} else if (end - start > 1) {
|
||||||
found = '`' + string.slice(start, end) + '`';
|
found = "`" + string.slice(start, end) + "`"
|
||||||
} else {
|
} else {
|
||||||
const match = string.slice(start).match(/^.+?\b/);
|
const match = string.slice(start).match(/^.+?\b/)
|
||||||
found = '`' + (match ? match[0] : string[start]) + '`';
|
found = "`" + (match ? match[0] : string[start]) + "`"
|
||||||
}
|
}
|
||||||
|
|
||||||
throw syntaxError(`Expected ${str} but found ${found}.`);
|
throw syntaxError(`Expected ${str} but found ${found}.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function syntaxError(message) {
|
function syntaxError(message) {
|
||||||
return { message, start, end };
|
return { message, start, end }
|
||||||
}
|
}
|
||||||
|
|
||||||
function skip(k) {
|
function skip(k) {
|
||||||
if (kind === k) {
|
if (kind === k) {
|
||||||
lex();
|
lex()
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ch() {
|
function ch() {
|
||||||
if (end < strLen) {
|
if (end < strLen) {
|
||||||
end++;
|
end++
|
||||||
code = end === strLen ? 0 : string.charCodeAt(end);
|
code = end === strLen ? 0 : string.charCodeAt(end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function lex() {
|
function lex() {
|
||||||
lastEnd = end;
|
lastEnd = end
|
||||||
|
|
||||||
while (code === 9 || code === 10 || code === 13 || code === 32) {
|
while (code === 9 || code === 10 || code === 13 || code === 32) {
|
||||||
ch();
|
ch()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
kind = 'EOF';
|
kind = "EOF"
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
start = end;
|
start = end
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
// "
|
// "
|
||||||
case 34:
|
case 34:
|
||||||
kind = 'String';
|
kind = "String"
|
||||||
return readString();
|
return readString()
|
||||||
// -, 0-9
|
// -, 0-9
|
||||||
case 45:
|
case 45:
|
||||||
case 48:
|
case 48:
|
||||||
@@ -178,50 +178,50 @@ function lex() {
|
|||||||
case 55:
|
case 55:
|
||||||
case 56:
|
case 56:
|
||||||
case 57:
|
case 57:
|
||||||
kind = 'Number';
|
kind = "Number"
|
||||||
return readNumber();
|
return readNumber()
|
||||||
// f
|
// f
|
||||||
case 102:
|
case 102:
|
||||||
if (string.slice(start, start + 5) !== 'false') {
|
if (string.slice(start, start + 5) !== "false") {
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
end += 4;
|
end += 4
|
||||||
ch();
|
ch()
|
||||||
|
|
||||||
kind = 'Boolean';
|
kind = "Boolean"
|
||||||
return;
|
return
|
||||||
// n
|
// n
|
||||||
case 110:
|
case 110:
|
||||||
if (string.slice(start, start + 4) !== 'null') {
|
if (string.slice(start, start + 4) !== "null") {
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
end += 3;
|
end += 3
|
||||||
ch();
|
ch()
|
||||||
|
|
||||||
kind = 'Null';
|
kind = "Null"
|
||||||
return;
|
return
|
||||||
// t
|
// t
|
||||||
case 116:
|
case 116:
|
||||||
if (string.slice(start, start + 4) !== 'true') {
|
if (string.slice(start, start + 4) !== "true") {
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
end += 3;
|
end += 3
|
||||||
ch();
|
ch()
|
||||||
|
|
||||||
kind = 'Boolean';
|
kind = "Boolean"
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
kind = string[start];
|
kind = string[start]
|
||||||
ch();
|
ch()
|
||||||
}
|
}
|
||||||
|
|
||||||
function readString() {
|
function readString() {
|
||||||
ch();
|
ch()
|
||||||
while (code !== 34 && code > 31) {
|
while (code !== 34 && code > 31) {
|
||||||
if (code === 92) {
|
if (code === 92) {
|
||||||
// \
|
// \
|
||||||
ch();
|
ch()
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 34: // "
|
case 34: // "
|
||||||
case 47: // /
|
case 47: // /
|
||||||
@@ -231,31 +231,31 @@ function readString() {
|
|||||||
case 110: // n
|
case 110: // n
|
||||||
case 114: // r
|
case 114: // r
|
||||||
case 116: // t
|
case 116: // t
|
||||||
ch();
|
ch()
|
||||||
break;
|
break
|
||||||
case 117: // u
|
case 117: // u
|
||||||
ch();
|
ch()
|
||||||
readHex();
|
readHex()
|
||||||
readHex();
|
readHex()
|
||||||
readHex();
|
readHex()
|
||||||
readHex();
|
readHex()
|
||||||
break;
|
break
|
||||||
default:
|
default:
|
||||||
throw syntaxError('Bad character escape sequence.');
|
throw syntaxError("Bad character escape sequence.")
|
||||||
}
|
}
|
||||||
} else if (end === strLen) {
|
} else if (end === strLen) {
|
||||||
throw syntaxError('Unterminated string.');
|
throw syntaxError("Unterminated string.")
|
||||||
} else {
|
} else {
|
||||||
ch();
|
ch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code === 34) {
|
if (code === 34) {
|
||||||
ch();
|
ch()
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
throw syntaxError('Unterminated string.');
|
throw syntaxError("Unterminated string.")
|
||||||
}
|
}
|
||||||
|
|
||||||
function readHex() {
|
function readHex() {
|
||||||
@@ -264,47 +264,47 @@ function readHex() {
|
|||||||
(code >= 65 && code <= 70) || // A-F
|
(code >= 65 && code <= 70) || // A-F
|
||||||
(code >= 97 && code <= 102) // a-f
|
(code >= 97 && code <= 102) // a-f
|
||||||
) {
|
) {
|
||||||
return ch();
|
return ch()
|
||||||
}
|
}
|
||||||
throw syntaxError('Expected hexadecimal digit.');
|
throw syntaxError("Expected hexadecimal digit.")
|
||||||
}
|
}
|
||||||
|
|
||||||
function readNumber() {
|
function readNumber() {
|
||||||
if (code === 45) {
|
if (code === 45) {
|
||||||
// -
|
// -
|
||||||
ch();
|
ch()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code === 48) {
|
if (code === 48) {
|
||||||
// 0
|
// 0
|
||||||
ch();
|
ch()
|
||||||
} else {
|
} else {
|
||||||
readDigits();
|
readDigits()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code === 46) {
|
if (code === 46) {
|
||||||
// .
|
// .
|
||||||
ch();
|
ch()
|
||||||
readDigits();
|
readDigits()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code === 69 || code === 101) {
|
if (code === 69 || code === 101) {
|
||||||
// E e
|
// E e
|
||||||
ch();
|
ch()
|
||||||
if (code === 43 || code === 45) {
|
if (code === 43 || code === 45) {
|
||||||
// + -
|
// + -
|
||||||
ch();
|
ch()
|
||||||
}
|
}
|
||||||
readDigits();
|
readDigits()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readDigits() {
|
function readDigits() {
|
||||||
if (code < 48 || code > 57) {
|
if (code < 48 || code > 57) {
|
||||||
// 0 - 9
|
// 0 - 9
|
||||||
throw syntaxError('Expected decimal digit.');
|
throw syntaxError("Expected decimal digit.")
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
ch();
|
ch()
|
||||||
} while (code >= 48 && code <= 57); // 0 - 9
|
} while (code >= 48 && code <= 57) // 0 - 9
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -758,7 +758,11 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
let showExtensionsToast = localStorage.getItem("showExtensionsToast") === "yes"
|
let showExtensionsToast = localStorage.getItem("showExtensionsToast") === "yes"
|
||||||
if (!this.extensionInstalled && !showExtensionsToast) {
|
|
||||||
|
// Just return if showExtensionsToast is "no"
|
||||||
|
if (!showExtensionsToast) return
|
||||||
|
|
||||||
|
if (!this.extensionInstalled) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$toast.show(this.$t("extensions_info2"), {
|
this.$toast.show(this.$t("extensions_info2"), {
|
||||||
icon: "extension",
|
icon: "extension",
|
||||||
@@ -776,6 +780,11 @@ export default {
|
|||||||
{
|
{
|
||||||
text: this.$t("no"),
|
text: this.$t("no"),
|
||||||
onClick: (e, toastObject) => {
|
onClick: (e, toastObject) => {
|
||||||
|
this.$store.commit("setMiscState", {
|
||||||
|
value: false,
|
||||||
|
attribute: "showExtensionsToast",
|
||||||
|
})
|
||||||
|
localStorage.setItem("showExtensionsToast", "no")
|
||||||
toastObject.goAway(0)
|
toastObject.goAway(0)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -7344,9 +7344,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"version": "10.0.7",
|
"version": "10.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.0.8.tgz",
|
||||||
"integrity": "sha512-Byj0F4l7GYUpYYHEqyFH69NiI6ICTg0CeCKbhRorL+ickbzILKUlZLiyCkljZV02wnoh7yH7PmFyYm9PRNwk9g==",
|
"integrity": "sha512-Oa9eS4DJqvQMVdywXfEor6F4vP+21fPHF8LUXgBbVWUSWBddjqsvO6Bv1LwMChmgQZZqwUvgJSHlu8HFHAPZmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "^3.0.0",
|
"chalk": "^3.0.0",
|
||||||
|
|||||||
13
package.json
13
package.json
@@ -18,6 +18,17 @@
|
|||||||
"pretty-quick": "pretty-quick --pattern \"**/*.*(html|js|json|vue)\"",
|
"pretty-quick": "pretty-quick --pattern \"**/*.*(html|js|json|vue)\"",
|
||||||
"test": "start-server-and-test start http-get://localhost:3000 e2e"
|
"test": "start-server-and-test start http-get://localhost:3000 e2e"
|
||||||
},
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "npm run pretty-quick"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": false,
|
||||||
|
"printWidth": 100
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/axios": "^5.9.5",
|
"@nuxtjs/axios": "^5.9.5",
|
||||||
"@nuxtjs/google-analytics": "^2.2.3",
|
"@nuxtjs/google-analytics": "^2.2.3",
|
||||||
@@ -42,7 +53,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cypress": "^4.0.2",
|
"cypress": "^4.0.2",
|
||||||
"husky": "^4.2.3",
|
"husky": "^4.2.3",
|
||||||
"lint-staged": "^10.0.7",
|
"lint-staged": "^10.0.8",
|
||||||
"node-sass": "^4.13.1",
|
"node-sass": "^4.13.1",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^1.19.1",
|
||||||
"pretty-quick": "^2.0.1",
|
"pretty-quick": "^2.0.1",
|
||||||
|
|||||||
@@ -6,7 +6,13 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<label for="url">{{ $t("url") }}</label>
|
<label for="url">{{ $t("url") }}</label>
|
||||||
<input id="url" type="url" v-model="url" @keyup.enter="getSchema()" />
|
<input
|
||||||
|
id="url"
|
||||||
|
type="url"
|
||||||
|
v-model="url"
|
||||||
|
spellcheck="false"
|
||||||
|
@keyup.enter="getSchema()"
|
||||||
|
/>
|
||||||
</li>
|
</li>
|
||||||
<div>
|
<div>
|
||||||
<li>
|
<li>
|
||||||
@@ -129,7 +135,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Editor
|
<Editor
|
||||||
:value="schemaString"
|
:value="schema"
|
||||||
:lang="'graphqlschema'"
|
:lang="'graphqlschema'"
|
||||||
:options="{
|
:options="{
|
||||||
maxLines: responseBodyMaxLines,
|
maxLines: responseBodyMaxLines,
|
||||||
@@ -144,10 +150,10 @@
|
|||||||
</pw-section>
|
</pw-section>
|
||||||
|
|
||||||
<pw-section class="cyan" :label="$t('query')" ref="query">
|
<pw-section class="cyan" :label="$t('query')" ref="query">
|
||||||
<div class="flex-wrap">
|
<div class="flex-wrap gqlRunQuery">
|
||||||
<label for="gqlQuery">{{ $t("query") }}</label>
|
<label for="gqlQuery">{{ $t("query") }}</label>
|
||||||
<div>
|
<div>
|
||||||
<button class="icon" @click="runQuery()" v-tooltip.bottom="$t('run_query')">
|
<button @click="runQuery()" v-tooltip.bottom="$t('run_query')">
|
||||||
<i class="material-icons">play_arrow</i>
|
<i class="material-icons">play_arrow</i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@@ -204,8 +210,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Editor
|
<Editor
|
||||||
:value="responseString"
|
:value="response"
|
||||||
:lang="'json'"
|
:lang="'json'"
|
||||||
|
:lint="false"
|
||||||
:options="{
|
:options="{
|
||||||
maxLines: responseBodyMaxLines,
|
maxLines: responseBodyMaxLines,
|
||||||
minLines: '16',
|
minLines: '16',
|
||||||
@@ -308,6 +315,9 @@
|
|||||||
max-height: calc(100vh - 186px);
|
max-height: calc(100vh - 186px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
.gqlRunQuery {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -333,18 +343,23 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
schemaString: "",
|
|
||||||
commonHeaders,
|
commonHeaders,
|
||||||
queryFields: [],
|
queryFields: [],
|
||||||
mutationFields: [],
|
mutationFields: [],
|
||||||
subscriptionFields: [],
|
subscriptionFields: [],
|
||||||
gqlTypes: [],
|
gqlTypes: [],
|
||||||
responseString: "",
|
|
||||||
copyButton: '<i class="material-icons">file_copy</i>',
|
copyButton: '<i class="material-icons">file_copy</i>',
|
||||||
downloadButton: '<i class="material-icons">get_app</i>',
|
downloadButton: '<i class="material-icons">get_app</i>',
|
||||||
doneButton: '<i class="material-icons">done</i>',
|
doneButton: '<i class="material-icons">done</i>',
|
||||||
expandResponse: false,
|
expandResponse: false,
|
||||||
responseBodyMaxLines: 16,
|
responseBodyMaxLines: 16,
|
||||||
|
|
||||||
|
settings: {
|
||||||
|
SCROLL_INTO_ENABLED:
|
||||||
|
typeof this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED !== "undefined"
|
||||||
|
? this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED
|
||||||
|
: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -373,6 +388,22 @@ export default {
|
|||||||
this.$store.commit("setGQLState", { value, attribute: "query" })
|
this.$store.commit("setGQLState", { value, attribute: "query" })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
response: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.gql.response
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$store.commit("setGQLState", { value, attribute: "response" })
|
||||||
|
},
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.gql.schema
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$store.commit("setGQLState", { value, attribute: "schema" })
|
||||||
|
},
|
||||||
|
},
|
||||||
variableString: {
|
variableString: {
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.gql.variablesJSONString
|
return this.$store.state.gql.variablesJSONString
|
||||||
@@ -400,7 +431,7 @@ export default {
|
|||||||
const rootTypeName = this.resolveRootType(type).name
|
const rootTypeName = this.resolveRootType(type).name
|
||||||
|
|
||||||
const target = document.getElementById(`type_${rootTypeName}`)
|
const target = document.getElementById(`type_${rootTypeName}`)
|
||||||
if (target && this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED) {
|
if (target && this.settings.SCROLL_INTO_ENABLED) {
|
||||||
target.scrollIntoView({
|
target.scrollIntoView({
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
})
|
})
|
||||||
@@ -414,7 +445,7 @@ export default {
|
|||||||
copySchema() {
|
copySchema() {
|
||||||
this.$refs.copySchemaCode.innerHTML = this.doneButton
|
this.$refs.copySchemaCode.innerHTML = this.doneButton
|
||||||
const aux = document.createElement("textarea")
|
const aux = document.createElement("textarea")
|
||||||
aux.innerText = this.schemaString
|
aux.innerText = this.schema
|
||||||
document.body.appendChild(aux)
|
document.body.appendChild(aux)
|
||||||
aux.select()
|
aux.select()
|
||||||
document.execCommand("copy")
|
document.execCommand("copy")
|
||||||
@@ -440,7 +471,7 @@ export default {
|
|||||||
copyResponse() {
|
copyResponse() {
|
||||||
this.$refs.copyResponseButton.innerHTML = this.doneButton
|
this.$refs.copyResponseButton.innerHTML = this.doneButton
|
||||||
const aux = document.createElement("textarea")
|
const aux = document.createElement("textarea")
|
||||||
aux.innerText = this.responseString
|
aux.innerText = this.response
|
||||||
document.body.appendChild(aux)
|
document.body.appendChild(aux)
|
||||||
aux.select()
|
aux.select()
|
||||||
document.execCommand("copy")
|
document.execCommand("copy")
|
||||||
@@ -453,8 +484,12 @@ export default {
|
|||||||
async runQuery() {
|
async runQuery() {
|
||||||
const startTime = Date.now()
|
const startTime = Date.now()
|
||||||
|
|
||||||
|
// Start showing the loading bar as soon as possible.
|
||||||
|
// The nuxt axios module will hide it when the request is made.
|
||||||
this.$nuxt.$loading.start()
|
this.$nuxt.$loading.start()
|
||||||
this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED && this.scrollInto("response")
|
|
||||||
|
this.response = this.$t("loading")
|
||||||
|
if (this.settings.SCROLL_INTO_ENABLED) this.scrollInto("response")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let headers = {}
|
let headers = {}
|
||||||
@@ -477,8 +512,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await sendNetworkRequest(reqOptions, this.$store)
|
const data = await sendNetworkRequest(reqOptions, this.$store)
|
||||||
|
this.response = JSON.stringify(data.data, null, 2)
|
||||||
this.responseString = JSON.stringify(data.data, null, 2)
|
|
||||||
|
|
||||||
this.$nuxt.$loading.finish()
|
this.$nuxt.$loading.finish()
|
||||||
const duration = Date.now() - startTime
|
const duration = Date.now() - startTime
|
||||||
@@ -486,6 +520,7 @@ export default {
|
|||||||
icon: "done",
|
icon: "done",
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
this.response = `${error}. ${this.$t("check_console_details")}`
|
||||||
this.$nuxt.$loading.finish()
|
this.$nuxt.$loading.finish()
|
||||||
|
|
||||||
this.$toast.error(`${error} ${this.$t("f12_details")}`, {
|
this.$toast.error(`${error} ${this.$t("f12_details")}`, {
|
||||||
@@ -496,13 +531,14 @@ export default {
|
|||||||
},
|
},
|
||||||
async getSchema() {
|
async getSchema() {
|
||||||
const startTime = Date.now()
|
const startTime = Date.now()
|
||||||
this.schemaString = this.$t("loading")
|
|
||||||
this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED && this.scrollInto("schema")
|
|
||||||
|
|
||||||
// Start showing the loading bar as soon as possible.
|
// Start showing the loading bar as soon as possible.
|
||||||
// The nuxt axios module will hide it when the request is made.
|
// The nuxt axios module will hide it when the request is made.
|
||||||
this.$nuxt.$loading.start()
|
this.$nuxt.$loading.start()
|
||||||
|
|
||||||
|
this.schema = this.$t("loading")
|
||||||
|
if (this.settings.SCROLL_INTO_ENABLED) this.scrollInto("schema")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const query = JSON.stringify({
|
const query = JSON.stringify({
|
||||||
query: gql.getIntrospectionQuery(),
|
query: gql.getIntrospectionQuery(),
|
||||||
@@ -523,8 +559,6 @@ export default {
|
|||||||
data: query,
|
data: query,
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(reqOptions);
|
|
||||||
|
|
||||||
const reqConfig = this.$store.state.postwoman.settings.PROXY_ENABLED
|
const reqConfig = this.$store.state.postwoman.settings.PROXY_ENABLED
|
||||||
? {
|
? {
|
||||||
method: "post",
|
method: "post",
|
||||||
@@ -537,9 +571,8 @@ export default {
|
|||||||
const res = await axios(reqConfig)
|
const res = await axios(reqConfig)
|
||||||
|
|
||||||
const data = this.$store.state.postwoman.settings.PROXY_ENABLED ? res.data : res
|
const data = this.$store.state.postwoman.settings.PROXY_ENABLED ? res.data : res
|
||||||
|
|
||||||
const schema = gql.buildClientSchema(data.data.data)
|
const schema = gql.buildClientSchema(data.data.data)
|
||||||
this.schemaString = gql.printSchema(schema, {
|
this.schema = gql.printSchema(schema, {
|
||||||
commentDescriptions: true,
|
commentDescriptions: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -597,7 +630,8 @@ export default {
|
|||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$nuxt.$loading.finish()
|
this.$nuxt.$loading.finish()
|
||||||
this.schemaString = `${error}. ${this.$t("check_console_details")}`
|
|
||||||
|
this.schema = `${error}. ${this.$t("check_console_details")}`
|
||||||
this.$toast.error(`${error} ${this.$t("f12_details")}`, {
|
this.$toast.error(`${error} ${this.$t("f12_details")}`, {
|
||||||
icon: "error",
|
icon: "error",
|
||||||
})
|
})
|
||||||
@@ -609,7 +643,7 @@ export default {
|
|||||||
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
|
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
|
||||||
},
|
},
|
||||||
downloadResponse() {
|
downloadResponse() {
|
||||||
const dataToWrite = JSON.stringify(this.schemaString, null, 2)
|
const dataToWrite = JSON.stringify(this.schema, null, 2)
|
||||||
const file = new Blob([dataToWrite], { type: "application/json" })
|
const file = new Blob([dataToWrite], { type: "application/json" })
|
||||||
const a = document.createElement("a")
|
const a = document.createElement("a")
|
||||||
const url = URL.createObjectURL(file)
|
const url = URL.createObjectURL(file)
|
||||||
@@ -650,7 +684,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
// console.log(oldHeaders);
|
|
||||||
},
|
},
|
||||||
scrollInto(view) {
|
scrollInto(view) {
|
||||||
this.$refs[view].$el.scrollIntoView({
|
this.$refs[view].$el.scrollIntoView({
|
||||||
|
|||||||
@@ -185,6 +185,7 @@
|
|||||||
name="url"
|
name="url"
|
||||||
type="url"
|
type="url"
|
||||||
v-model="uri"
|
v-model="uri"
|
||||||
|
spellcheck="false"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<div>
|
<div>
|
||||||
@@ -1424,6 +1425,13 @@ export default {
|
|||||||
files: [],
|
files: [],
|
||||||
filenames: "",
|
filenames: "",
|
||||||
navigatorShare: navigator.share,
|
navigatorShare: navigator.share,
|
||||||
|
|
||||||
|
settings: {
|
||||||
|
SCROLL_INTO_ENABLED:
|
||||||
|
typeof this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED !== "undefined"
|
||||||
|
? this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED
|
||||||
|
: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -1980,7 +1988,7 @@ export default {
|
|||||||
this.path = path
|
this.path = path
|
||||||
this.showPreRequestScript = usesScripts
|
this.showPreRequestScript = usesScripts
|
||||||
this.preRequestScript = preRequestScript
|
this.preRequestScript = preRequestScript
|
||||||
this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED && this.scrollInto("request")
|
if (this.settings.SCROLL_INTO_ENABLED) this.scrollInto("request")
|
||||||
},
|
},
|
||||||
getVariablesFromPreRequestScript() {
|
getVariablesFromPreRequestScript() {
|
||||||
if (!this.preRequestScript) {
|
if (!this.preRequestScript) {
|
||||||
@@ -2015,7 +2023,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async sendRequest() {
|
async sendRequest() {
|
||||||
this.$toast.clear()
|
this.$toast.clear()
|
||||||
this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED && this.scrollInto("response")
|
if (this.settings.SCROLL_INTO_ENABLED) this.scrollInto("response")
|
||||||
if (!this.isValidURL) {
|
if (!this.isValidURL) {
|
||||||
this.$toast.error(this.$t("url_invalid_format"), {
|
this.$toast.error(this.$t("url_invalid_format"), {
|
||||||
icon: "error",
|
icon: "error",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
<input
|
<input
|
||||||
id="url"
|
id="url"
|
||||||
type="url"
|
type="url"
|
||||||
|
spellcheck="false"
|
||||||
:class="{ error: !urlValid }"
|
:class="{ error: !urlValid }"
|
||||||
v-model="url"
|
v-model="url"
|
||||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||||
|
|||||||
@@ -7,6 +7,12 @@ export default {
|
|||||||
gql[attribute] = value
|
gql[attribute] = value
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setCollapsedSection({ theme }, value) {
|
||||||
|
theme.collapsedSections.includes(value)
|
||||||
|
? (theme.collapsedSections = theme.collapsedSections.filter(section => section !== value))
|
||||||
|
: theme.collapsedSections.push(value)
|
||||||
|
},
|
||||||
|
|
||||||
addGQLHeader({ gql }, object) {
|
addGQLHeader({ gql }, object) {
|
||||||
gql.headers.push(object)
|
gql.headers.push(object)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,8 +21,13 @@ export default () => ({
|
|||||||
gql: {
|
gql: {
|
||||||
url: "https://rickandmortyapi.com/graphql",
|
url: "https://rickandmortyapi.com/graphql",
|
||||||
headers: [],
|
headers: [],
|
||||||
|
schema: "",
|
||||||
variablesJSONString: "{}",
|
variablesJSONString: "{}",
|
||||||
query: "",
|
query: "",
|
||||||
|
response: "",
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
collapsedSections: [],
|
||||||
},
|
},
|
||||||
oauth2: {
|
oauth2: {
|
||||||
tokens: [],
|
tokens: [],
|
||||||
|
|||||||
Reference in New Issue
Block a user