You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
5.3 KiB
211 lines
5.3 KiB
Prism.languages.graphql = { |
|
'comment': /#.*/, |
|
'description': { |
|
pattern: /(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i, |
|
greedy: true, |
|
alias: 'string', |
|
inside: { |
|
'language-markdown': { |
|
pattern: /(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/, |
|
lookbehind: true, |
|
inside: Prism.languages.markdown |
|
} |
|
} |
|
}, |
|
'string': { |
|
pattern: /"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/, |
|
greedy: true |
|
}, |
|
'number': /(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i, |
|
'boolean': /\b(?:false|true)\b/, |
|
'variable': /\$[a-z_]\w*/i, |
|
'directive': { |
|
pattern: /@[a-z_]\w*/i, |
|
alias: 'function' |
|
}, |
|
'attr-name': { |
|
pattern: /\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i, |
|
greedy: true |
|
}, |
|
'atom-input': { |
|
pattern: /\b[A-Z]\w*Input\b/, |
|
alias: 'class-name' |
|
}, |
|
'scalar': /\b(?:Boolean|Float|ID|Int|String)\b/, |
|
'constant': /\b[A-Z][A-Z_\d]*\b/, |
|
'class-name': { |
|
pattern: /(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/, |
|
lookbehind: true |
|
}, |
|
'fragment': { |
|
pattern: /(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/, |
|
lookbehind: true, |
|
alias: 'function' |
|
}, |
|
'definition-mutation': { |
|
pattern: /(\bmutation\s+)[a-zA-Z_]\w*/, |
|
lookbehind: true, |
|
alias: 'function' |
|
}, |
|
'definition-query': { |
|
pattern: /(\bquery\s+)[a-zA-Z_]\w*/, |
|
lookbehind: true, |
|
alias: 'function' |
|
}, |
|
'keyword': /\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/, |
|
'operator': /[!=|&]|\.{3}/, |
|
'property-query': /\w+(?=\s*\()/, |
|
'object': /\w+(?=\s*\{)/, |
|
'punctuation': /[!(){}\[\]:=,]/, |
|
'property': /\w+/ |
|
}; |
|
|
|
Prism.hooks.add('after-tokenize', function afterTokenizeGraphql(env) { |
|
if (env.language !== 'graphql') { |
|
return; |
|
} |
|
|
|
/** |
|
* get the graphql token stream that we want to customize |
|
* |
|
* @typedef {InstanceType<import("./prism-core")["Token"]>} Token |
|
* @type {Token[]} |
|
*/ |
|
var validTokens = env.tokens.filter(function (token) { |
|
return typeof token !== 'string' && token.type !== 'comment' && token.type !== 'scalar'; |
|
}); |
|
|
|
var currentIndex = 0; |
|
|
|
/** |
|
* Returns whether the token relative to the current index has the given type. |
|
* |
|
* @param {number} offset |
|
* @returns {Token | undefined} |
|
*/ |
|
function getToken(offset) { |
|
return validTokens[currentIndex + offset]; |
|
} |
|
|
|
/** |
|
* Returns whether the token relative to the current index has the given type. |
|
* |
|
* @param {readonly string[]} types |
|
* @param {number} [offset=0] |
|
* @returns {boolean} |
|
*/ |
|
function isTokenType(types, offset) { |
|
offset = offset || 0; |
|
for (var i = 0; i < types.length; i++) { |
|
var token = getToken(i + offset); |
|
if (!token || token.type !== types[i]) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
/** |
|
* Returns the index of the closing bracket to an opening bracket. |
|
* |
|
* It is assumed that `token[currentIndex - 1]` is an opening bracket. |
|
* |
|
* If no closing bracket could be found, `-1` will be returned. |
|
* |
|
* @param {RegExp} open |
|
* @param {RegExp} close |
|
* @returns {number} |
|
*/ |
|
function findClosingBracket(open, close) { |
|
var stackHeight = 1; |
|
|
|
for (var i = currentIndex; i < validTokens.length; i++) { |
|
var token = validTokens[i]; |
|
var content = token.content; |
|
|
|
if (token.type === 'punctuation' && typeof content === 'string') { |
|
if (open.test(content)) { |
|
stackHeight++; |
|
} else if (close.test(content)) { |
|
stackHeight--; |
|
|
|
if (stackHeight === 0) { |
|
return i; |
|
} |
|
} |
|
} |
|
} |
|
|
|
return -1; |
|
} |
|
|
|
/** |
|
* Adds an alias to the given token. |
|
* |
|
* @param {Token} token |
|
* @param {string} alias |
|
* @returns {void} |
|
*/ |
|
function addAlias(token, alias) { |
|
var aliases = token.alias; |
|
if (!aliases) { |
|
token.alias = aliases = []; |
|
} else if (!Array.isArray(aliases)) { |
|
token.alias = aliases = [aliases]; |
|
} |
|
aliases.push(alias); |
|
} |
|
|
|
for (; currentIndex < validTokens.length;) { |
|
var startToken = validTokens[currentIndex++]; |
|
|
|
// add special aliases for mutation tokens |
|
if (startToken.type === 'keyword' && startToken.content === 'mutation') { |
|
// any array of the names of all input variables (if any) |
|
var inputVariables = []; |
|
|
|
if (isTokenType(['definition-mutation', 'punctuation']) && getToken(1).content === '(') { |
|
// definition |
|
|
|
currentIndex += 2; // skip 'definition-mutation' and 'punctuation' |
|
|
|
var definitionEnd = findClosingBracket(/^\($/, /^\)$/); |
|
if (definitionEnd === -1) { |
|
continue; |
|
} |
|
|
|
// find all input variables |
|
for (; currentIndex < definitionEnd; currentIndex++) { |
|
var t = getToken(0); |
|
if (t.type === 'variable') { |
|
addAlias(t, 'variable-input'); |
|
inputVariables.push(t.content); |
|
} |
|
} |
|
|
|
currentIndex = definitionEnd + 1; |
|
} |
|
|
|
if (isTokenType(['punctuation', 'property-query']) && getToken(0).content === '{') { |
|
currentIndex++; // skip opening bracket |
|
|
|
addAlias(getToken(0), 'property-mutation'); |
|
|
|
if (inputVariables.length > 0) { |
|
var mutationEnd = findClosingBracket(/^\{$/, /^\}$/); |
|
if (mutationEnd === -1) { |
|
continue; |
|
} |
|
|
|
// give references to input variables a special alias |
|
for (var i = currentIndex; i < mutationEnd; i++) { |
|
var varToken = validTokens[i]; |
|
if (varToken.type === 'variable' && inputVariables.indexOf(varToken.content) >= 0) { |
|
addAlias(varToken, 'variable-input'); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
});
|
|
|