mirror of
https://github.com/JamesIves/github-pages-deploy-action.git
synced 2023-12-15 20:03:39 +08:00
245 lines
7.4 KiB
JavaScript
245 lines
7.4 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
Object.defineProperty(exports, "__esModule", {
|
||
|
value: true
|
||
|
});
|
||
|
exports.createRule = createRule;
|
||
|
|
||
|
var _graphql = require("graphql");
|
||
|
|
||
|
var _constants = require("./constants");
|
||
|
|
||
|
function strWithLen(len) {
|
||
|
// from http://stackoverflow.com/questions/14343844/create-a-string-of-variable-length-filled-with-a-repeated-character
|
||
|
return new Array(len + 1).join("x");
|
||
|
}
|
||
|
|
||
|
function replaceExpressions(node, context, env) {
|
||
|
var chunks = [];
|
||
|
|
||
|
node.quasis.forEach(function (element, i) {
|
||
|
var chunk = element.value.cooked;
|
||
|
var value = node.expressions[i];
|
||
|
|
||
|
chunks.push(chunk);
|
||
|
|
||
|
if (!env || env === "apollo") {
|
||
|
// In Apollo, interpolation is only valid outside top-level structures like `query` or `mutation`.
|
||
|
// We'll check to make sure there's an equivalent set of opening and closing brackets, otherwise
|
||
|
// we're attempting to do an invalid interpolation.
|
||
|
if (chunk.split("{").length - 1 !== chunk.split("}").length - 1) {
|
||
|
context.report({
|
||
|
node: value,
|
||
|
message: "Invalid interpolation - fragment interpolation must occur outside of the brackets."
|
||
|
});
|
||
|
throw new Error("Invalid interpolation");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!element.tail) {
|
||
|
// Preserve location of errors by replacing with exactly the same length
|
||
|
var nameLength = value.end - value.start;
|
||
|
|
||
|
if (env === "relay" && /:\s*$/.test(chunk)) {
|
||
|
// The chunk before this one had a colon at the end, so this
|
||
|
// is a variable
|
||
|
|
||
|
// Add 2 for brackets in the interpolation
|
||
|
var placeholder = strWithLen(nameLength + 2);
|
||
|
chunks.push("$" + placeholder);
|
||
|
} else if (env === "lokka" && /\.\.\.\s*$/.test(chunk)) {
|
||
|
// This is Lokka-style fragment interpolation where you actually type the '...' yourself
|
||
|
var _placeholder = strWithLen(nameLength + 3);
|
||
|
chunks.push(_placeholder);
|
||
|
} else if (env === "relay") {
|
||
|
// This is Relay-style fragment interpolation where you don't type '...'
|
||
|
// Ellipsis cancels out extra characters
|
||
|
var _placeholder2 = strWithLen(nameLength);
|
||
|
chunks.push("..." + _placeholder2);
|
||
|
} else if (!env || env === "apollo") {
|
||
|
// In Apollo, fragment interpolation is only valid outside of brackets
|
||
|
// Since we don't know what we'd interpolate here (that occurs at runtime),
|
||
|
// we're not going to do anything with this interpolation.
|
||
|
} else if (env === "fraql") {
|
||
|
if (chunk.lastIndexOf("{") > chunk.lastIndexOf("}")) {
|
||
|
chunks.push("__typename");
|
||
|
}
|
||
|
} else {
|
||
|
// Invalid interpolation
|
||
|
context.report({
|
||
|
node: value,
|
||
|
message: "Invalid interpolation - not a valid fragment or variable."
|
||
|
});
|
||
|
throw new Error("Invalid interpolation");
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return chunks.join("");
|
||
|
}
|
||
|
|
||
|
function locFrom(node, error) {
|
||
|
if (!error.locations || !error.locations.length) {
|
||
|
return;
|
||
|
}
|
||
|
var location = error.locations[0];
|
||
|
|
||
|
var line = void 0;
|
||
|
var column = void 0;
|
||
|
if (location.line === 1 && node.tag.name !== _constants.internalTag) {
|
||
|
line = node.loc.start.line;
|
||
|
column = node.tag.loc.end.column + location.column;
|
||
|
} else {
|
||
|
line = node.loc.start.line + location.line - 1;
|
||
|
column = location.column - 1;
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
line: line,
|
||
|
column: column
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function handleTemplateTag(node, context, schema, env, validators) {
|
||
|
var text = void 0;
|
||
|
try {
|
||
|
text = replaceExpressions(node.quasi, context, env);
|
||
|
} catch (e) {
|
||
|
if (e.message !== "Invalid interpolation") {
|
||
|
console.log(e); // eslint-disable-line no-console
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Re-implement syntax sugar for fragment names, which is technically not valid
|
||
|
// graphql
|
||
|
if ((env === "lokka" || env === "relay" || env === "fraql") && /fragment\s+on/.test(text)) {
|
||
|
text = text.replace("fragment", "fragment _");
|
||
|
}
|
||
|
|
||
|
var ast = void 0;
|
||
|
|
||
|
try {
|
||
|
ast = (0, _graphql.parse)(text);
|
||
|
} catch (error) {
|
||
|
context.report({
|
||
|
node: node,
|
||
|
message: error.message.split("\n")[0],
|
||
|
loc: locFrom(node, error)
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var validationErrors = schema ? (0, _graphql.validate)(schema, ast, validators) : [];
|
||
|
if (validationErrors && validationErrors.length > 0) {
|
||
|
context.report({
|
||
|
node: node,
|
||
|
message: validationErrors[0].message,
|
||
|
loc: locFrom(node, validationErrors[0])
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function templateExpressionMatchesTag(tagName, node) {
|
||
|
var tagNameSegments = tagName.split(".").length;
|
||
|
if (tagNameSegments === 1) {
|
||
|
// Check for single identifier, like 'gql'
|
||
|
if (node.tag.type !== "Identifier" || node.tag.name !== tagName) {
|
||
|
return false;
|
||
|
}
|
||
|
} else if (tagNameSegments === 2) {
|
||
|
// Check for dotted identifier, like 'Relay.QL'
|
||
|
if (node.tag.type !== "MemberExpression" || node.tag.object.name + "." + node.tag.property.name !== tagName) {
|
||
|
return false;
|
||
|
}
|
||
|
} else {
|
||
|
// We don't currently support 3 segments so ignore
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function createRule(context, optionParser) {
|
||
|
var tagNames = new Set();
|
||
|
var tagRules = [];
|
||
|
var options = context.options.length === 0 ? [{}] : context.options;
|
||
|
var _iteratorNormalCompletion = true;
|
||
|
var _didIteratorError = false;
|
||
|
var _iteratorError = undefined;
|
||
|
|
||
|
try {
|
||
|
var _loop = function _loop() {
|
||
|
var optionGroup = _step.value;
|
||
|
|
||
|
var _optionParser = optionParser(optionGroup),
|
||
|
schema = _optionParser.schema,
|
||
|
env = _optionParser.env,
|
||
|
tagName = _optionParser.tagName,
|
||
|
validators = _optionParser.validators;
|
||
|
|
||
|
var boundValidators = validators.map(function (v) {
|
||
|
return function (ctx) {
|
||
|
return v(ctx, optionGroup);
|
||
|
};
|
||
|
});
|
||
|
if (tagNames.has(tagName)) {
|
||
|
throw new Error("Multiple options for GraphQL tag " + tagName);
|
||
|
}
|
||
|
tagNames.add(tagName);
|
||
|
tagRules.push({ schema: schema, env: env, tagName: tagName, validators: boundValidators });
|
||
|
};
|
||
|
|
||
|
for (var _iterator = options[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||
|
_loop();
|
||
|
}
|
||
|
} catch (err) {
|
||
|
_didIteratorError = true;
|
||
|
_iteratorError = err;
|
||
|
} finally {
|
||
|
try {
|
||
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
||
|
_iterator.return();
|
||
|
}
|
||
|
} finally {
|
||
|
if (_didIteratorError) {
|
||
|
throw _iteratorError;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
TaggedTemplateExpression: function TaggedTemplateExpression(node) {
|
||
|
var _iteratorNormalCompletion2 = true;
|
||
|
var _didIteratorError2 = false;
|
||
|
var _iteratorError2 = undefined;
|
||
|
|
||
|
try {
|
||
|
for (var _iterator2 = tagRules[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||
|
var _ref2 = _step2.value;
|
||
|
var schema = _ref2.schema,
|
||
|
env = _ref2.env,
|
||
|
tagName = _ref2.tagName,
|
||
|
validators = _ref2.validators;
|
||
|
|
||
|
if (templateExpressionMatchesTag(tagName, node)) {
|
||
|
return handleTemplateTag(node, context, schema, env, validators);
|
||
|
}
|
||
|
}
|
||
|
} catch (err) {
|
||
|
_didIteratorError2 = true;
|
||
|
_iteratorError2 = err;
|
||
|
} finally {
|
||
|
try {
|
||
|
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||
|
_iterator2.return();
|
||
|
}
|
||
|
} finally {
|
||
|
if (_didIteratorError2) {
|
||
|
throw _iteratorError2;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|