@openfga/frontend-utils
Version:
Exposes helpful utilities for building authoring experiences of OpenFGA Models.
122 lines (121 loc) • 5.71 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.provideCodeActions = void 0;
const syntax_transformer_1 = require("@openfga/syntax-transformer");
const keyword_1 = require("../../../constants/keyword");
const schema_version_1 = require("../../../constants/schema-version");
const single_indentation_1 = require("../../../constants/single-indentation");
const errorFixesByErrorCodeAndSchema = {
[syntax_transformer_1.errors.ValidationError.MissingDefinition]: {
[schema_version_1.SchemaVersion.OneDotZero]: ({ model, marker, relation }) => {
const lineContent = model.getLineContent(marker.startLineNumber);
return {
startColumn: 0,
title: `Fix: add definition for \`${relation}\`.`,
text: `${single_indentation_1.SINGLE_INDENTATION}${single_indentation_1.SINGLE_INDENTATION}${keyword_1.Keyword.DEFINE} ${relation} ${keyword_1.Keyword.AS} ${keyword_1.Keyword.SELF}\n${lineContent}`,
};
},
[schema_version_1.SchemaVersion.OneDotOne]: ({ model, marker, relation }) => {
const lineContent = model.getLineContent(marker.startLineNumber);
return {
startColumn: 0,
title: `Fix: add definition for \`${relation}\`.`,
text: `${single_indentation_1.SINGLE_INDENTATION}${single_indentation_1.SINGLE_INDENTATION}${keyword_1.Keyword.DEFINE} ${relation}: [typeName]\n${lineContent}`,
};
},
[schema_version_1.SchemaVersion.OneDotTwo]: ({ model, marker, relation }) => {
const lineContent = model.getLineContent(marker.startLineNumber);
return {
startColumn: 0,
title: `Fix: add definition for \`${relation}\`.`,
text: `${single_indentation_1.SINGLE_INDENTATION}${single_indentation_1.SINGLE_INDENTATION}${keyword_1.Keyword.DEFINE} ${relation}: [typeName]\n${lineContent}`,
};
},
},
[syntax_transformer_1.errors.ValidationError.SelfError]: {
[schema_version_1.SchemaVersion.OneDotZero]: ({ text }) => ({
title: `Fix: replace \`${text}\` by \`self\`.`,
text: keyword_1.Keyword.SELF,
}),
[schema_version_1.SchemaVersion.OneDotOne]: ({ text }) => ({
title: `Fix: replace \`${text}\` with type restrictions.`,
text: "[typeName]",
}),
[schema_version_1.SchemaVersion.OneDotTwo]: ({ text }) => ({
title: `Fix: replace \`${text}\` with type restrictions.`,
text: "[typeName]",
}),
},
[syntax_transformer_1.errors.ValidationError.DuplicatedError]: {
[schema_version_1.SchemaVersion.OneDotZero]: ({ model, marker, markerRange, text }) => ({
startLineNumber: markerRange.startLineNumber - 1,
startColumn: model.getLineContent(marker.startLineNumber - 1).length + 1,
title: `Fix: remove duplicated \`${text}\`.`,
text: "",
}),
[schema_version_1.SchemaVersion.OneDotOne]: ({ model, marker, markerRange, text }) => ({
startLineNumber: markerRange.startLineNumber - 1,
startColumn: model.getLineContent(marker.startLineNumber - 1).length + 1,
title: `Fix: remove duplicated \`${text}\`.`,
text: "",
}),
[schema_version_1.SchemaVersion.OneDotTwo]: ({ model, marker, markerRange, text }) => ({
startLineNumber: markerRange.startLineNumber - 1,
startColumn: model.getLineContent(marker.startLineNumber - 1).length + 1,
title: `Fix: remove duplicated \`${text}\`.`,
text: "",
}),
},
};
function getCodeActionForError({ markerRange, model, marker, text, schemaVersion }) {
var _a, _b;
const { error, relation } = marker.extraInformation || {};
const fixContent = (_b = (_a = errorFixesByErrorCodeAndSchema[error]) === null || _a === void 0 ? void 0 : _a[schemaVersion]) === null || _b === void 0 ? void 0 : _b.call(_a, {
model,
marker,
markerRange,
text,
relation,
});
if (!fixContent) {
return;
}
return {
title: fixContent === null || fixContent === void 0 ? void 0 : fixContent.title,
diagnostics: [marker],
edit: {
edits: [
{
textEdit: {
range: markerRange,
text: fixContent.text,
},
resource: model.uri,
versionId: undefined,
},
],
},
kind: "quickfix",
};
}
const provideCodeActions = (monaco, schemaVersion) => (model, range, context) => {
const codeActions = [];
context.markers
.map((marker) => {
const startOffset = model.getOffsetAt({ column: marker.startColumn, lineNumber: marker.startLineNumber });
const endOffset = model.getOffsetAt({ column: marker.endColumn, lineNumber: marker.endLineNumber });
const text = model.getValue().substr(startOffset, endOffset - startOffset);
const markerRange = new monaco.Range(marker.startLineNumber, marker.startColumn, marker.endLineNumber, marker.endColumn);
const action = getCodeActionForError({ markerRange, model, marker, text, schemaVersion });
if (action) {
codeActions.push(action);
}
})
.filter((action) => action);
return {
actions: codeActions,
// eslint-disable-next-line @typescript-eslint/no-empty-function
dispose() { },
};
};
exports.provideCodeActions = provideCodeActions;