zenstack
Version:
FullStack enhancement for Prisma ORM: seamless integration from database to UI
139 lines • 7.4 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZModelWorkspaceManager = void 0;
const ast_1 = require("@zenstackhq/language/ast");
const sdk_1 = require("@zenstackhq/sdk");
const langium_1 = require("langium");
const path_1 = __importDefault(require("path"));
const vscode_languageserver_1 = require("vscode-languageserver");
const vscode_uri_1 = require("vscode-uri");
const constants_1 = require("./constants");
/**
* Custom Langium WorkspaceManager implementation which automatically loads stdlib.zmodel
*/
class ZModelWorkspaceManager extends langium_1.DefaultWorkspaceManager {
constructor() {
super(...arguments);
this.pluginModels = new Set();
}
loadAdditionalDocuments(_folders, _collector) {
const _super = Object.create(null, {
loadAdditionalDocuments: { get: () => super.loadAdditionalDocuments }
});
return __awaiter(this, void 0, void 0, function* () {
yield _super.loadAdditionalDocuments.call(this, _folders, _collector);
const stdLibUri = vscode_uri_1.URI.file(path_1.default.join(__dirname, '../res', constants_1.STD_LIB_MODULE_NAME));
console.log(`Adding stdlib document from ${stdLibUri}`);
const stdlib = this.langiumDocuments.getOrCreateDocument(stdLibUri);
_collector(stdlib);
});
}
initializeWorkspace(folders_1) {
return __awaiter(this, arguments, void 0, function* (folders, cancelToken = vscode_languageserver_1.CancellationToken.None) {
const fileExtensions = this.serviceRegistry.all.flatMap((e) => e.LanguageMetaData.fileExtensions);
const documents = [];
const collector = (document) => {
documents.push(document);
if (!this.langiumDocuments.hasDocument(document.uri)) {
this.langiumDocuments.addDocument(document);
}
};
yield this.loadAdditionalDocuments(folders, collector);
yield Promise.all(folders
.map((wf) => [wf, this.getRootFolder(wf)])
.map((entry) => __awaiter(this, void 0, void 0, function* () { return this.traverseFolder(...entry, fileExtensions, collector); })));
// find plugin models
documents.forEach((doc) => {
const parsed = doc.parseResult.value;
parsed.declarations.forEach((decl) => {
if ((0, ast_1.isPlugin)(decl)) {
const providerField = decl.fields.find((f) => f.name === 'provider');
if (providerField) {
const provider = (0, sdk_1.getLiteral)(providerField.value);
if (provider) {
this.pluginModels.add(provider);
}
}
}
});
});
if (this.pluginModels.size > 0) {
console.log(`Used plugin documents: ${Array.from(this.pluginModels)}`);
// the loaded plugin models would be removed from the set
const unLoadedPluginModels = new Set(this.pluginModels);
yield Promise.all(folders
.map((wf) => [wf, this.getRootFolder(wf)])
.map((entry) => __awaiter(this, void 0, void 0, function* () { return this.loadPluginModels(...entry, unLoadedPluginModels, collector); })));
if (unLoadedPluginModels.size > 0) {
console.warn(`The following plugin documents could not be loaded: ${Array.from(unLoadedPluginModels)}`);
}
}
// Only after creating all documents do we check whether we need to cancel the initialization
// The document builder will later pick up on all unprocessed documents
yield (0, langium_1.interruptAndCheck)(cancelToken);
yield this.documentBuilder.build(documents, undefined, cancelToken);
});
}
loadPluginModels(workspaceFolder, folderPath, pluginModels, collector) {
return __awaiter(this, void 0, void 0, function* () {
const content = yield (yield this.fileSystemProvider.readDirectory(folderPath)).sort((a, b) => {
// make sure the node_moudules folder is always the first one to be checked
// so it could be early exited if the plugin is found
if (a.isDirectory && b.isDirectory) {
const aName = vscode_uri_1.Utils.basename(a.uri);
if (aName === 'node_modules') {
return -1;
}
else {
return 1;
}
}
else {
return 0;
}
});
for (const entry of content) {
if (entry.isDirectory) {
const name = vscode_uri_1.Utils.basename(entry.uri);
if (name === 'node_modules') {
for (const plugin of Array.from(pluginModels)) {
const path = vscode_uri_1.Utils.joinPath(entry.uri, plugin, constants_1.PLUGIN_MODULE_NAME);
try {
this.fileSystemProvider.readFileSync(path);
const document = this.langiumDocuments.getOrCreateDocument(path);
collector(document);
console.log(`Adding plugin document from ${path.path}`);
pluginModels.delete(plugin);
// early exit if all plugins are loaded
if (pluginModels.size === 0) {
return;
}
}
catch (_a) {
// no-op. The module might be found in another node_modules folder
// will show the warning message eventually if not found
}
}
}
else {
yield this.loadPluginModels(workspaceFolder, entry.uri, pluginModels, collector);
}
}
}
});
}
}
exports.ZModelWorkspaceManager = ZModelWorkspaceManager;
//# sourceMappingURL=zmodel-workspace-manager.js.map
;