@prisma/language-server
Version:
Prisma Language Server
145 lines • 5.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrismaSchema = exports.SchemaDocument = void 0;
const schema_files_loader_1 = require("@prisma/schema-files-loader");
const config_1 = require("@prisma/config");
const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
const vscode_uri_1 = require("vscode-uri");
const ast_1 = require("./ast");
class SchemaDocument {
constructor(textDocument) {
this.textDocument = textDocument;
this.lines = [];
for (let i = 0; i < textDocument.lineCount; i++) {
const line = (0, ast_1.getCurrentLine)(textDocument, i);
this.lines.push({
document: this,
lineIndex: i,
untrimmedText: line,
text: line.trim(),
});
}
}
get uri() {
return this.textDocument.uri;
}
get content() {
return this.textDocument.getText();
}
positionAt(offset) {
return this.textDocument.positionAt(offset);
}
getLineContent(lineIndex) {
return this.lines[lineIndex].text;
}
}
exports.SchemaDocument = SchemaDocument;
/**
* Will try to load the prisma config file from the given path, default path or create a default config.
*/
async function loadConfig() {
const { config, error, resolvedPath } = await (0, config_1.loadConfigFromFile)({});
if (error) {
switch (error._tag) {
case 'ConfigFileNotFound':
throw new Error(`Config file not found at "${resolvedPath}"`);
case 'ConfigFileParseError':
throw new Error(`Failed to parse config file at "${resolvedPath}"`);
case 'TypeScriptImportFailed':
throw new Error(`Failed to import config file as TypeScript from "${resolvedPath}". Error: ${error.error.message}`);
case 'UnknownError':
throw new Error(`Unknown error during config file loading: ${error.error.message}`);
default:
throw new Error(`Unhandled error '${JSON.stringify(error)}' in 'loadConfigFromFile'.`);
}
}
return config;
}
async function loadPrismaSchema(fsPath, allDocuments) {
// `loadRelatedSchemaFiles` locates and returns either a single schema files, or a set of related schema files.
const schemaFiles = await (0, schema_files_loader_1.loadRelatedSchemaFiles)(fsPath, createFilesResolver(allDocuments));
const documents = schemaFiles.map(([filePath, content]) => {
return new SchemaDocument(vscode_languageserver_textdocument_1.TextDocument.create(vscode_uri_1.URI.file(filePath).toString(), 'prisma', 1, content));
});
return new PrismaSchema(documents);
}
function loadPrismaSchemaWithConfig(config, currentDocument, allDocuments) {
const fsPath = config.schema ?? vscode_uri_1.URI.parse(currentDocument.uri).fsPath;
return loadPrismaSchema(fsPath, allDocuments);
}
class PrismaSchema {
// TODO: remove, use `PrismaSchema.load` directly
static singleFile(textDocument) {
return new PrismaSchema([new SchemaDocument(textDocument)]);
}
static async load(currentDocument, allDocuments) {
const config = await loadConfig();
if (config instanceof Error) {
console.debug('Failed to load Prisma config file', config);
console.log('Continuing without Prisma config file');
const fsPath = vscode_uri_1.URI.parse(currentDocument.uri).fsPath;
return loadPrismaSchema(fsPath, allDocuments);
}
return loadPrismaSchemaWithConfig(config, currentDocument, allDocuments);
}
constructor(documents) {
this.documents = documents;
}
*iterLines() {
for (const doc of this.documents) {
for (const line of doc.lines) {
yield line;
}
}
}
linesAsArray() {
return Array.from(this.iterLines());
}
findDocByUri(fileUri) {
return this.documents.find((doc) => doc.uri === fileUri);
}
findWithRegex(regexp) {
for (const doc of this.documents) {
regexp.lastIndex = 0;
const match = regexp.exec(doc.content);
if (match) {
return { match, documentUri: doc.uri };
}
}
return undefined;
}
/**
*
* @returns array of (uri, content) tuples. Expected input for prisma-schema-wasm
*/
toTuples() {
return this.documents.map((doc) => [doc.uri, doc.content]);
}
toJSON() {
return this.toTuples();
}
}
exports.PrismaSchema = PrismaSchema;
function createFilesResolver(allDocuments) {
const options = {
// Technically, macos and Windows can use case-sensitive file systems
// too, however, VSCode does not support this at the moment, so there is
// no meaningful way for us to support them in extension
// See:
// - https://github.com/microsoft/vscode/issues/123660
// - https://github.com/microsoft/vscode/issues/94307
// - https://github.com/microsoft/vscode/blob/c06c555b481aaac4afd51d6fc7691d7658949651/src/vs/platform/files/node/diskFileSystemProvider.ts#L81
caseSensitive: process.platform === 'linux',
};
return new schema_files_loader_1.CompositeFilesResolver(createInMemoryResolver(allDocuments, options), schema_files_loader_1.realFsResolver, options);
}
function createInMemoryResolver(allDocuments, options) {
const resolver = new schema_files_loader_1.InMemoryFilesResolver(options);
for (const doc of allDocuments.all()) {
const filePath = vscode_uri_1.URI.parse(doc.uri).fsPath;
const content = doc.getText();
resolver.addFile(filePath, content);
}
return resolver;
}
//# sourceMappingURL=Schema.js.map