From b974fae229bd293ee0e5543c31d2c14bd1515761 Mon Sep 17 00:00:00 2001 From: lastlink Date: Sat, 6 Jul 2024 08:01:31 -0400 Subject: [PATCH 1/8] improved comment parsing --- src/nosql-ts.ts | 91 +----------------------------------- src/nosql.ts | 74 +---------------------------- src/utils/constants-nosql.ts | 91 ++++++++++++++++++++++++++++++++++++ src/utils/nosqlUtils.ts | 39 ++++++++++++---- 4 files changed, 124 insertions(+), 171 deletions(-) create mode 100644 src/utils/constants-nosql.ts diff --git a/src/nosql-ts.ts b/src/nosql-ts.ts index cd81035..34399ab 100644 --- a/src/nosql-ts.ts +++ b/src/nosql-ts.ts @@ -9,6 +9,7 @@ import { convertCoreTypesToTypeScript } from "core-types-ts"; import { GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; import { pluginVersion } from "./utils/constants"; import { ConvertOpenApiToDatabaseModel, dbToOpenApi, GeneratePropertyModel } from "./utils/nosqlUtils"; +import { defaultReset, defaultResetOpenApi } from "./utils/constants-nosql"; declare const window: Customwindow; @@ -128,96 +129,6 @@ Draw.loadPlugin(function(ui) { const sqlInputFromNOSQL = document.createElement("textarea"); sqlInputFromNOSQL.style.height = "200px"; sqlInputFromNOSQL.style.width = "100%"; - const defaultReset = `/*\n\tDrawio default value\n\tPlugin: nosql\n\tVersion: ${pluginVersion}\n*/\n\n -export interface WeatherForecast { - /** @format date-time */ - date?: string; - /** @format int32 */ - temperatureC?: number; - /** @format int32 */ - temperatureF?: number; - summary?: string | null; - nestedProp: string[]; - children?: Child[]; -} - -export interface Child { - name: string -} - `; - - - const defaultResetOpenApi = ` -{ - "openapi": "3.0.0", - "info": { - "title": "nosql plugin sample", - "version": "${pluginVersion}", - "x-comment": "Generated by core-types-json-schema (https://github.com/grantila/core-types-json-schema)" - }, - "paths": {}, - "components": { - "schemas": { - "WeatherForecast": { - "properties": { - "date": { - "title": "WeatherForecast.date", - "description": "@format date-time", - "type": "string" - }, - "temperatureC": { - "title": "WeatherForecast.temperatureC", - "description": "@format int32", - "type": "number" - }, - "temperatureF": { - "title": "WeatherForecast.temperatureF", - "description": "@format int32", - "type": "number" - }, - "summary": { - "title": "WeatherForecast.summary", - "nullable": true, - "type": "string" - }, - "nestedProp": { - "items": { - "title": "WeatherForecast.nestedProp.[]", - "type": "string" - }, - "title": "WeatherForecast.nestedProp", - "type": "array" - }, - "child": { - "$ref": "#/components/schemas/Child", - "title": "WeatherForecast.child" - } - }, - "required": [ - "nestedProp" - ], - "additionalProperties": false, - "title": "WeatherForecast", - "type": "object" - }, - "Child": { - "properties": { - "name": { - "title": "Child.name", - "type": "string" - } - }, - "required": [ - "name" - ], - "additionalProperties": false, - "title": "Child", - "type": "object" - } - } - } -} - `; sqlInputFromNOSQL.value = defaultReset; mxUtils.br(divFromNOSQL); diff --git a/src/nosql.ts b/src/nosql.ts index 867e2fa..8b17595 100644 --- a/src/nosql.ts +++ b/src/nosql.ts @@ -7,6 +7,7 @@ import { JsonSchemaDocumentToOpenApiOptions, PartialOpenApiSchema } from "openap import { GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; import { pluginVersion } from "./utils/constants"; import { ConvertOpenApiToDatabaseModel, dbToOpenApi, GeneratePropertyModel } from "./utils/nosqlUtils"; +import { defaultResetOpenApi } from "./utils/constants-nosql"; declare const window: Customwindow; @@ -113,79 +114,6 @@ Draw.loadPlugin(function(ui) { const sqlInputFromNOSQL = document.createElement("textarea"); sqlInputFromNOSQL.style.height = "200px"; sqlInputFromNOSQL.style.width = "100%"; - - const defaultResetOpenApi = ` -{ - "openapi": "3.0.0", - "info": { - "title": "nosql plugin sample", - "version": "${pluginVersion}", - "x-comment": "Generated by core-types-json-schema (https://github.com/grantila/core-types-json-schema)" - }, - "paths": {}, - "components": { - "schemas": { - "WeatherForecast": { - "properties": { - "date": { - "title": "WeatherForecast.date", - "description": "@format date-time", - "type": "string" - }, - "temperatureC": { - "title": "WeatherForecast.temperatureC", - "description": "@format int32", - "type": "number" - }, - "temperatureF": { - "title": "WeatherForecast.temperatureF", - "description": "@format int32", - "type": "number" - }, - "summary": { - "title": "WeatherForecast.summary", - "nullable": true, - "type": "string" - }, - "nestedProp": { - "items": { - "title": "WeatherForecast.nestedProp.[]", - "type": "string" - }, - "title": "WeatherForecast.nestedProp", - "type": "array" - }, - "child": { - "$ref": "#/components/schemas/Child", - "title": "WeatherForecast.child" - } - }, - "required": [ - "nestedProp" - ], - "additionalProperties": false, - "title": "WeatherForecast", - "type": "object" - }, - "Child": { - "properties": { - "name": { - "title": "Child.name", - "type": "string" - } - }, - "required": [ - "name" - ], - "additionalProperties": false, - "title": "Child", - "type": "object" - } - } - } -} - `; - sqlInputFromNOSQL.value = defaultResetOpenApi; mxUtils.br(divFromNOSQL); divFromNOSQL.appendChild(sqlInputFromNOSQL); diff --git a/src/utils/constants-nosql.ts b/src/utils/constants-nosql.ts new file mode 100644 index 0000000..d429782 --- /dev/null +++ b/src/utils/constants-nosql.ts @@ -0,0 +1,91 @@ +import { pluginVersion } from "./constants"; + +export const defaultReset = `/*\n\tDrawio default value\n\tPlugin: nosql\n\tVersion: ${pluginVersion}\n*/\n\n +export interface WeatherForecast { + /** @format date-time */ + date?: string; + /** @format int32 */ + temperatureC?: number; + /** @format int32 */ + temperatureF?: number; + summary?: string | null; + nestedProp: string[]; + children?: Child[]; +} + +export interface Child { + name: string +} + `; + +export const defaultResetOpenApi = ` +{ + "openapi": "3.0.0", + "info": { + "title": "nosql plugin sample", + "version": "${pluginVersion}", + "x-comment": "Generated by core-types-json-schema (https://github.com/grantila/core-types-json-schema)" + }, + "paths": {}, + "components": { + "schemas": { + "WeatherForecast": { + "properties": { + "date": { + "title": "WeatherForecast.date", + "description": "@format date-time", + "type": "string" + }, + "temperatureC": { + "title": "WeatherForecast.temperatureC", + "description": "@format int32", + "type": "number" + }, + "temperatureF": { + "title": "WeatherForecast.temperatureF", + "description": "@format int32", + "type": "number" + }, + "summary": { + "title": "WeatherForecast.summary", + "nullable": true, + "type": "string" + }, + "nestedProp": { + "items": { + "title": "WeatherForecast.nestedProp.[]", + "type": "string" + }, + "title": "WeatherForecast.nestedProp", + "type": "array" + }, + "child": { + "$ref": "#/components/schemas/Child", + "title": "WeatherForecast.child" + } + }, + "required": [ + "nestedProp" + ], + "additionalProperties": false, + "title": "WeatherForecast", + "type": "object" + }, + "Child": { + "properties": { + "name": { + "title": "Child.name", + "type": "string" + } + }, + "required": [ + "name" + ], + "additionalProperties": false, + "title": "Child", + "type": "object" + } + } + } +} + `; \ No newline at end of file diff --git a/src/utils/nosqlUtils.ts b/src/utils/nosqlUtils.ts index a7a637f..f4066eb 100644 --- a/src/utils/nosqlUtils.ts +++ b/src/utils/nosqlUtils.ts @@ -153,7 +153,7 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { schema[schemaKey].type = type; } else { const property: JSONSchema4 = { - title: `${key}.${propName}`, + title: `${schemaKey}.${propName}`, nullable: attribute.attributeType?.includes("nullable") ?? false, type: type, }; @@ -211,9 +211,11 @@ export function ConvertOpenApiToDatabaseModel( PrimaryKeyList: [], ForeignKeyList: [], }; + const tableDict: Record = {}; for (const key in schemas) { if (Object.prototype.hasOwnProperty.call(schemas, key)) { const schema = schemas[key] as JSONSchema4; + const originalKey = dbTypeEnds(key); const tableModel: TableModel = { Name: dbTypeEnds(key), Properties: [], @@ -250,7 +252,7 @@ export function ConvertOpenApiToDatabaseModel( ) { const property = schema.properties[propertyKey]; const propertyModel: PropertyModel = GeneratePropertyModel( - key, + tableModel.Name, propertyKey, property ); @@ -264,18 +266,27 @@ export function ConvertOpenApiToDatabaseModel( } else if (property.items && typeof property.items == "object") { refName = (property.items as JSONSchema4).$ref?.split("/").pop(); } + if(refName) { + const refSchema:JSONSchema4|null = schemas[refName] as JSONSchema4; + if(refSchema && !refSchema.enum){ + const comment = generateComment(refSchema.description, refSchema.format); + if (comment) { + refName = `${dbTypeEnds(refName)} ${comment}`; + } + } + } if (refName) { const primaryKeyModel: ForeignKeyModel = { - PrimaryKeyTableName: dbTypeEnds(key), - ReferencesTableName: dbTypeEnds(refName), + PrimaryKeyTableName: tableModel.Name, + ReferencesTableName: refName, PrimaryKeyName: dbTypeEnds(propertyKey), // should just point to first property in uml table ReferencesPropertyName: "", IsDestination: false, }; const foreignKeyModel: ForeignKeyModel = { - ReferencesTableName: dbTypeEnds(key), - PrimaryKeyTableName: dbTypeEnds(refName), + ReferencesTableName: tableModel.Name, + PrimaryKeyTableName: refName, ReferencesPropertyName: dbTypeEnds(propertyKey), // should just point to first property in uml table PrimaryKeyName: "", @@ -292,24 +303,36 @@ export function ConvertOpenApiToDatabaseModel( } models.TableList.push(tableModel); + // may no longer be needed + if(!tableDict[originalKey]) { + tableDict[originalKey] = tableModel; + } } } for (let i = 0; i < models.ForeignKeyList.length; i++) { const fk = models.ForeignKeyList[i]; if (!fk.ReferencesPropertyName) { // match to first entry - const property = models.TableList.find( + let property = models.TableList.find( (t) => t.Name == fk.ReferencesTableName )?.Properties[0]; + if(!property) { + // attempt a comment lookup + property = tableDict[fk.ReferencesTableName]?.Properties[0]; + } if (property) { models.ForeignKeyList[i].ReferencesPropertyName = property.Name; } } if (!fk.PrimaryKeyName) { // match to first entry - const property = models.TableList.find( + let property = models.TableList.find( (t) => t.Name == fk.PrimaryKeyTableName )?.Properties[0]; + if(!property) { + // attempt a comment lookup + property = tableDict[fk.PrimaryKeyTableName]?.Properties[0]; + } if (property) { models.ForeignKeyList[i].PrimaryKeyName = property.Name; } From ad02326bbb929e038b7230b4e1369b5d06b6198f Mon Sep 17 00:00:00 2001 From: lastlink Date: Sat, 6 Jul 2024 11:12:09 -0400 Subject: [PATCH 2/8] improved fk line support and recursive fk --- src/nosql-ts.ts | 147 +------ src/nosql.ts | 147 +------ src/sql.ts | 145 +------ src/utils/constants.ts | 6 + src/utils/nosqlUtils.ts | 181 ++++---- src/utils/sharedUtils.ts | 865 +++++++++++++++++++++++++++------------ 6 files changed, 748 insertions(+), 743 deletions(-) diff --git a/src/nosql-ts.ts b/src/nosql-ts.ts index 34399ab..a803419 100644 --- a/src/nosql-ts.ts +++ b/src/nosql-ts.ts @@ -6,7 +6,7 @@ import { convertCoreTypesToJsonSchema, convertOpenApiToCoreTypes, jsonSchemaDocu import { JsonSchemaDocumentToOpenApiOptions, PartialOpenApiSchema } from "openapi-json-schema"; import { convertTypeScriptToCoreTypes } from "core-types-ts/dist/lib/ts-to-core-types"; import { convertCoreTypesToTypeScript } from "core-types-ts"; -import { GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; +import { CreateTableUI, GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; import { pluginVersion } from "./utils/constants"; import { ConvertOpenApiToDatabaseModel, dbToOpenApi, GeneratePropertyModel } from "./utils/nosqlUtils"; import { defaultReset, defaultResetOpenApi } from "./utils/constants-nosql"; @@ -146,36 +146,6 @@ Draw.loadPlugin(function(ui) { wndFromNOSQL.setResizable(false); wndFromNOSQL.setClosable(true); - function AddRow(propertyModel: PropertyModel, tableName: string) { - - const cellName = propertyModel.Name + (propertyModel.ColumnProperties ? " " + propertyModel.ColumnProperties: ""); - - rowCell = new mxCell(cellName, new mxGeometry(0, 0, 90, 26), - "shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;"); - rowCell.vertex = true; - - const columnType = propertyModel.IsPrimaryKey && propertyModel.IsForeignKey ? "PK | FK" : propertyModel.IsPrimaryKey ? "PK" : propertyModel.IsForeignKey ? "FK" : ""; - - const left = sb.cloneCell(rowCell, columnType); - left.connectable = false; - left.style = "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;"; - left.geometry.width = 54; - left.geometry.height = 26; - rowCell.insert(left); - - const size = ui.editor.graph.getPreferredSizeForCell(rowCell); - - if(tableCell){ - if (size !== null && tableCell.geometry.width < size.width + 10) { - tableCell.geometry.width = size.width + 10; - } - - tableCell.insert(rowCell); - tableCell.geometry.height += 26; - } - - }; - function parseFromInput(text: string, type?: "ts" | "openapi" | undefined) { // reset values cells = []; @@ -208,7 +178,13 @@ Draw.loadPlugin(function(ui) { primaryKeyList = models.PrimaryKeyList; tableList = models.TableList; exportedTables = tableList.length; - CreateTableUI(type); + const createTableResult = CreateTableUI(ui, wndFromNOSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type); + if(createTableResult){ + cells = createTableResult.cells; + dx = createTableResult.dx; + tableCell = createTableResult.tableCell; + rowCell = createTableResult.rowCell; + } } } catch (error) { @@ -217,113 +193,6 @@ Draw.loadPlugin(function(ui) { } }; - function CreateTableUI(type: "ts" | "openapi" | undefined) { - tableList.forEach(function(tableModel) { - //Define table size width - const maxNameLenght = 100 + tableModel.Name.length; - - //Create Table - tableCell = new mxCell(tableModel.Name, new mxGeometry(dx, 0, maxNameLenght, 26), - "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;"); - tableCell.vertex = true; - - //Resize row - if(rowCell){ - const size = ui.editor.graph.getPreferredSizeForCell(rowCell); - if (size !== null) { - tableCell.geometry.width = size.width + maxNameLenght; - } - } - - //Add Table to cells - cells.push(tableCell); - - //Add properties - tableModel.Properties.forEach(function(propertyModel) { - - //Add row - AddRow(propertyModel, tableModel.Name); - }); - - //Close table - dx += tableCell.geometry.width + 40; - tableCell = null; - }); - - if (cells.length > 0) { - const graph = ui.editor.graph; - const view = graph.view; - const bds = graph.getGraphBounds(); - - // Computes unscaled, untranslated graph bounds - const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize); - const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + 4 * graph.gridSize); - - graph.setSelectionCells(graph.importCells(cells, x, y)); - // add foreign key edges - const model = graph.getModel(); - const columnQuantifiers = GetColumnQuantifiers(type); - // const pt = graph.getFreeInsertPoint(); - foreignKeyList.forEach(function(fk){ - if(fk.IsDestination && fk.PrimaryKeyName && fk.ReferencesPropertyName && - fk.PrimaryKeyTableName && fk.ReferencesTableName) { - const insertEdge = mxUtils.bind(this, function(targetCell, sourceCell, edge){ - const label = ""; - const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; - const edgeCell = graph.insertEdge(null, null, label || "", (edge.invert) ? - sourceCell : targetCell, (edge.invert) ? targetCell : sourceCell, edgeStyle); - }); - const edge = { - invert: true - }; - let targetCell = null; - let sourceCell = null; - // locate edge source and target cells - for (const key in model.cells) { - if(targetCell && sourceCell) - break; - if (Object.hasOwnProperty.call(model.cells, key)) { - const mxcell = model.cells[key]; - if(mxcell.style && mxcell.style.trim().startsWith("swimlane;")){ - const entity = { - name: mxcell.value, - attributes: [] - }; - const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; - const isForeignTable = entity.name == fk.ReferencesTableName; - if(isPrimaryTable || isForeignTable){ - for (let c = 0; c < mxcell.children.length; c++) { - if(targetCell && sourceCell) - break; - const col = mxcell.children[c]; - if(col.mxObjectId.indexOf("mxCell") !== -1) { - if(col.style && col.style.trim().startsWith("shape=partialRectangle")){ - const attribute = getDbLabel(col.value, columnQuantifiers); - if(isPrimaryTable && dbTypeEnds(attribute.attributeName) == fk.PrimaryKeyName){ - targetCell = col; - break; - } else if(isForeignTable && dbTypeEnds(attribute.attributeName) == fk.ReferencesPropertyName){ - sourceCell = col; - break; - } - } - } - } - } - - } - } - } - if(targetCell && sourceCell) - insertEdge(targetCell, sourceCell, edge); - } - }); - graph.scrollCellToVisible(graph.getSelectionCell()); - } - - wndFromNOSQL.setVisible(false); - }; - mxUtils.br(divFromNOSQL); const resetBtnFromNOSQL = mxUtils.button(mxResources.get("Reset TS"), function() { diff --git a/src/nosql.ts b/src/nosql.ts index 8b17595..a981233 100644 --- a/src/nosql.ts +++ b/src/nosql.ts @@ -4,7 +4,7 @@ import { DatabaseModel, ForeignKeyModel, PrimaryKeyModel, PropertyModel, TableMo import { JSONSchema4, JSONSchema4TypeName } from "json-schema"; import { convertCoreTypesToJsonSchema, convertOpenApiToCoreTypes, jsonSchemaDocumentToOpenApi } from "core-types-json-schema"; import { JsonSchemaDocumentToOpenApiOptions, PartialOpenApiSchema } from "openapi-json-schema"; -import { GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; +import { CreateTableUI, GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; import { pluginVersion } from "./utils/constants"; import { ConvertOpenApiToDatabaseModel, dbToOpenApi, GeneratePropertyModel } from "./utils/nosqlUtils"; import { defaultResetOpenApi } from "./utils/constants-nosql"; @@ -130,36 +130,6 @@ Draw.loadPlugin(function(ui) { wndFromNOSQL.setResizable(false); wndFromNOSQL.setClosable(true); - function AddRow(propertyModel: PropertyModel, tableName: string) { - - const cellName = propertyModel.Name + (propertyModel.ColumnProperties ? " " + propertyModel.ColumnProperties: ""); - - rowCell = new mxCell(cellName, new mxGeometry(0, 0, 90, 26), - "shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;"); - rowCell.vertex = true; - - const columnType = propertyModel.IsPrimaryKey && propertyModel.IsForeignKey ? "PK | FK" : propertyModel.IsPrimaryKey ? "PK" : propertyModel.IsForeignKey ? "FK" : ""; - - const left = sb.cloneCell(rowCell, columnType); - left.connectable = false; - left.style = "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;"; - left.geometry.width = 54; - left.geometry.height = 26; - rowCell.insert(left); - - const size = ui.editor.graph.getPreferredSizeForCell(rowCell); - - if(tableCell){ - if (size !== null && tableCell.geometry.width < size.width + 10) { - tableCell.geometry.width = size.width + 10; - } - - tableCell.insert(rowCell); - tableCell.geometry.height += 26; - } - - }; - function parseFromInput(text: string, type?: "ts" | "openapi" | undefined) { // reset values cells = []; @@ -190,7 +160,13 @@ Draw.loadPlugin(function(ui) { primaryKeyList = models.PrimaryKeyList; tableList = models.TableList; exportedTables = tableList.length; - CreateTableUI(type); + const createTableResult = CreateTableUI(ui, wndFromNOSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type); + if(createTableResult){ + cells = createTableResult.cells; + dx = createTableResult.dx; + tableCell = createTableResult.tableCell; + rowCell = createTableResult.rowCell; + } } } catch (error) { @@ -199,113 +175,6 @@ Draw.loadPlugin(function(ui) { } }; - function CreateTableUI(type: "ts" | "openapi" | undefined) { - tableList.forEach(function(tableModel) { - //Define table size width - const maxNameLenght = 100 + tableModel.Name.length; - - //Create Table - tableCell = new mxCell(tableModel.Name, new mxGeometry(dx, 0, maxNameLenght, 26), - "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;"); - tableCell.vertex = true; - - //Resize row - if(rowCell){ - const size = ui.editor.graph.getPreferredSizeForCell(rowCell); - if (size !== null) { - tableCell.geometry.width = size.width + maxNameLenght; - } - } - - //Add Table to cells - cells.push(tableCell); - - //Add properties - tableModel.Properties.forEach(function(propertyModel) { - - //Add row - AddRow(propertyModel, tableModel.Name); - }); - - //Close table - dx += tableCell.geometry.width + 40; - tableCell = null; - }); - - if (cells.length > 0) { - const graph = ui.editor.graph; - const view = graph.view; - const bds = graph.getGraphBounds(); - - // Computes unscaled, untranslated graph bounds - const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize); - const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + 4 * graph.gridSize); - - graph.setSelectionCells(graph.importCells(cells, x, y)); - // add foreign key edges - const model = graph.getModel(); - const columnQuantifiers = GetColumnQuantifiers(type); - // const pt = graph.getFreeInsertPoint(); - foreignKeyList.forEach(function(fk){ - if(fk.IsDestination && fk.PrimaryKeyName && fk.ReferencesPropertyName && - fk.PrimaryKeyTableName && fk.ReferencesTableName) { - const insertEdge = mxUtils.bind(this, function(targetCell, sourceCell, edge){ - const label = ""; - const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; - const edgeCell = graph.insertEdge(null, null, label || "", (edge.invert) ? - sourceCell : targetCell, (edge.invert) ? targetCell : sourceCell, edgeStyle); - }); - const edge = { - invert: true - }; - let targetCell = null; - let sourceCell = null; - // locate edge source and target cells - for (const key in model.cells) { - if(targetCell && sourceCell) - break; - if (Object.hasOwnProperty.call(model.cells, key)) { - const mxcell = model.cells[key]; - if(mxcell.style && mxcell.style.trim().startsWith("swimlane;")){ - const entity = { - name: mxcell.value, - attributes: [] - }; - const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; - const isForeignTable = entity.name == fk.ReferencesTableName; - if(isPrimaryTable || isForeignTable){ - for (let c = 0; c < mxcell.children.length; c++) { - if(targetCell && sourceCell) - break; - const col = mxcell.children[c]; - if(col.mxObjectId.indexOf("mxCell") !== -1) { - if(col.style && col.style.trim().startsWith("shape=partialRectangle")){ - const attribute = getDbLabel(col.value, columnQuantifiers); - if(isPrimaryTable && dbTypeEnds(attribute.attributeName) == fk.PrimaryKeyName){ - targetCell = col; - break; - } else if(isForeignTable && dbTypeEnds(attribute.attributeName) == fk.ReferencesPropertyName){ - sourceCell = col; - break; - } - } - } - } - } - - } - } - } - if(targetCell && sourceCell) - insertEdge(targetCell, sourceCell, edge); - } - }); - graph.scrollCellToVisible(graph.getSelectionCell()); - } - - wndFromNOSQL.setVisible(false); - }; - mxUtils.br(divFromNOSQL); const resetOpenAPIBtnFromNOSQL = mxUtils.button("Reset OpenAPI", function() { diff --git a/src/sql.ts b/src/sql.ts index 09df6ef..da0b1d4 100644 --- a/src/sql.ts +++ b/src/sql.ts @@ -3,7 +3,7 @@ import { DbDefinition, DbRelationshipDefinition } from "@funktechno/little-merma import { TableAttribute, TableEntity } from "./types/sql-plugin-types"; import { SqlSimpleParser } from "@funktechno/sqlsimpleparser"; import { ForeignKeyModel, PrimaryKeyModel, PropertyModel, TableModel } from "@funktechno/sqlsimpleparser/lib/types"; -import { GetColumnQuantifiers, RemoveNameQuantifiers, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; +import { CreateTableUI, GetColumnQuantifiers, RemoveNameQuantifiers, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; import { pluginVersion } from "./utils/constants"; declare const window: Customwindow; @@ -157,36 +157,6 @@ Draw.loadPlugin(function(ui) { wndFromSQL.setResizable(false); wndFromSQL.setClosable(true); - function AddRow(propertyModel: PropertyModel, tableName: string) { - - const cellName = propertyModel.Name + (propertyModel.ColumnProperties ? " " + propertyModel.ColumnProperties: ""); - - rowCell = new mxCell(cellName, new mxGeometry(0, 0, 90, 26), - "shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;"); - rowCell.vertex = true; - - const columnType = propertyModel.IsPrimaryKey && propertyModel.IsForeignKey ? "PK | FK" : propertyModel.IsPrimaryKey ? "PK" : propertyModel.IsForeignKey ? "FK" : ""; - - const left = sb.cloneCell(rowCell, columnType); - left.connectable = false; - left.style = "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;"; - left.geometry.width = 54; - left.geometry.height = 26; - rowCell.insert(left); - - const size = ui.editor.graph.getPreferredSizeForCell(rowCell); - - if(tableCell){ - if (size !== null && tableCell.geometry.width < size.width + 10) { - tableCell.geometry.width = size.width + 10; - } - - tableCell.insert(rowCell); - tableCell.geometry.height += 26; - } - - }; - function parseSql(text: string, type?: "mysql" | "sqlite" | "postgres" | "sqlserver" | undefined) { // reset values cells = []; @@ -209,114 +179,13 @@ Draw.loadPlugin(function(ui) { exportedTables = tableList.length; //Create Table in UI - CreateTableUI(type); - }; - - function CreateTableUI(type: "mysql" | "sqlite" | "postgres" | "sqlserver" | undefined) { - tableList.forEach(function(tableModel) { - //Define table size width - const maxNameLenght = 100 + tableModel.Name.length; - - //Create Table - tableCell = new mxCell(tableModel.Name, new mxGeometry(dx, 0, maxNameLenght, 26), - "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;"); - tableCell.vertex = true; - - //Resize row - if(rowCell){ - const size = ui.editor.graph.getPreferredSizeForCell(rowCell); - if (size !== null) { - tableCell.geometry.width = size.width + maxNameLenght; - } - } - - //Add Table to cells - cells.push(tableCell); - - //Add properties - tableModel.Properties.forEach(function(propertyModel) { - - //Add row - AddRow(propertyModel, tableModel.Name); - }); - - //Close table - dx += tableCell.geometry.width + 40; - tableCell = null; - }); - - if (cells.length > 0) { - const graph = ui.editor.graph; - const view = graph.view; - const bds = graph.getGraphBounds(); - - // Computes unscaled, untranslated graph bounds - const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize); - const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + 4 * graph.gridSize); - - graph.setSelectionCells(graph.importCells(cells, x, y)); - // add foreign key edges - const model = graph.getModel(); - const columnQuantifiers = GetColumnQuantifiers(type); - // const pt = graph.getFreeInsertPoint(); - foreignKeyList.forEach(function(fk){ - if(fk.IsDestination && fk.PrimaryKeyName && fk.ReferencesPropertyName && - fk.PrimaryKeyTableName && fk.ReferencesTableName) { - const insertEdge = mxUtils.bind(this, function(targetCell, sourceCell, edge){ - const label = ""; - const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; - const edgeCell = graph.insertEdge(null, null, label || "", (edge.invert) ? - sourceCell : targetCell, (edge.invert) ? targetCell : sourceCell, edgeStyle); - }); - const edge = { - invert: true - }; - let targetCell = null; - let sourceCell = null; - // locate edge source and target cells - for (const key in model.cells) { - if(targetCell && sourceCell) - break; - if (Object.hasOwnProperty.call(model.cells, key)) { - const mxcell = model.cells[key]; - if(mxcell.style && mxcell.style.trim().startsWith("swimlane;")){ - const entity = { - name: mxcell.value, - attributes: [] - }; - const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; - const isForeignTable = entity.name == fk.ReferencesTableName; - if(isPrimaryTable || isForeignTable){ - for (let c = 0; c < mxcell.children.length; c++) { - if(targetCell && sourceCell) - break; - const col = mxcell.children[c]; - if(col.mxObjectId.indexOf("mxCell") !== -1) { - if(col.style && col.style.trim().startsWith("shape=partialRectangle")){ - const attribute = getDbLabel(col.value, columnQuantifiers); - if(isPrimaryTable && attribute.attributeName == fk.PrimaryKeyName){ - targetCell = col; - break; - } else if(isForeignTable && attribute.attributeName == fk.ReferencesPropertyName){ - sourceCell = col; - break; - } - } - } - } - } - - } - } - } - if(targetCell && sourceCell) - insertEdge(targetCell, sourceCell, edge); - } - }); - graph.scrollCellToVisible(graph.getSelectionCell()); + const createTableResult = CreateTableUI(ui, wndFromSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type); + if(createTableResult){ + cells = createTableResult.cells; + dx = createTableResult.dx; + tableCell = createTableResult.tableCell; + rowCell = createTableResult.rowCell; } - - wndFromSQL.setVisible(false); }; mxUtils.br(divFromSQL); diff --git a/src/utils/constants.ts b/src/utils/constants.ts index fbb94c3..c00a0c3 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -12,4 +12,10 @@ export const formatKeyword = "@format"; export const enumKeyword = "enum"; +export const nullableKeyword = "nullable"; + +export const arrayKeyword = "array"; + +export const objectKeyword = "object"; + export const validEnumTypes = ["string", "number", "integer", "boolean"]; \ No newline at end of file diff --git a/src/utils/nosqlUtils.ts b/src/utils/nosqlUtils.ts index f4066eb..42ec77f 100644 --- a/src/utils/nosqlUtils.ts +++ b/src/utils/nosqlUtils.ts @@ -3,13 +3,28 @@ import { OpenApiSchemaTypeDefinition, PartialOpenApiSchema, } from "openapi-json-schema"; -import { commentColumnQuantifiers, enumKeyword, formatKeyword, pluginVersion, validEnumTypes } from "./constants"; +import { + arrayKeyword, + commentColumnQuantifiers, + enumKeyword, + formatKeyword, + nullableKeyword, + objectKeyword, + pluginVersion, + validEnumTypes, +} from "./constants"; import { JSONSchema4, JSONSchema4TypeName } from "json-schema"; import { ColumnQuantifiers, DatabaseModelResult, } from "../types/sql-plugin-types"; -import { dbTypeEnds, generateComment, getCommentIndexes, getDbLabel } from "./sharedUtils"; +import { + dbTypeEnds, + generateComment, + GetColumnQuantifiers, + getCommentIndexes, + getDbLabel, +} from "./sharedUtils"; import { DatabaseModel, ForeignKeyModel, @@ -45,38 +60,37 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { let commentIndexes = getCommentIndexes(key); let description = ""; let formatValue = ""; - if(commentIndexes.start > -1 && commentIndexes.end > -1) { - - let result = schemaKey.toString().trim(); - commentIndexes = getCommentIndexes(result); - const firstSpaceIndex = commentIndexes.start; - const lastSpaceIndex= commentIndexes.end; - schemaKey = result.substring(0, commentIndexes.beforeStart); - result = result.substring(firstSpaceIndex, lastSpaceIndex).trim(); - if (result.indexOf(formatKeyword) !== -1) { + if (commentIndexes.start > -1 && commentIndexes.end > -1) { + let result = schemaKey.toString().trim(); + commentIndexes = getCommentIndexes(result); + const firstSpaceIndex = commentIndexes.start; + const lastSpaceIndex = commentIndexes.end; + schemaKey = result.substring(0, commentIndexes.beforeStart); + result = result.substring(firstSpaceIndex, lastSpaceIndex).trim(); + if (result.indexOf(formatKeyword) !== -1) { const formatIndex = result.indexOf(formatKeyword); - formatValue = result.substring( - formatIndex + formatKeyword.length - ).trim(); + formatValue = result + .substring(formatIndex + formatKeyword.length) + .trim(); result = result.substring(0, formatIndex); - } - if (result) { - description = result; - } + } + if (result) { + description = result; + } } if (schema[schemaKey]) { continue; } schema[schemaKey] = { - type: "object", + type: objectKeyword, title: schemaKey, additionalProperties: false, properties: {}, }; - if(description) { + if (description) { schema[schemaKey].description = description.trim(); } - if(formatValue) { + if (formatValue) { schema[schemaKey].format = formatValue.trim(); } for (let p = 0; p < entity.attributes.length; p++) { @@ -112,8 +126,10 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { let result = attribute.attributeType; const commentIndexes = getCommentIndexes(result); const firstSpaceIndex = commentIndexes.start; - const lastSpaceIndex= commentIndexes.end; - const enumRaw = result.substring(0, commentIndexes.beforeStart).trim(); + const lastSpaceIndex = commentIndexes.end; + const enumRaw = result + .substring(0, commentIndexes.beforeStart) + .trim(); if (enumRaw) { try { enumValues = JSON.parse(enumRaw); @@ -181,11 +197,19 @@ export function GeneratePropertyModel( propertyName: string, property: JSONSchema4 ): PropertyModel { - let columnProperties = (property.type ?? "object").toString(); + let columnProperties = (property.type ?? objectKeyword).toString(); + if (columnProperties === arrayKeyword) { + if (property.items && typeof property.items === objectKeyword) { + if ((property.items as JSONSchema4).format) + columnProperties = `${(property.items as JSONSchema4).format}[]`; + else if ((property.items as JSONSchema4).type) + columnProperties = `${(property.items as JSONSchema4).type}[]`; + } + } if (property.enum) { columnProperties = `${JSON.stringify(property.enum)}`; } else if (property.nullable) { - columnProperties += " nullable"; + columnProperties += ` ${nullableKeyword}`; } const description = generateComment(property.description, property.format); if (description) { @@ -223,7 +247,7 @@ export function ConvertOpenApiToDatabaseModel( if (schema.enum) { const enumList = schema.enum; // serialize to string enum [values] - const propertyKey = `${schema.type} enum`; + const propertyKey = `${schema.type} ${enumKeyword}`; const property: JSONSchema4 = { enum: enumList, }; @@ -251,52 +275,71 @@ export function ConvertOpenApiToDatabaseModel( Object.prototype.hasOwnProperty.call(schema.properties, propertyKey) ) { const property = schema.properties[propertyKey]; + // TODO: if note object or array use ref + + let refName: string | null | undefined = null; + if (property.$ref) { + refName = property.$ref.split("/").pop(); + } else if (property.items && typeof property.items == objectKeyword) { + refName = (property.items as JSONSchema4).$ref?.split("/").pop(); + } else if ( + property.additionalItems && + typeof property.additionalItems == "object" + ) { + refName = property.additionalItems.$ref?.split("/").pop(); + } + if (refName) { + const refSchema: JSONSchema4 | null = schemas[ + refName + ] as JSONSchema4; + if (refSchema && !refSchema.enum) { + const comment = generateComment( + refSchema.description, + refSchema.format + ); + if (comment) { + refName = `${dbTypeEnds(refName)} ${comment}`; + } else { + refName = dbTypeEnds(refName); + } + } else { + refName = dbTypeEnds(refName); + } + } + if (refName && !property.type) { + property.type = refName as JSONSchema4TypeName; + } const propertyModel: PropertyModel = GeneratePropertyModel( tableModel.Name, propertyKey, property ); - if ( - propertyModel.ColumnProperties.includes("object") || - propertyModel.ColumnProperties.includes("array") - ) { - let refName: string | null | undefined = null; - if (property.$ref) { - refName = property.$ref.split("/").pop(); - } else if (property.items && typeof property.items == "object") { - refName = (property.items as JSONSchema4).$ref?.split("/").pop(); - } - if(refName) { - const refSchema:JSONSchema4|null = schemas[refName] as JSONSchema4; - if(refSchema && !refSchema.enum){ - const comment = generateComment(refSchema.description, refSchema.format); - if (comment) { - refName = `${dbTypeEnds(refName)} ${comment}`; - } - } - } - if (refName) { - const primaryKeyModel: ForeignKeyModel = { - PrimaryKeyTableName: tableModel.Name, - ReferencesTableName: refName, - PrimaryKeyName: dbTypeEnds(propertyKey), - // should just point to first property in uml table - ReferencesPropertyName: "", - IsDestination: false, - }; - const foreignKeyModel: ForeignKeyModel = { - ReferencesTableName: tableModel.Name, - PrimaryKeyTableName: refName, - ReferencesPropertyName: dbTypeEnds(propertyKey), - // should just point to first property in uml table - PrimaryKeyName: "", - IsDestination: true, - }; - models.ForeignKeyList.push(foreignKeyModel); - models.ForeignKeyList.push(primaryKeyModel); - propertyModel.IsForeignKey = true; - } + // if ( + // propertyModel.ColumnProperties.includes(objectKeyword) || + // propertyModel.ColumnProperties.includes(arrayKeyword) + // ) { + if (refName) { + const primaryKeyModel: ForeignKeyModel = { + PrimaryKeyTableName: tableModel.Name, + ReferencesTableName: refName, + PrimaryKeyName: dbTypeEnds(propertyKey), + // should just point to first property in uml table + ReferencesPropertyName: "", + IsDestination: false, + }; + const foreignKeyModel: ForeignKeyModel = { + ReferencesTableName: tableModel.Name, + PrimaryKeyTableName: refName, + ReferencesPropertyName: dbTypeEnds(propertyKey), + // should just point to first property in uml table + PrimaryKeyName: "", + IsDestination: true, + }; + models.ForeignKeyList.push(foreignKeyModel); + models.ForeignKeyList.push(primaryKeyModel); + propertyModel.IsForeignKey = true; } + // } tableModel.Properties.push(propertyModel); } @@ -304,7 +347,7 @@ export function ConvertOpenApiToDatabaseModel( models.TableList.push(tableModel); // may no longer be needed - if(!tableDict[originalKey]) { + if (!tableDict[originalKey]) { tableDict[originalKey] = tableModel; } } @@ -316,7 +359,7 @@ export function ConvertOpenApiToDatabaseModel( let property = models.TableList.find( (t) => t.Name == fk.ReferencesTableName )?.Properties[0]; - if(!property) { + if (!property) { // attempt a comment lookup property = tableDict[fk.ReferencesTableName]?.Properties[0]; } @@ -329,7 +372,7 @@ export function ConvertOpenApiToDatabaseModel( let property = models.TableList.find( (t) => t.Name == fk.PrimaryKeyTableName )?.Properties[0]; - if(!property) { + if (!property) { // attempt a comment lookup property = tableDict[fk.PrimaryKeyTableName]?.Properties[0]; } diff --git a/src/utils/sharedUtils.ts b/src/utils/sharedUtils.ts index bf3863d..b17c610 100644 --- a/src/utils/sharedUtils.ts +++ b/src/utils/sharedUtils.ts @@ -1,6 +1,19 @@ -import { DbDefinition, DbRelationshipDefinition } from "@funktechno/little-mermaid-2-the-sql/lib/src/types"; -import { ColumnQuantifiers, DatabaseModelResult, TableAttribute, TableEntity } from "../types/sql-plugin-types"; +import { + DbDefinition, + DbRelationshipDefinition, +} from "@funktechno/little-mermaid-2-the-sql/lib/src/types"; +import { + ColumnQuantifiers, + DatabaseModelResult, + TableAttribute, + TableEntity, +} from "../types/sql-plugin-types"; import { commentColumnQuantifiers, formatKeyword } from "./constants"; +import { + TableModel, + ForeignKeyModel, + PropertyModel, +} from "@funktechno/sqlsimpleparser/lib/types"; /** * return text quantifiers for dialect @@ -86,288 +99,624 @@ export function getDbLabel( return attribute; } - export function entityName(description?: string, format?: string): string { - let result = ""; - if (description) { - result += `${description}`; - } - if (format) { - result += ` @format ${format}`; - } - if(result){ - result = result.trim(); - result = `/** ${result} */`; - } - return result; + let result = ""; + if (description) { + result += `${description}`; + } + if (format) { + result += ` ${formatKeyword} ${format}`; + } + if (result) { + result = result.trim(); + result = `/** ${result} */`; + } + return result; } export function getCommentIndexes(result: string) { - let hasComment = false; - if(result.indexOf(commentColumnQuantifiers.Start) !== -1 && result.indexOf(commentColumnQuantifiers.End) !== -1){ - hasComment = true; - } - const beforeIndex = hasComment ? result.indexOf(commentColumnQuantifiers.Start) : -1; - const firstSpaceIndex = hasComment ? result.indexOf(commentColumnQuantifiers.Start) + commentColumnQuantifiers.Start.length : -1; - const lastSpaceIndex = hasComment ? result.indexOf(commentColumnQuantifiers.End) -1 : -1; - - return { - beforeStart: beforeIndex, - start: firstSpaceIndex, - end: lastSpaceIndex - }; + let hasComment = false; + if ( + result.indexOf(commentColumnQuantifiers.Start) !== -1 && + result.indexOf(commentColumnQuantifiers.End) !== -1 + ) { + hasComment = true; + } + const beforeIndex = hasComment + ? result.indexOf(commentColumnQuantifiers.Start) + : -1; + const firstSpaceIndex = hasComment + ? result.indexOf(commentColumnQuantifiers.Start) + + commentColumnQuantifiers.Start.length + : -1; + const lastSpaceIndex = hasComment + ? result.indexOf(commentColumnQuantifiers.End) - 1 + : -1; + + return { + beforeStart: beforeIndex, + start: firstSpaceIndex, + end: lastSpaceIndex, + }; } /** * generate db from drawio graph models - * @param ui - * @param type - * @returns + * @param ui + * @param type + * @returns */ -export function getMermaidDiagramDb(ui: DrawioUI, type: "mysql" | "sqlserver" | "sqlite" | "postgres" | "ts" | "openapi" | undefined): DatabaseModelResult{ - const model = ui.editor.graph.getModel(); - // same models from mermaid for diagram relationships - // only difference is entities is an array rather than object to allow duplicate tables - const entities: Record = {}; - const relationships: DbRelationshipDefinition[] = []; - // TODO: support for ts and openapi enum - // build models - for (const key in model.cells) { - if (Object.hasOwnProperty.call(model.cells, key)) { - const mxcell = model.cells[key]; - if(mxcell.mxObjectId.indexOf("mxCell") !== -1) { - if(mxcell.style && mxcell.style.trim().startsWith("swimlane;")){ - let entityName = mxcell.value.toString(); - let description = ""; - let formatValue = ""; - if ( - entityName?.includes(commentColumnQuantifiers.Start) && - entityName?.includes(commentColumnQuantifiers.End) - ) { - let result = entityName.toString(); - const commentIndexes = getCommentIndexes(result); - const firstSpaceIndex = commentIndexes.start; - const lastSpaceIndex= commentIndexes.end; - entityName = result.substring(0, commentIndexes.beforeStart); - result = result.substring(firstSpaceIndex, lastSpaceIndex); - if (result.indexOf(formatKeyword) !== -1) { - const formatIndex = result.indexOf(formatKeyword); - formatValue = result.substring( - formatIndex + formatKeyword.length - ).trim(); - result = result.substring(0, formatIndex); - } - if (result) { - description = result; - } - - // decription = attribute.attributeType?.replace("/**", "").replace("*/", ""); - } - const entity: TableEntity = { - name: RemoveNameQuantifiers(entityName), - attributes: [] as TableAttribute[], - }; - const comment = generateComment(description, formatValue); - if(comment){ - entity.name += comment; - } - // const comment = - for (let c = 0; c < mxcell.children.length; c++) { - const col = mxcell.children[c]; - if(col.mxObjectId.indexOf("mxCell") !== -1) { - if(col.style && col.style.trim().startsWith("shape=partialRectangle")){ - const columnQuantifiers = GetColumnQuantifiers(type); - //Get delimiter of column name - //Get full name - const attribute = getDbLabel(col.value, columnQuantifiers); - const attributeKeyType = col.children.find(x=> ["FK","PK"].findIndex(k => k== x.value.toUpperCase()) !== -1 || - x.value.toUpperCase().indexOf("PK,")!=-1); - if(attributeKeyType){ - attribute.attributeKeyType = attributeKeyType.value; - if(attribute.attributeKeyType != "PK" && attribute.attributeKeyType.indexOf("PK") != -1){ - attribute.attributeKeyType = "PK"; - } - } - entity.attributes.push(attribute); - if(col.edges && col.edges.length){ - // check for edges foreign keys - for (let e = 0; e < col.edges.length; e++) { - const edge = col.edges[e]; - if(edge.mxObjectId.indexOf("mxCell") !== -1) { - if(edge.style && edge.style.indexOf("endArrow=") != -1 && edge.source && - edge.source.value && edge.target && edge.target.value){ - // need to check if end is open or certain value to determin relationship type - // extract endArrow txt - // check if both match and contain many or open - // if both match and are many then create a new table - const endCheck = "endArrow="; - const endArr = edge.style.indexOf(endCheck) != -1 ? - edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length, edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length).indexOf(";") + edge.style.indexOf(endCheck) + endCheck.length) - : ""; - const startCheck = "startArrow="; - const startArr = edge.style.indexOf(startCheck) != -1 ? - edge.style.substring(edge.style.indexOf(startCheck) + startCheck.length, edge.style.substring(edge.style.indexOf(startCheck) + startCheck.length).indexOf(";") + edge.style.indexOf(startCheck) + startCheck.length) - : ""; - - const manyCheck = ["open","many"]; - const sourceIsPrimary = endArr && manyCheck - .findIndex(x => endArr.toLocaleLowerCase().indexOf(x)!=-1) != -1; - const targetIsPrimary = startArr && manyCheck - .findIndex(x => startArr.toLocaleLowerCase().indexOf(x)!=-1) != -1; - // has to be one to many and not one to one - if((targetIsPrimary || sourceIsPrimary) && - !(targetIsPrimary && sourceIsPrimary) - ){ - let sourceId = edge.source.value; - const sourceAttr = getDbLabel(sourceId, columnQuantifiers); - sourceId = sourceAttr.attributeName; - const sourceEntity = RemoveNameQuantifiers(edge.source.parent.value); - let targetId = edge.target.value; - const targetAttr = getDbLabel(targetId, columnQuantifiers); - targetId = targetAttr.attributeName; - const targetEntity = RemoveNameQuantifiers(edge.target.parent.value); - // entityA primary - // entityB foreign - const relationship: DbRelationshipDefinition = { - entityA: sourceIsPrimary ? sourceEntity : targetEntity, - entityB: sourceIsPrimary ? targetEntity : sourceEntity, - // based off of styles? - relSpec: { - cardA: "ZERO_OR_MORE", - cardB: "ONLY_ONE", - relType: "IDENTIFYING" - }, - roleA: sourceIsPrimary ? - `[${sourceEntity}.${sourceId}] to [${targetEntity}.${targetId}]` : - `[${targetEntity}.${targetId}] to [${sourceEntity}.${sourceId}]` - }; - // check that is doesn't already exist - const exists = relationships.findIndex(r => r.entityA == relationship.entityA && r.entityB == relationship.entityB && r.roleA == relationship.roleA); - if(exists ==-1){ - relationships.push(relationship); - } - } else if(targetIsPrimary && sourceIsPrimary){ - // add a new many to many table - let sourceId = edge.source.value; - const sourceAttr = getDbLabel(sourceId, columnQuantifiers); - sourceAttr.attributeKeyType = "PK"; - sourceId = sourceAttr.attributeName; - const sourceEntity = RemoveNameQuantifiers(edge.source.parent.value); - let targetId = edge.target.value; - const targetAttr = getDbLabel(targetId, columnQuantifiers); - targetAttr.attributeKeyType = "PK"; - targetId = targetAttr.attributeName; - const targetEntity = RemoveNameQuantifiers(edge.target.parent.value); - const compositeEntity = { - name: RemoveNameQuantifiers(sourceEntity) + "_" + RemoveNameQuantifiers(targetEntity), - attributes: [sourceAttr, targetAttr] - }; - // add composite entity - if(entities[compositeEntity.name]){ - // DON'T add duplicate composite tables - } else { - entities[compositeEntity.name] = compositeEntity; - } - // entityA primary - // entityB foreign - const relationship = { - entityA: sourceEntity, - entityB: compositeEntity.name, - // based off of styles? - relSpec: { - cardA: "ZERO_OR_MORE", - cardB: "ONLY_ONE", - relType: "IDENTIFYING" - }, - roleA: `[${sourceEntity}.${sourceId}] to [${compositeEntity.name}.${sourceId}]` - }; - // check that is doesn't already exist - let exists = relationships.findIndex(r => r.entityA == relationship.entityA && r.entityB == relationship.entityB && r.roleA == relationship.roleA); - if(exists ==-1){ - relationships.push(relationship); - } - const relationship2 = { - entityA: targetEntity, - entityB: compositeEntity.name, - // based off of styles? - relSpec: { - cardA: "ZERO_OR_MORE", - cardB: "ONLY_ONE", - relType: "IDENTIFYING" - }, - roleA: `[${targetEntity}.${targetId}] to [${compositeEntity.name}.${targetId}]` - }; - // check that is doesn't already exist - exists = relationships.findIndex(r => r.entityA == relationship2.entityA && r.entityB == relationship2.entityB && r.roleA == relationship2.roleA); - if(exists ==-1){ - relationships.push(relationship2); - } - } - - } - } - - } - } - } - } - } - // allows for duplicates if another table has the same name - if(entities[entity.name]){ - let count = 2; - while(entities[entity.name + count.toString()]){ - count++; +export function getMermaidDiagramDb( + ui: DrawioUI, + type: + | "mysql" + | "sqlserver" + | "sqlite" + | "postgres" + | "ts" + | "openapi" + | undefined +): DatabaseModelResult { + const model = ui.editor.graph.getModel(); + // same models from mermaid for diagram relationships + // only difference is entities is an array rather than object to allow duplicate tables + const entities: Record = {}; + const relationships: DbRelationshipDefinition[] = []; + // TODO: support for ts and openapi enum + // build models + // fix fk for comments + for (const key in model.cells) { + if (Object.hasOwnProperty.call(model.cells, key)) { + const mxcell = model.cells[key]; + if (mxcell.mxObjectId.indexOf("mxCell") !== -1) { + if (mxcell.style && mxcell.style.trim().startsWith("swimlane;")) { + let entityName = mxcell.value.toString(); + let description = ""; + let formatValue = ""; + if ( + entityName?.includes(commentColumnQuantifiers.Start) && + entityName?.includes(commentColumnQuantifiers.End) + ) { + let result = entityName.toString(); + const commentIndexes = getCommentIndexes(result); + const firstSpaceIndex = commentIndexes.start; + const lastSpaceIndex = commentIndexes.end; + entityName = result.substring(0, commentIndexes.beforeStart); + result = result.substring(firstSpaceIndex, lastSpaceIndex); + if (result.indexOf(formatKeyword) !== -1) { + const formatIndex = result.indexOf(formatKeyword); + formatValue = result + .substring(formatIndex + formatKeyword.length) + .trim(); + result = result.substring(0, formatIndex); + } + if (result) { + description = result; + } + + // decription = attribute.attributeType?.replace("/**", "").replace("*/", ""); + } + const entity: TableEntity = { + name: RemoveNameQuantifiers(entityName), + attributes: [] as TableAttribute[], + }; + const comment = generateComment(description, formatValue); + if (comment) { + entity.name += comment; + } + // const comment = + for (let c = 0; c < mxcell.children.length; c++) { + const col = mxcell.children[c]; + if (col.mxObjectId.indexOf("mxCell") !== -1) { + if ( + col.style && + col.style.trim().startsWith("shape=partialRectangle") + ) { + const columnQuantifiers = GetColumnQuantifiers(type); + //Get delimiter of column name + //Get full name + const attribute = getDbLabel(col.value, columnQuantifiers); + const attributeKeyType = col.children.find( + (x) => + ["FK", "PK"].findIndex( + (k) => k == x.value.toUpperCase() + ) !== -1 || x.value.toUpperCase().indexOf("PK,") != -1 + ); + if (attributeKeyType) { + attribute.attributeKeyType = attributeKeyType.value; + if ( + attribute.attributeKeyType != "PK" && + attribute.attributeKeyType.indexOf("PK") != -1 + ) { + attribute.attributeKeyType = "PK"; + } + } + entity.attributes.push(attribute); + if (col.edges && col.edges.length) { + // check for edges foreign keys + for (let e = 0; e < col.edges.length; e++) { + const edge = col.edges[e]; + if (edge.mxObjectId.indexOf("mxCell") !== -1) { + if ( + edge.style && + edge.style.indexOf("endArrow=") != -1 && + edge.source && + edge.source.value && + edge.target && + edge.target.value + ) { + // need to check if end is open or certain value to determin relationship type + // extract endArrow txt + // check if both match and contain many or open + // if both match and are many then create a new table + const endCheck = "endArrow="; + const endArr = + edge.style.indexOf(endCheck) != -1 + ? edge.style.substring( + edge.style.indexOf(endCheck) + endCheck.length, + edge.style + .substring( + edge.style.indexOf(endCheck) + + endCheck.length + ) + .indexOf(";") + + edge.style.indexOf(endCheck) + + endCheck.length + ) + : ""; + const startCheck = "startArrow="; + const startArr = + edge.style.indexOf(startCheck) != -1 + ? edge.style.substring( + edge.style.indexOf(startCheck) + + startCheck.length, + edge.style + .substring( + edge.style.indexOf(startCheck) + + startCheck.length + ) + .indexOf(";") + + edge.style.indexOf(startCheck) + + startCheck.length + ) + : ""; + + const manyCheck = ["open", "many"]; + const sourceIsPrimary = + endArr && + manyCheck.findIndex( + (x) => endArr.toLocaleLowerCase().indexOf(x) != -1 + ) != -1; + const targetIsPrimary = + startArr && + manyCheck.findIndex( + (x) => startArr.toLocaleLowerCase().indexOf(x) != -1 + ) != -1; + // has to be one to many and not one to one + if ( + (targetIsPrimary || sourceIsPrimary) && + !(targetIsPrimary && sourceIsPrimary) + ) { + let sourceId = edge.source.value; + const sourceAttr = getDbLabel( + sourceId, + columnQuantifiers + ); + sourceId = sourceAttr.attributeName; + const sourceEntity = RemoveNameQuantifiers( + edge.source.parent.value + ); + let targetId = edge.target.value; + const targetAttr = getDbLabel( + targetId, + columnQuantifiers + ); + targetId = targetAttr.attributeName; + const targetEntity = RemoveNameQuantifiers( + edge.target.parent.value + ); + // entityA primary + // entityB foreign + const relationship: DbRelationshipDefinition = { + entityA: sourceIsPrimary + ? sourceEntity + : targetEntity, + entityB: sourceIsPrimary + ? targetEntity + : sourceEntity, + // based off of styles? + relSpec: { + cardA: "ZERO_OR_MORE", + cardB: "ONLY_ONE", + relType: "IDENTIFYING", + }, + roleA: sourceIsPrimary + ? `[${sourceEntity}.${sourceId}] to [${targetEntity}.${targetId}]` + : `[${targetEntity}.${targetId}] to [${sourceEntity}.${sourceId}]`, + }; + // check that is doesn't already exist + const exists = relationships.findIndex( + (r) => + r.entityA == relationship.entityA && + r.entityB == relationship.entityB && + r.roleA == relationship.roleA + ); + if (exists == -1) { + relationships.push(relationship); + } + } else if (targetIsPrimary && sourceIsPrimary) { + // add a new many to many table + let sourceId = edge.source.value; + const sourceAttr = getDbLabel( + sourceId, + columnQuantifiers + ); + sourceAttr.attributeKeyType = "PK"; + sourceId = sourceAttr.attributeName; + const sourceEntity = RemoveNameQuantifiers( + edge.source.parent.value + ); + let targetId = edge.target.value; + const targetAttr = getDbLabel( + targetId, + columnQuantifiers + ); + targetAttr.attributeKeyType = "PK"; + targetId = targetAttr.attributeName; + const targetEntity = RemoveNameQuantifiers( + edge.target.parent.value + ); + const compositeEntity = { + name: + RemoveNameQuantifiers(sourceEntity) + + "_" + + RemoveNameQuantifiers(targetEntity), + attributes: [sourceAttr, targetAttr], + }; + // add composite entity + if (entities[compositeEntity.name]) { + // DON'T add duplicate composite tables + } else { + entities[compositeEntity.name] = compositeEntity; + } + // entityA primary + // entityB foreign + const relationship = { + entityA: sourceEntity, + entityB: compositeEntity.name, + // based off of styles? + relSpec: { + cardA: "ZERO_OR_MORE", + cardB: "ONLY_ONE", + relType: "IDENTIFYING", + }, + roleA: `[${sourceEntity}.${sourceId}] to [${compositeEntity.name}.${sourceId}]`, + }; + // check that is doesn't already exist + let exists = relationships.findIndex( + (r) => + r.entityA == relationship.entityA && + r.entityB == relationship.entityB && + r.roleA == relationship.roleA + ); + if (exists == -1) { + relationships.push(relationship); + } + const relationship2 = { + entityA: targetEntity, + entityB: compositeEntity.name, + // based off of styles? + relSpec: { + cardA: "ZERO_OR_MORE", + cardB: "ONLY_ONE", + relType: "IDENTIFYING", + }, + roleA: `[${targetEntity}.${targetId}] to [${compositeEntity.name}.${targetId}]`, + }; + // check that is doesn't already exist + exists = relationships.findIndex( + (r) => + r.entityA == relationship2.entityA && + r.entityB == relationship2.entityB && + r.roleA == relationship2.roleA + ); + if (exists == -1) { + relationships.push(relationship2); + } } - entities[entity.name + count.toString()] = entity; - } else { - entities[entity.name] = entity; + } } + } } - + } + } + } + // allows for duplicates if another table has the same name + if (entities[entity.name]) { + let count = 2; + while (entities[entity.name + count.toString()]) { + count++; } + entities[entity.name + count.toString()] = entity; + } else { + entities[entity.name] = entity; + } } + } } + } - const db = GenerateDatabaseModel(entities, relationships); + const db = GenerateDatabaseModel(entities, relationships); - return db; + return db; } -export function GenerateDatabaseModel(entities: Record, relationships: DbRelationshipDefinition[]) { - class DatabaseModel{ - constructor(entities: Record, relationships: DbRelationshipDefinition[]){ - this.entities = entities; - this.relationships = relationships; - } - - private entities: Record; - - private relationships: DbRelationshipDefinition[]; +export function GenerateDatabaseModel( + entities: Record, + relationships: DbRelationshipDefinition[] +) { + class DatabaseModel { + constructor( + entities: Record, + relationships: DbRelationshipDefinition[] + ) { + this.entities = entities; + this.relationships = relationships; + } - getEntities(){ - return this.entities; - } + private entities: Record; - getRelationships(){ - return this.relationships; - } + private relationships: DbRelationshipDefinition[]; + + getEntities() { + return this.entities; + } + + getRelationships() { + return this.relationships; } + } - const db:DatabaseModelResult = new DatabaseModel(entities, relationships); + const db: DatabaseModelResult = new DatabaseModel(entities, relationships); - return db; + return db; } export function generateComment(description?: string, formatValue?: string) { - let result = ""; - if (description) { - result += `${description}`; - } - if (formatValue) { - result += ` @format ${formatValue}`; + let result = ""; + if (description) { + result += `${description}`; + } + if (formatValue) { + result += ` ${formatKeyword} ${formatValue}`; + } + if (result) { + result = result.trim(); + result = `${commentColumnQuantifiers.Start} ${result} ${commentColumnQuantifiers.End}`; + } + return result; +} + +export function CreateTableUI( + ui: DrawioUI, + wndFromInput: mxWindow, + tableList: TableModel[], + cells: mxCell[], + rowCell: mxCell | null, + tableCell: mxCell | null, + foreignKeyList: ForeignKeyModel[], + dx: number, + type: + | "mysql" + | "sqlite" + | "postgres" + | "sqlserver" + | "ts" + | "openapi" + | undefined +) { + tableList.forEach(function (tableModel) { + //Define table size width + const maxNameLenght = 100 + tableModel.Name.length; + + //Create Table + tableCell = new mxCell( + tableModel.Name, + new mxGeometry(dx, 0, maxNameLenght, 26), + "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;" + ); + tableCell.vertex = true; + + //Resize row + if (rowCell) { + const size = ui.editor.graph.getPreferredSizeForCell(rowCell); + if (size !== null) { + tableCell.geometry.width = size.width + maxNameLenght; + } } - if(result){ - result = result.trim(); - result = `${commentColumnQuantifiers.Start} ${result} ${commentColumnQuantifiers.End}`; + + //Add Table to cells + cells.push(tableCell); + + //Add properties + tableModel.Properties.forEach(function (propertyModel) { + //Add row + const addRowResult = AddRow( + ui, + propertyModel, + tableModel.Name, + rowCell, + tableCell + ); + if (addRowResult) { + rowCell = addRowResult.rowCell; + tableCell = addRowResult.tableCell; + } + }); + + //Close table + dx += tableCell.geometry.width + 40; + tableCell = null; + }); + + if (cells.length > 0) { + const graph = ui.editor.graph; + const view = graph.view; + const bds = graph.getGraphBounds(); + + // Computes unscaled, untranslated graph bounds + const x = Math.ceil( + Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize + ); + const y = Math.ceil( + Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + + 4 * graph.gridSize + ); + + graph.setSelectionCells(graph.importCells(cells, x, y)); + // add foreign key edges + const model = graph.getModel(); + const columnQuantifiers = GetColumnQuantifiers(type); + // const pt = graph.getFreeInsertPoint(); + foreignKeyList.forEach(function (fk) { + if ( + fk.IsDestination && + fk.PrimaryKeyName && + fk.ReferencesPropertyName && + fk.PrimaryKeyTableName && + fk.ReferencesTableName + ) { + const insertEdge = mxUtils.bind( + this, + function (targetCell, sourceCell, edge) { + const label = ""; + const edgeStyle = + "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; + const edgeCell = graph.insertEdge( + null, + null, + label || "", + edge.invert ? sourceCell : targetCell, + edge.invert ? targetCell : sourceCell, + edgeStyle + ); + } + ); + const edge = { + invert: true, + }; + let targetCell = null; + let sourceCell = null; + // locate edge source and target cells + for (const key in model.cells) { + if (targetCell && sourceCell) break; + if (Object.hasOwnProperty.call(model.cells, key)) { + const mxcell = model.cells[key]; + if (mxcell.style && mxcell.style.trim().startsWith("swimlane;")) { + const entity = { + name: mxcell.value, + attributes: [], + }; + const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; + const isForeignTable = entity.name == fk.ReferencesTableName; + if (isPrimaryTable || isForeignTable) { + for (let c = 0; c < mxcell.children.length; c++) { + if (targetCell && sourceCell) break; + const col = mxcell.children[c]; + if (col.mxObjectId.indexOf("mxCell") !== -1) { + if ( + col.style && + col.style.trim().startsWith("shape=partialRectangle") + ) { + const attribute = getDbLabel( + col.value, + columnQuantifiers + ); + if ( + isPrimaryTable && + dbTypeEnds(attribute.attributeName) == fk.PrimaryKeyName + ) { + targetCell = col; + // allow recursion + } + if ( + isForeignTable && + dbTypeEnds(attribute.attributeName) == + fk.ReferencesPropertyName + ) { + sourceCell = col; + } + if(targetCell && sourceCell) break; + } + } + } + } + } + } + } + if (targetCell && sourceCell) insertEdge(targetCell, sourceCell, edge); + } + }); + graph.scrollCellToVisible(graph.getSelectionCell()); + } + + wndFromInput.setVisible(false); + return { + cells, + rowCell, + tableCell, + dx, + }; +} + +function AddRow( + ui: DrawioUI, + propertyModel: PropertyModel, + tableName: string, + rowCell: mxCell | null, + tableCell: mxCell | null +) { + const cellName = + propertyModel.Name + + (propertyModel.ColumnProperties + ? " " + propertyModel.ColumnProperties + : ""); + + rowCell = new mxCell( + cellName, + new mxGeometry(0, 0, 90, 26), + "shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;" + ); + rowCell.vertex = true; + + const columnType = + propertyModel.IsPrimaryKey && propertyModel.IsForeignKey + ? "PK | FK" + : propertyModel.IsPrimaryKey + ? "PK" + : propertyModel.IsForeignKey + ? "FK" + : ""; + + const left = sb.cloneCell(rowCell, columnType); + left.connectable = false; + left.style = + "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;"; + left.geometry.width = 54; + left.geometry.height = 26; + rowCell.insert(left); + + const size = ui.editor.graph.getPreferredSizeForCell(rowCell); + + if (tableCell) { + if (size !== null && tableCell.geometry.width < size.width + 10) { + tableCell.geometry.width = size.width + 10; } - return result; + + tableCell.insert(rowCell); + tableCell.geometry.height += 26; + } + return { + rowCell, + tableCell, + }; } From 2a77a90d6e1498911bcc6294ce9b81738f4d694d Mon Sep 17 00:00:00 2001 From: lastlink Date: Sat, 6 Jul 2024 11:25:48 -0400 Subject: [PATCH 3/8] fix additional properties type check --- src/utils/nosqlUtils.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/utils/nosqlUtils.ts b/src/utils/nosqlUtils.ts index 42ec77f..7c04950 100644 --- a/src/utils/nosqlUtils.ts +++ b/src/utils/nosqlUtils.ts @@ -275,18 +275,17 @@ export function ConvertOpenApiToDatabaseModel( Object.prototype.hasOwnProperty.call(schema.properties, propertyKey) ) { const property = schema.properties[propertyKey]; - // TODO: if note object or array use ref - + // if note object or array use ref let refName: string | null | undefined = null; if (property.$ref) { refName = property.$ref.split("/").pop(); } else if (property.items && typeof property.items == objectKeyword) { refName = (property.items as JSONSchema4).$ref?.split("/").pop(); } else if ( - property.additionalItems && - typeof property.additionalItems == "object" + property.additionalProperties && + typeof property.additionalProperties == "object" ) { - refName = property.additionalItems.$ref?.split("/").pop(); + refName = property.additionalProperties.$ref?.split("/").pop(); } if (refName) { const refSchema: JSONSchema4 | null = schemas[ From e7a6d5b23f6ed78ee7f7ec4ddb2b3f1243d3f3e4 Mon Sep 17 00:00:00 2001 From: lastlink Date: Sat, 6 Jul 2024 13:56:27 -0400 Subject: [PATCH 4/8] improved open api export and import support --- src/utils/constants-nosql.ts | 16 +++- src/utils/constants.ts | 2 - src/utils/nosqlUtils.ts | 144 +++++++++++++++++++++++++++-------- src/utils/sharedUtils.ts | 111 +++++++++++++++++++++++---- 4 files changed, 223 insertions(+), 50 deletions(-) diff --git a/src/utils/constants-nosql.ts b/src/utils/constants-nosql.ts index d429782..43cd000 100644 --- a/src/utils/constants-nosql.ts +++ b/src/utils/constants-nosql.ts @@ -1,4 +1,5 @@ import { pluginVersion } from "./constants"; +import { JSONSchema4TypeName } from "json-schema"; export const defaultReset = `/*\n\tDrawio default value\n\tPlugin: nosql\n\tVersion: ${pluginVersion}\n*/\n\n export interface WeatherForecast { @@ -88,4 +89,17 @@ export const defaultResetOpenApi = ` } } } - `; \ No newline at end of file + `; + +const JSONSchemaTypes:JSONSchema4TypeName[] = [ + "string", + "number", + "integer", + "boolean", + "object", + "array", + "null", + "any" +]; + +export const validJSONSchemaTypes:string[] = JSONSchemaTypes; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c00a0c3..99df90d 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -17,5 +17,3 @@ export const nullableKeyword = "nullable"; export const arrayKeyword = "array"; export const objectKeyword = "object"; - -export const validEnumTypes = ["string", "number", "integer", "boolean"]; \ No newline at end of file diff --git a/src/utils/nosqlUtils.ts b/src/utils/nosqlUtils.ts index 7c04950..e7a97a8 100644 --- a/src/utils/nosqlUtils.ts +++ b/src/utils/nosqlUtils.ts @@ -11,7 +11,6 @@ import { nullableKeyword, objectKeyword, pluginVersion, - validEnumTypes, } from "./constants"; import { JSONSchema4, JSONSchema4TypeName } from "json-schema"; import { @@ -24,6 +23,7 @@ import { GetColumnQuantifiers, getCommentIndexes, getDbLabel, + RemoveNameQuantifiers, } from "./sharedUtils"; import { DatabaseModel, @@ -31,6 +31,7 @@ import { PropertyModel, TableModel, } from "@funktechno/sqlsimpleparser/lib/types"; +import { validJSONSchemaTypes } from "./constants-nosql"; /** * convert db to openapi @@ -58,14 +59,14 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { let schemaKey = key; const entity = entities[key]; let commentIndexes = getCommentIndexes(key); - let description = ""; + let schemaDescription = ""; let formatValue = ""; if (commentIndexes.start > -1 && commentIndexes.end > -1) { let result = schemaKey.toString().trim(); commentIndexes = getCommentIndexes(result); const firstSpaceIndex = commentIndexes.start; const lastSpaceIndex = commentIndexes.end; - schemaKey = result.substring(0, commentIndexes.beforeStart); + schemaKey = result.substring(0, commentIndexes.beforeStart).trim(); result = result.substring(firstSpaceIndex, lastSpaceIndex).trim(); if (result.indexOf(formatKeyword) !== -1) { const formatIndex = result.indexOf(formatKeyword); @@ -75,7 +76,7 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { result = result.substring(0, formatIndex); } if (result) { - description = result; + schemaDescription = result; } } if (schema[schemaKey]) { @@ -87,8 +88,8 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { additionalProperties: false, properties: {}, }; - if (description) { - schema[schemaKey].description = description.trim(); + if (schemaDescription) { + schema[schemaKey].description = schemaDescription.trim(); } if (formatValue) { schema[schemaKey].format = formatValue.trim(); @@ -108,7 +109,7 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { const splitPropName = propName.split(" "); if ( splitPropName.length == 2 && - validEnumTypes.indexOf(splitPropName[0]) !== -1 && + validJSONSchemaTypes.indexOf(splitPropName[0]) !== -1 && splitPropName[1] == enumKeyword ) { isEnum = true; @@ -116,18 +117,18 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { } } // extract desciption /** asdf */ - let description = ""; + let propertyDescription = ""; let formatValue = ""; let enumValues: any[] | null = null; if ( attribute.attributeType?.includes(commentColumnQuantifiers.Start) && attribute.attributeType?.includes(commentColumnQuantifiers.End) ) { - let result = attribute.attributeType; - const commentIndexes = getCommentIndexes(result); + let attributeTypeResult = attribute.attributeType; + const commentIndexes = getCommentIndexes(attributeTypeResult); const firstSpaceIndex = commentIndexes.start; const lastSpaceIndex = commentIndexes.end; - const enumRaw = result + const enumRaw = attributeTypeResult .substring(0, commentIndexes.beforeStart) .trim(); if (enumRaw) { @@ -141,16 +142,16 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { ); } } - result = result.substring(firstSpaceIndex, lastSpaceIndex); - if (result.indexOf(formatKeyword) !== -1) { - const formatIndex = result.indexOf(formatKeyword); - formatValue = result + attributeTypeResult = attributeTypeResult.substring(firstSpaceIndex, lastSpaceIndex); + if (attributeTypeResult.indexOf(formatKeyword) !== -1) { + const formatIndex = attributeTypeResult.indexOf(formatKeyword); + formatValue = attributeTypeResult .substring(formatIndex + formatKeyword.length) .trim(); - result = result.substring(0, formatIndex); + attributeTypeResult = attributeTypeResult.substring(0, formatIndex); } - if (result) { - description = result; + if (attributeTypeResult.trim()) { + propertyDescription = attributeTypeResult.trim(); } // decription = attribute.attributeType?.replace("/**", "").replace("*/", ""); @@ -160,24 +161,92 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { if (enumValues) { schema[schemaKey].enum = enumValues; } - if (description) { - schema[schemaKey].description = description.trim(); + if (propertyDescription.trim()) { + schema[schemaKey].description = propertyDescription.trim(); } - if (formatValue) { + if (formatValue.trim()) { schema[schemaKey].format = formatValue.trim(); } schema[schemaKey].type = type; } else { + // check if type is jsonschema type + let $ref = null; + let removeType = false; + let items: JSONSchema4 | null = null; + let additionalProperties: JSONSchema4 | null = null; + if (validJSONSchemaTypes.indexOf(type) === -1) { + if (type.indexOf("[]") != -1) { + const itemsType = type.replace("[]", "") as JSONSchema4TypeName; + if (validJSONSchemaTypes.indexOf(itemsType) != -1) { + items = { + type: itemsType, + }; + type = "array"; + } + } + + if (validJSONSchemaTypes.indexOf(type) != -1) { + // + } else { + // else { + removeType = true; + $ref = `#/components/schemas/${RemoveNameQuantifiers(type)}`; + } + } + if(["array", "object"].indexOf(type) !== -1) { + const relationships = db.getRelationships().filter(x=> x.entityA == key); + const roleLookup = `[${key}.${propName}]`; + // FIND MATCH + const rel = relationships.find(x => x.roleA.indexOf(roleLookup) != -1); + if(rel) { + const commentFKIndexes = getCommentIndexes(rel.entityB); + const entityBName = rel.entityB.substring(0, commentFKIndexes.beforeStart).trim(); + $ref = `#/components/schemas/${entityBName}`; + } + if($ref) { + // if array additionalProperties.$ref + if(type == "array") { + items = { + $ref: $ref + }; + } + // if object items.$ref + if(type == "object") { + additionalProperties = { + $ref: $ref + }; + } + } + } + const property: JSONSchema4 = { title: `${schemaKey}.${propName}`, - nullable: attribute.attributeType?.includes("nullable") ?? false, type: type, }; - if (description) { - property.description = description.trim(); + if(additionalProperties) { + property.additionalProperties = additionalProperties; + } + if (items) { + property.items = items; } - if (formatValue) { - property.format = formatValue.trim(); + if (attribute.attributeType?.includes("nullable")) { + property.nullable = true; + } + if ($ref && !additionalProperties?.$ref && !items?.$ref) { + property["$ref"] = $ref; + } + if (removeType) { + delete property.type; + } + // $ref properties don't have descriptions + if (propertyDescription.trim() && !$ref) { + // TODO: pull from proper location + property.description = propertyDescription.trim(); + } + if (formatValue.trim()) { + if (property.items) { + (property.items as JSONSchema4).format = formatValue.trim(); + } else property.format = formatValue.trim(); } schema[schemaKey].properties[attribute.attributeName!] = property; } @@ -191,7 +260,13 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { return result; } -// TODO: may need to make recursive for when schema property items is array +/** + * used in uml generation + * @param tableName + * @param propertyName + * @param property + * @returns + */ export function GeneratePropertyModel( tableName: string, propertyName: string, @@ -200,9 +275,12 @@ export function GeneratePropertyModel( let columnProperties = (property.type ?? objectKeyword).toString(); if (columnProperties === arrayKeyword) { if (property.items && typeof property.items === objectKeyword) { - if ((property.items as JSONSchema4).format) - columnProperties = `${(property.items as JSONSchema4).format}[]`; - else if ((property.items as JSONSchema4).type) + if ((property.items as JSONSchema4).format && !property.format) { + property.format = (property.items as JSONSchema4).format; + // columnProperties = `${(property.items as JSONSchema4).format}[]`; + } + // else + if ((property.items as JSONSchema4).type) columnProperties = `${(property.items as JSONSchema4).type}[]`; } } @@ -225,7 +303,11 @@ export function GeneratePropertyModel( }; return result; } - +/** + * convert openapi schema to database model + * @param schemas + * @returns + */ export function ConvertOpenApiToDatabaseModel( schemas: Record ): DatabaseModel { diff --git a/src/utils/sharedUtils.ts b/src/utils/sharedUtils.ts index b17c610..6caded3 100644 --- a/src/utils/sharedUtils.ts +++ b/src/utils/sharedUtils.ts @@ -30,8 +30,8 @@ export function GetColumnQuantifiers( | undefined ): ColumnQuantifiers { const chars = { - Start: "\"", - End: "\"", + Start: '"', + End: '"', }; if (type && ["mysql", "ts", "openapi"].includes(type)) { chars.Start = "`"; @@ -55,7 +55,11 @@ export function removeHtml(label: string) { tempDiv.remove(); return text; } - +/** + * add db ends + * @param label + * @returns + */ export function dbTypeEnds(label: string): string { const char1 = "`"; const char2 = "`"; @@ -65,7 +69,11 @@ export function dbTypeEnds(label: string): string { // } return `${char1}${label}${char2}`; } - +/** + * remove name quantifiers + * @param name + * @returns + */ export function RemoveNameQuantifiers(name: string) { return name.replace(/\[|\]|\(|\"|\'|\`/g, "").trim(); } @@ -201,7 +209,7 @@ export function getMermaidDiagramDb( }; const comment = generateComment(description, formatValue); if (comment) { - entity.name += comment; + entity.name += ` ${comment}`; } // const comment = for (let c = 0; c < mxcell.children.length; c++) { @@ -302,18 +310,59 @@ export function getMermaidDiagramDb( columnQuantifiers ); sourceId = sourceAttr.attributeName; - const sourceEntity = RemoveNameQuantifiers( - edge.source.parent.value - ); + let sourceEntity = edge.source.parent.value; + // extract comments + let commentsIndexes = getCommentIndexes(sourceEntity); + if ( + commentsIndexes.start != -1 && + commentsIndexes.end != -1 + ) { + const sourceComment = sourceEntity + .substring( + commentsIndexes.start, + commentsIndexes.end + ) + .trim(); + sourceEntity = sourceEntity + .substring(0, commentsIndexes.beforeStart) + .trim(); + sourceEntity = `${RemoveNameQuantifiers( + sourceEntity + )} ${generateComment(sourceComment)}`; + } else { + sourceEntity = RemoveNameQuantifiers(sourceEntity); + } let targetId = edge.target.value; const targetAttr = getDbLabel( targetId, columnQuantifiers ); targetId = targetAttr.attributeName; - const targetEntity = RemoveNameQuantifiers( - edge.target.parent.value - ); + + let targetEntity = edge.target.parent.value; + commentsIndexes = getCommentIndexes(targetEntity); + if ( + commentsIndexes.start != -1 && + commentsIndexes.end != -1 + ) { + const targetComment = targetEntity + .substring( + commentsIndexes.start, + commentsIndexes.end + ) + .trim(); + targetEntity = targetEntity + .substring(0, commentsIndexes.beforeStart) + .trim(); + targetEntity = `${RemoveNameQuantifiers( + targetEntity + )} ${generateComment(targetComment)}`; + } else { + targetEntity = RemoveNameQuantifiers(targetEntity); + } + // const targetEntity = RemoveNameQuantifiers( + // edge.target.parent.value + // ); // entityA primary // entityB foreign const relationship: DbRelationshipDefinition = { @@ -449,7 +498,12 @@ export function getMermaidDiagramDb( return db; } - +/** + * genearte a database model + * @param entities + * @param relationships + * @returns + */ export function GenerateDatabaseModel( entities: Record, relationships: DbRelationshipDefinition[] @@ -480,7 +534,12 @@ export function GenerateDatabaseModel( return db; } - +/** + * generate a comment using description and format + * @param description + * @param formatValue + * @returns + */ export function generateComment(description?: string, formatValue?: string) { let result = ""; if (description) { @@ -495,7 +554,19 @@ export function generateComment(description?: string, formatValue?: string) { } return result; } - +/** + * create uml tables from db models + * @param ui + * @param wndFromInput + * @param tableList + * @param cells + * @param rowCell + * @param tableCell + * @param foreignKeyList + * @param dx + * @param type + * @returns + */ export function CreateTableUI( ui: DrawioUI, wndFromInput: mxWindow, @@ -645,7 +716,7 @@ export function CreateTableUI( ) { sourceCell = col; } - if(targetCell && sourceCell) break; + if (targetCell && sourceCell) break; } } } @@ -667,7 +738,15 @@ export function CreateTableUI( dx, }; } - +/** + * add row to uml table + * @param ui + * @param propertyModel + * @param tableName + * @param rowCell + * @param tableCell + * @returns + */ function AddRow( ui: DrawioUI, propertyModel: PropertyModel, From d92ac14ae3ab0d649330f0c078b23ee36ad101aa Mon Sep 17 00:00:00 2001 From: lastlink Date: Sat, 6 Jul 2024 13:58:55 -0400 Subject: [PATCH 5/8] 0.0.6 build --- dist/nosql-ts.js | 957 ++++++++++++++++++++++++++++--------------- dist/nosql-ts.min.js | 14 +- dist/nosql.js | 938 ++++++++++++++++++++++++++++-------------- dist/nosql.min.js | 28 +- dist/sql.js | 482 ++++++++++++++-------- package.json | 2 +- 6 files changed, 1614 insertions(+), 807 deletions(-) diff --git a/dist/nosql-ts.js b/dist/nosql-ts.js index e93bbe4..03ffcd4 100644 --- a/dist/nosql-ts.js +++ b/dist/nosql-ts.js @@ -200853,9 +200853,10 @@ const core_types_ts_1 = require("core-types-ts"); const sharedUtils_1 = require("./utils/sharedUtils"); const constants_1 = require("./utils/constants"); const nosqlUtils_1 = require("./utils/nosqlUtils"); +const constants_nosql_1 = require("./utils/constants-nosql"); /** * SQL Tools Plugin for importing and exporting typescript interfaces. - * Version: 0.0.5 + * Version: 0.0.6 */ Draw.loadPlugin(function (ui) { //Create Base div @@ -200949,95 +200950,7 @@ Draw.loadPlugin(function (ui) { const sqlInputFromNOSQL = document.createElement("textarea"); sqlInputFromNOSQL.style.height = "200px"; sqlInputFromNOSQL.style.width = "100%"; - const defaultReset = `/*\n\tDrawio default value\n\tPlugin: nosql\n\tVersion: ${constants_1.pluginVersion}\n*/\n\n -export interface WeatherForecast { - /** @format date-time */ - date?: string; - /** @format int32 */ - temperatureC?: number; - /** @format int32 */ - temperatureF?: number; - summary?: string | null; - nestedProp: string[]; - children?: Child[]; -} - -export interface Child { - name: string -} - `; - const defaultResetOpenApi = ` -{ - "openapi": "3.0.0", - "info": { - "title": "nosql plugin sample", - "version": "${constants_1.pluginVersion}", - "x-comment": "Generated by core-types-json-schema (https://github.com/grantila/core-types-json-schema)" - }, - "paths": {}, - "components": { - "schemas": { - "WeatherForecast": { - "properties": { - "date": { - "title": "WeatherForecast.date", - "description": "@format date-time", - "type": "string" - }, - "temperatureC": { - "title": "WeatherForecast.temperatureC", - "description": "@format int32", - "type": "number" - }, - "temperatureF": { - "title": "WeatherForecast.temperatureF", - "description": "@format int32", - "type": "number" - }, - "summary": { - "title": "WeatherForecast.summary", - "nullable": true, - "type": "string" - }, - "nestedProp": { - "items": { - "title": "WeatherForecast.nestedProp.[]", - "type": "string" - }, - "title": "WeatherForecast.nestedProp", - "type": "array" - }, - "child": { - "$ref": "#/components/schemas/Child", - "title": "WeatherForecast.child" - } - }, - "required": [ - "nestedProp" - ], - "additionalProperties": false, - "title": "WeatherForecast", - "type": "object" - }, - "Child": { - "properties": { - "name": { - "title": "Child.name", - "type": "string" - } - }, - "required": [ - "name" - ], - "additionalProperties": false, - "title": "Child", - "type": "object" - } - } - } -} - `; - sqlInputFromNOSQL.value = defaultReset; + sqlInputFromNOSQL.value = constants_nosql_1.defaultReset; mxUtils.br(divFromNOSQL); divFromNOSQL.appendChild(sqlInputFromNOSQL); // const graph = ui.editor.graph; @@ -201048,27 +200961,6 @@ export interface Child { wndFromNOSQL.setMaximizable(false); wndFromNOSQL.setResizable(false); wndFromNOSQL.setClosable(true); - function AddRow(propertyModel, tableName) { - const cellName = propertyModel.Name + (propertyModel.ColumnProperties ? " " + propertyModel.ColumnProperties : ""); - rowCell = new mxCell(cellName, new mxGeometry(0, 0, 90, 26), "shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;"); - rowCell.vertex = true; - const columnType = propertyModel.IsPrimaryKey && propertyModel.IsForeignKey ? "PK | FK" : propertyModel.IsPrimaryKey ? "PK" : propertyModel.IsForeignKey ? "FK" : ""; - const left = sb.cloneCell(rowCell, columnType); - left.connectable = false; - left.style = "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;"; - left.geometry.width = 54; - left.geometry.height = 26; - rowCell.insert(left); - const size = ui.editor.graph.getPreferredSizeForCell(rowCell); - if (tableCell) { - if (size !== null && tableCell.geometry.width < size.width + 10) { - tableCell.geometry.width = size.width + 10; - } - tableCell.insert(rowCell); - tableCell.geometry.height += 26; - } - } - ; function parseFromInput(text, type) { var _a; // reset values @@ -201103,7 +200995,13 @@ export interface Child { primaryKeyList = models.PrimaryKeyList; tableList = models.TableList; exportedTables = tableList.length; - CreateTableUI(type); + const createTableResult = (0, sharedUtils_1.CreateTableUI)(ui, wndFromNOSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type); + if (createTableResult) { + cells = createTableResult.cells; + dx = createTableResult.dx; + tableCell = createTableResult.tableCell; + rowCell = createTableResult.rowCell; + } } } catch (error) { @@ -201112,112 +201010,16 @@ export interface Child { } } ; - function CreateTableUI(type) { - tableList.forEach(function (tableModel) { - //Define table size width - const maxNameLenght = 100 + tableModel.Name.length; - //Create Table - tableCell = new mxCell(tableModel.Name, new mxGeometry(dx, 0, maxNameLenght, 26), "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;"); - tableCell.vertex = true; - //Resize row - if (rowCell) { - const size = ui.editor.graph.getPreferredSizeForCell(rowCell); - if (size !== null) { - tableCell.geometry.width = size.width + maxNameLenght; - } - } - //Add Table to cells - cells.push(tableCell); - //Add properties - tableModel.Properties.forEach(function (propertyModel) { - //Add row - AddRow(propertyModel, tableModel.Name); - }); - //Close table - dx += tableCell.geometry.width + 40; - tableCell = null; - }); - if (cells.length > 0) { - const graph = ui.editor.graph; - const view = graph.view; - const bds = graph.getGraphBounds(); - // Computes unscaled, untranslated graph bounds - const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize); - const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + 4 * graph.gridSize); - graph.setSelectionCells(graph.importCells(cells, x, y)); - // add foreign key edges - const model = graph.getModel(); - const columnQuantifiers = (0, sharedUtils_1.GetColumnQuantifiers)(type); - // const pt = graph.getFreeInsertPoint(); - foreignKeyList.forEach(function (fk) { - if (fk.IsDestination && fk.PrimaryKeyName && fk.ReferencesPropertyName && - fk.PrimaryKeyTableName && fk.ReferencesTableName) { - const insertEdge = mxUtils.bind(this, function (targetCell, sourceCell, edge) { - const label = ""; - const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; - const edgeCell = graph.insertEdge(null, null, label || "", (edge.invert) ? - sourceCell : targetCell, (edge.invert) ? targetCell : sourceCell, edgeStyle); - }); - const edge = { - invert: true - }; - let targetCell = null; - let sourceCell = null; - // locate edge source and target cells - for (const key in model.cells) { - if (targetCell && sourceCell) - break; - if (Object.hasOwnProperty.call(model.cells, key)) { - const mxcell = model.cells[key]; - if (mxcell.style && mxcell.style.trim().startsWith("swimlane;")) { - const entity = { - name: mxcell.value, - attributes: [] - }; - const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; - const isForeignTable = entity.name == fk.ReferencesTableName; - if (isPrimaryTable || isForeignTable) { - for (let c = 0; c < mxcell.children.length; c++) { - if (targetCell && sourceCell) - break; - const col = mxcell.children[c]; - if (col.mxObjectId.indexOf("mxCell") !== -1) { - if (col.style && col.style.trim().startsWith("shape=partialRectangle")) { - const attribute = (0, sharedUtils_1.getDbLabel)(col.value, columnQuantifiers); - if (isPrimaryTable && (0, sharedUtils_1.dbTypeEnds)(attribute.attributeName) == fk.PrimaryKeyName) { - targetCell = col; - break; - } - else if (isForeignTable && (0, sharedUtils_1.dbTypeEnds)(attribute.attributeName) == fk.ReferencesPropertyName) { - sourceCell = col; - break; - } - } - } - } - } - } - } - } - if (targetCell && sourceCell) - insertEdge(targetCell, sourceCell, edge); - } - }); - graph.scrollCellToVisible(graph.getSelectionCell()); - } - wndFromNOSQL.setVisible(false); - } - ; mxUtils.br(divFromNOSQL); const resetBtnFromNOSQL = mxUtils.button(mxResources.get("Reset TS"), function () { - sqlInputFromNOSQL.value = defaultReset; + sqlInputFromNOSQL.value = constants_nosql_1.defaultReset; }); resetBtnFromNOSQL.style.marginTop = "8px"; resetBtnFromNOSQL.style.marginRight = "4px"; resetBtnFromNOSQL.style.padding = "4px"; divFromNOSQL.appendChild(resetBtnFromNOSQL); const resetOpenAPIBtnFromNOSQL = mxUtils.button("Reset OpenAPI", function () { - sqlInputFromNOSQL.value = defaultResetOpenApi; + sqlInputFromNOSQL.value = constants_nosql_1.defaultResetOpenApi; }); resetOpenAPIBtnFromNOSQL.style.marginTop = "8px"; resetOpenAPIBtnFromNOSQL.style.marginRight = "4px"; @@ -201275,21 +201077,128 @@ export interface Child { } }); -},{"./utils/constants":49,"./utils/nosqlUtils":50,"./utils/sharedUtils":51,"core-types-json-schema":2,"core-types-ts":25,"core-types-ts/dist/lib/ts-to-core-types":29}],49:[function(require,module,exports){ +},{"./utils/constants":50,"./utils/constants-nosql":49,"./utils/nosqlUtils":51,"./utils/sharedUtils":52,"core-types-json-schema":2,"core-types-ts":25,"core-types-ts/dist/lib/ts-to-core-types":29}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.validEnumTypes = exports.enumKeyword = exports.formatKeyword = exports.commentColumnQuantifiers = exports.pluginVersion = void 0; +exports.validJSONSchemaTypes = exports.defaultResetOpenApi = exports.defaultReset = void 0; +const constants_1 = require("./constants"); +exports.defaultReset = `/*\n\tDrawio default value\n\tPlugin: nosql\n\tVersion: ${constants_1.pluginVersion}\n*/\n\n +export interface WeatherForecast { + /** @format date-time */ + date?: string; + /** @format int32 */ + temperatureC?: number; + /** @format int32 */ + temperatureF?: number; + summary?: string | null; + nestedProp: string[]; + children?: Child[]; +} + +export interface Child { + name: string +} + `; +exports.defaultResetOpenApi = ` +{ + "openapi": "3.0.0", + "info": { + "title": "nosql plugin sample", + "version": "${constants_1.pluginVersion}", + "x-comment": "Generated by core-types-json-schema (https://github.com/grantila/core-types-json-schema)" + }, + "paths": {}, + "components": { + "schemas": { + "WeatherForecast": { + "properties": { + "date": { + "title": "WeatherForecast.date", + "description": "@format date-time", + "type": "string" + }, + "temperatureC": { + "title": "WeatherForecast.temperatureC", + "description": "@format int32", + "type": "number" + }, + "temperatureF": { + "title": "WeatherForecast.temperatureF", + "description": "@format int32", + "type": "number" + }, + "summary": { + "title": "WeatherForecast.summary", + "nullable": true, + "type": "string" + }, + "nestedProp": { + "items": { + "title": "WeatherForecast.nestedProp.[]", + "type": "string" + }, + "title": "WeatherForecast.nestedProp", + "type": "array" + }, + "child": { + "$ref": "#/components/schemas/Child", + "title": "WeatherForecast.child" + } + }, + "required": [ + "nestedProp" + ], + "additionalProperties": false, + "title": "WeatherForecast", + "type": "object" + }, + "Child": { + "properties": { + "name": { + "title": "Child.name", + "type": "string" + } + }, + "required": [ + "name" + ], + "additionalProperties": false, + "title": "Child", + "type": "object" + } + } + } +} + `; +const JSONSchemaTypes = [ + "string", + "number", + "integer", + "boolean", + "object", + "array", + "null", + "any" +]; +exports.validJSONSchemaTypes = JSONSchemaTypes; + +},{"./constants":50}],50:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.objectKeyword = exports.arrayKeyword = exports.nullableKeyword = exports.enumKeyword = exports.formatKeyword = exports.commentColumnQuantifiers = exports.pluginVersion = void 0; // export sql methods -exports.pluginVersion = "0.0.5"; +exports.pluginVersion = "0.0.6"; exports.commentColumnQuantifiers = { Start: "/**", End: "*/", }; exports.formatKeyword = "@format"; exports.enumKeyword = "enum"; -exports.validEnumTypes = ["string", "number", "integer", "boolean"]; +exports.nullableKeyword = "nullable"; +exports.arrayKeyword = "array"; +exports.objectKeyword = "object"; -},{}],50:[function(require,module,exports){ +},{}],51:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dbToOpenApi = dbToOpenApi; @@ -201297,13 +201206,14 @@ exports.GeneratePropertyModel = GeneratePropertyModel; exports.ConvertOpenApiToDatabaseModel = ConvertOpenApiToDatabaseModel; const constants_1 = require("./constants"); const sharedUtils_1 = require("./sharedUtils"); +const constants_nosql_1 = require("./constants-nosql"); /** * convert db to openapi * @param db * @returns */ function dbToOpenApi(db) { - var _a, _b, _c, _d, _e, _f, _g; + var _a, _b, _c, _d, _e, _f; const result = { openapi: "3.0.0", info: { @@ -201324,35 +201234,37 @@ function dbToOpenApi(db) { let schemaKey = key; const entity = entities[key]; let commentIndexes = (0, sharedUtils_1.getCommentIndexes)(key); - let description = ""; + let schemaDescription = ""; let formatValue = ""; if (commentIndexes.start > -1 && commentIndexes.end > -1) { let result = schemaKey.toString().trim(); commentIndexes = (0, sharedUtils_1.getCommentIndexes)(result); const firstSpaceIndex = commentIndexes.start; const lastSpaceIndex = commentIndexes.end; - schemaKey = result.substring(0, commentIndexes.beforeStart); + schemaKey = result.substring(0, commentIndexes.beforeStart).trim(); result = result.substring(firstSpaceIndex, lastSpaceIndex).trim(); if (result.indexOf(constants_1.formatKeyword) !== -1) { const formatIndex = result.indexOf(constants_1.formatKeyword); - formatValue = result.substring(formatIndex + constants_1.formatKeyword.length).trim(); + formatValue = result + .substring(formatIndex + constants_1.formatKeyword.length) + .trim(); result = result.substring(0, formatIndex); } if (result) { - description = result; + schemaDescription = result; } } if (schema[schemaKey]) { continue; } schema[schemaKey] = { - type: "object", + type: constants_1.objectKeyword, title: schemaKey, additionalProperties: false, properties: {}, }; - if (description) { - schema[schemaKey].description = description.trim(); + if (schemaDescription) { + schema[schemaKey].description = schemaDescription.trim(); } if (formatValue) { schema[schemaKey].format = formatValue.trim(); @@ -201371,23 +201283,25 @@ function dbToOpenApi(db) { if (propName.indexOf(constants_1.enumKeyword) !== -1) { const splitPropName = propName.split(" "); if (splitPropName.length == 2 && - constants_1.validEnumTypes.indexOf(splitPropName[0]) !== -1 && + constants_nosql_1.validJSONSchemaTypes.indexOf(splitPropName[0]) !== -1 && splitPropName[1] == constants_1.enumKeyword) { isEnum = true; type = splitPropName[0]; } } // extract desciption /** asdf */ - let description = ""; + let propertyDescription = ""; let formatValue = ""; let enumValues = null; if (((_d = attribute.attributeType) === null || _d === void 0 ? void 0 : _d.includes(constants_1.commentColumnQuantifiers.Start)) && ((_e = attribute.attributeType) === null || _e === void 0 ? void 0 : _e.includes(constants_1.commentColumnQuantifiers.End))) { - let result = attribute.attributeType; - const commentIndexes = (0, sharedUtils_1.getCommentIndexes)(result); + let attributeTypeResult = attribute.attributeType; + const commentIndexes = (0, sharedUtils_1.getCommentIndexes)(attributeTypeResult); const firstSpaceIndex = commentIndexes.start; const lastSpaceIndex = commentIndexes.end; - const enumRaw = result.substring(0, commentIndexes.beforeStart).trim(); + const enumRaw = attributeTypeResult + .substring(0, commentIndexes.beforeStart) + .trim(); if (enumRaw) { try { enumValues = JSON.parse(enumRaw); @@ -201396,16 +201310,16 @@ function dbToOpenApi(db) { console.log(`Error parsing raw enum values: ${enumRaw} Message: ${JSON.stringify(error)}`); } } - result = result.substring(firstSpaceIndex, lastSpaceIndex); - if (result.indexOf(constants_1.formatKeyword) !== -1) { - const formatIndex = result.indexOf(constants_1.formatKeyword); - formatValue = result + attributeTypeResult = attributeTypeResult.substring(firstSpaceIndex, lastSpaceIndex); + if (attributeTypeResult.indexOf(constants_1.formatKeyword) !== -1) { + const formatIndex = attributeTypeResult.indexOf(constants_1.formatKeyword); + formatValue = attributeTypeResult .substring(formatIndex + constants_1.formatKeyword.length) .trim(); - result = result.substring(0, formatIndex); + attributeTypeResult = attributeTypeResult.substring(0, formatIndex); } - if (result) { - description = result; + if (attributeTypeResult.trim()) { + propertyDescription = attributeTypeResult.trim(); } // decription = attribute.attributeType?.replace("/**", "").replace("*/", ""); } @@ -201415,25 +201329,94 @@ function dbToOpenApi(db) { if (enumValues) { schema[schemaKey].enum = enumValues; } - if (description) { - schema[schemaKey].description = description.trim(); + if (propertyDescription.trim()) { + schema[schemaKey].description = propertyDescription.trim(); } - if (formatValue) { + if (formatValue.trim()) { schema[schemaKey].format = formatValue.trim(); } schema[schemaKey].type = type; } else { + // check if type is jsonschema type + let $ref = null; + let removeType = false; + let items = null; + let additionalProperties = null; + if (constants_nosql_1.validJSONSchemaTypes.indexOf(type) === -1) { + if (type.indexOf("[]") != -1) { + const itemsType = type.replace("[]", ""); + if (constants_nosql_1.validJSONSchemaTypes.indexOf(itemsType) != -1) { + items = { + type: itemsType, + }; + type = "array"; + } + } + if (constants_nosql_1.validJSONSchemaTypes.indexOf(type) != -1) { + // + } + else { + // else { + removeType = true; + $ref = `#/components/schemas/${(0, sharedUtils_1.RemoveNameQuantifiers)(type)}`; + } + } + if (["array", "object"].indexOf(type) !== -1) { + const relationships = db.getRelationships().filter(x => x.entityA == key); + const roleLookup = `[${key}.${propName}]`; + // FIND MATCH + const rel = relationships.find(x => x.roleA.indexOf(roleLookup) != -1); + if (rel) { + const commentFKIndexes = (0, sharedUtils_1.getCommentIndexes)(rel.entityB); + const entityBName = rel.entityB.substring(0, commentFKIndexes.beforeStart).trim(); + $ref = `#/components/schemas/${entityBName}`; + } + if ($ref) { + // if array additionalProperties.$ref + if (type == "array") { + items = { + $ref: $ref + }; + } + // if object items.$ref + if (type == "object") { + additionalProperties = { + $ref: $ref + }; + } + } + } const property = { - title: `${key}.${propName}`, - nullable: (_g = (_f = attribute.attributeType) === null || _f === void 0 ? void 0 : _f.includes("nullable")) !== null && _g !== void 0 ? _g : false, + title: `${schemaKey}.${propName}`, type: type, }; - if (description) { - property.description = description.trim(); + if (additionalProperties) { + property.additionalProperties = additionalProperties; + } + if (items) { + property.items = items; + } + if ((_f = attribute.attributeType) === null || _f === void 0 ? void 0 : _f.includes("nullable")) { + property.nullable = true; } - if (formatValue) { - property.format = formatValue.trim(); + if ($ref && !(additionalProperties === null || additionalProperties === void 0 ? void 0 : additionalProperties.$ref) && !(items === null || items === void 0 ? void 0 : items.$ref)) { + property["$ref"] = $ref; + } + if (removeType) { + delete property.type; + } + // $ref properties don't have descriptions + if (propertyDescription.trim() && !$ref) { + // TODO: pull from proper location + property.description = propertyDescription.trim(); + } + if (formatValue.trim()) { + if (property.items) { + property.items.format = formatValue.trim(); + } + else + property.format = formatValue.trim(); } schema[schemaKey].properties[attribute.attributeName] = property; } @@ -201446,15 +201429,32 @@ function dbToOpenApi(db) { result.components.schemas = schema; return result; } -// TODO: may need to make recursive for when schema property items is array +/** + * used in uml generation + * @param tableName + * @param propertyName + * @param property + * @returns + */ function GeneratePropertyModel(tableName, propertyName, property) { var _a; - let columnProperties = ((_a = property.type) !== null && _a !== void 0 ? _a : "object").toString(); + let columnProperties = ((_a = property.type) !== null && _a !== void 0 ? _a : constants_1.objectKeyword).toString(); + if (columnProperties === constants_1.arrayKeyword) { + if (property.items && typeof property.items === constants_1.objectKeyword) { + if (property.items.format && !property.format) { + property.format = property.items.format; + // columnProperties = `${(property.items as JSONSchema4).format}[]`; + } + // else + if (property.items.type) + columnProperties = `${property.items.type}[]`; + } + } if (property.enum) { columnProperties = `${JSON.stringify(property.enum)}`; } else if (property.nullable) { - columnProperties += " nullable"; + columnProperties += ` ${constants_1.nullableKeyword}`; } const description = (0, sharedUtils_1.generateComment)(property.description, property.format); if (description) { @@ -201470,17 +201470,24 @@ function GeneratePropertyModel(tableName, propertyName, property) { }; return result; } +/** + * convert openapi schema to database model + * @param schemas + * @returns + */ function ConvertOpenApiToDatabaseModel(schemas) { - var _a, _b, _c; + var _a, _b, _c, _d, _e, _f; const models = { Dialect: "nosql", TableList: [], PrimaryKeyList: [], ForeignKeyList: [], }; + const tableDict = {}; for (const key in schemas) { if (Object.prototype.hasOwnProperty.call(schemas, key)) { const schema = schemas[key]; + const originalKey = (0, sharedUtils_1.dbTypeEnds)(key); const tableModel = { Name: (0, sharedUtils_1.dbTypeEnds)(key), Properties: [], @@ -201488,7 +201495,7 @@ function ConvertOpenApiToDatabaseModel(schemas) { if (schema.enum) { const enumList = schema.enum; // serialize to string enum [values] - const propertyKey = `${schema.type} enum`; + const propertyKey = `${schema.type} ${constants_1.enumKeyword}`; const property = { enum: enumList, }; @@ -201511,56 +201518,93 @@ function ConvertOpenApiToDatabaseModel(schemas) { for (const propertyKey in schema.properties) { if (Object.prototype.hasOwnProperty.call(schema.properties, propertyKey)) { const property = schema.properties[propertyKey]; - const propertyModel = GeneratePropertyModel(key, propertyKey, property); - if (propertyModel.ColumnProperties.includes("object") || - propertyModel.ColumnProperties.includes("array")) { - let refName = null; - if (property.$ref) { - refName = property.$ref.split("/").pop(); - } - else if (property.items && typeof property.items == "object") { - refName = (_a = property.items.$ref) === null || _a === void 0 ? void 0 : _a.split("/").pop(); + // if note object or array use ref + let refName = null; + if (property.$ref) { + refName = property.$ref.split("/").pop(); + } + else if (property.items && typeof property.items == constants_1.objectKeyword) { + refName = (_a = property.items.$ref) === null || _a === void 0 ? void 0 : _a.split("/").pop(); + } + else if (property.additionalProperties && + typeof property.additionalProperties == "object") { + refName = (_b = property.additionalProperties.$ref) === null || _b === void 0 ? void 0 : _b.split("/").pop(); + } + if (refName) { + const refSchema = schemas[refName]; + if (refSchema && !refSchema.enum) { + const comment = (0, sharedUtils_1.generateComment)(refSchema.description, refSchema.format); + if (comment) { + refName = `${(0, sharedUtils_1.dbTypeEnds)(refName)} ${comment}`; + } + else { + refName = (0, sharedUtils_1.dbTypeEnds)(refName); + } } - if (refName) { - const primaryKeyModel = { - PrimaryKeyTableName: (0, sharedUtils_1.dbTypeEnds)(key), - ReferencesTableName: (0, sharedUtils_1.dbTypeEnds)(refName), - PrimaryKeyName: (0, sharedUtils_1.dbTypeEnds)(propertyKey), - // should just point to first property in uml table - ReferencesPropertyName: "", - IsDestination: false, - }; - const foreignKeyModel = { - ReferencesTableName: (0, sharedUtils_1.dbTypeEnds)(key), - PrimaryKeyTableName: (0, sharedUtils_1.dbTypeEnds)(refName), - ReferencesPropertyName: (0, sharedUtils_1.dbTypeEnds)(propertyKey), - // should just point to first property in uml table - PrimaryKeyName: "", - IsDestination: true, - }; - models.ForeignKeyList.push(foreignKeyModel); - models.ForeignKeyList.push(primaryKeyModel); - propertyModel.IsForeignKey = true; + else { + refName = (0, sharedUtils_1.dbTypeEnds)(refName); } } + if (refName && !property.type) { + property.type = refName; + } + const propertyModel = GeneratePropertyModel(tableModel.Name, propertyKey, property); + // if ( + // propertyModel.ColumnProperties.includes(objectKeyword) || + // propertyModel.ColumnProperties.includes(arrayKeyword) + // ) { + if (refName) { + const primaryKeyModel = { + PrimaryKeyTableName: tableModel.Name, + ReferencesTableName: refName, + PrimaryKeyName: (0, sharedUtils_1.dbTypeEnds)(propertyKey), + // should just point to first property in uml table + ReferencesPropertyName: "", + IsDestination: false, + }; + const foreignKeyModel = { + ReferencesTableName: tableModel.Name, + PrimaryKeyTableName: refName, + ReferencesPropertyName: (0, sharedUtils_1.dbTypeEnds)(propertyKey), + // should just point to first property in uml table + PrimaryKeyName: "", + IsDestination: true, + }; + models.ForeignKeyList.push(foreignKeyModel); + models.ForeignKeyList.push(primaryKeyModel); + propertyModel.IsForeignKey = true; + } + // } tableModel.Properties.push(propertyModel); } } models.TableList.push(tableModel); + // may no longer be needed + if (!tableDict[originalKey]) { + tableDict[originalKey] = tableModel; + } } } for (let i = 0; i < models.ForeignKeyList.length; i++) { const fk = models.ForeignKeyList[i]; if (!fk.ReferencesPropertyName) { // match to first entry - const property = (_b = models.TableList.find((t) => t.Name == fk.ReferencesTableName)) === null || _b === void 0 ? void 0 : _b.Properties[0]; + let property = (_c = models.TableList.find((t) => t.Name == fk.ReferencesTableName)) === null || _c === void 0 ? void 0 : _c.Properties[0]; + if (!property) { + // attempt a comment lookup + property = (_d = tableDict[fk.ReferencesTableName]) === null || _d === void 0 ? void 0 : _d.Properties[0]; + } if (property) { models.ForeignKeyList[i].ReferencesPropertyName = property.Name; } } if (!fk.PrimaryKeyName) { // match to first entry - const property = (_c = models.TableList.find((t) => t.Name == fk.PrimaryKeyTableName)) === null || _c === void 0 ? void 0 : _c.Properties[0]; + let property = (_e = models.TableList.find((t) => t.Name == fk.PrimaryKeyTableName)) === null || _e === void 0 ? void 0 : _e.Properties[0]; + if (!property) { + // attempt a comment lookup + property = (_f = tableDict[fk.PrimaryKeyTableName]) === null || _f === void 0 ? void 0 : _f.Properties[0]; + } if (property) { models.ForeignKeyList[i].PrimaryKeyName = property.Name; } @@ -201569,7 +201613,7 @@ function ConvertOpenApiToDatabaseModel(schemas) { return models; } -},{"./constants":49,"./sharedUtils":51}],51:[function(require,module,exports){ +},{"./constants":50,"./constants-nosql":49,"./sharedUtils":52}],52:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GetColumnQuantifiers = GetColumnQuantifiers; @@ -201582,6 +201626,7 @@ exports.getCommentIndexes = getCommentIndexes; exports.getMermaidDiagramDb = getMermaidDiagramDb; exports.GenerateDatabaseModel = GenerateDatabaseModel; exports.generateComment = generateComment; +exports.CreateTableUI = CreateTableUI; const constants_1 = require("./constants"); /** * return text quantifiers for dialect @@ -201589,8 +201634,8 @@ const constants_1 = require("./constants"); */ function GetColumnQuantifiers(type) { const chars = { - Start: "\"", - End: "\"", + Start: '"', + End: '"', }; if (type && ["mysql", "ts", "openapi"].includes(type)) { chars.Start = "`"; @@ -201614,6 +201659,11 @@ function removeHtml(label) { tempDiv.remove(); return text; } +/** + * add db ends + * @param label + * @returns + */ function dbTypeEnds(label) { const char1 = "`"; const char2 = "`"; @@ -201623,6 +201673,11 @@ function dbTypeEnds(label) { // } return `${char1}${label}${char2}`; } +/** + * remove name quantifiers + * @param name + * @returns + */ function RemoveNameQuantifiers(name) { return name.replace(/\[|\]|\(|\"|\'|\`/g, "").trim(); } @@ -201654,7 +201709,7 @@ function entityName(description, format) { result += `${description}`; } if (format) { - result += ` @format ${format}`; + result += ` ${constants_1.formatKeyword} ${format}`; } if (result) { result = result.trim(); @@ -201664,16 +201719,24 @@ function entityName(description, format) { } function getCommentIndexes(result) { let hasComment = false; - if (result.indexOf(constants_1.commentColumnQuantifiers.Start) !== -1 && result.indexOf(constants_1.commentColumnQuantifiers.End) !== -1) { + if (result.indexOf(constants_1.commentColumnQuantifiers.Start) !== -1 && + result.indexOf(constants_1.commentColumnQuantifiers.End) !== -1) { hasComment = true; } - const beforeIndex = hasComment ? result.indexOf(constants_1.commentColumnQuantifiers.Start) : -1; - const firstSpaceIndex = hasComment ? result.indexOf(constants_1.commentColumnQuantifiers.Start) + constants_1.commentColumnQuantifiers.Start.length : -1; - const lastSpaceIndex = hasComment ? result.indexOf(constants_1.commentColumnQuantifiers.End) - 1 : -1; + const beforeIndex = hasComment + ? result.indexOf(constants_1.commentColumnQuantifiers.Start) + : -1; + const firstSpaceIndex = hasComment + ? result.indexOf(constants_1.commentColumnQuantifiers.Start) + + constants_1.commentColumnQuantifiers.Start.length + : -1; + const lastSpaceIndex = hasComment + ? result.indexOf(constants_1.commentColumnQuantifiers.End) - 1 + : -1; return { beforeStart: beforeIndex, start: firstSpaceIndex, - end: lastSpaceIndex + end: lastSpaceIndex, }; } /** @@ -201690,6 +201753,7 @@ function getMermaidDiagramDb(ui, type) { const relationships = []; // TODO: support for ts and openapi enum // build models + // fix fk for comments for (const key in model.cells) { if (Object.hasOwnProperty.call(model.cells, key)) { const mxcell = model.cells[key]; @@ -201708,7 +201772,9 @@ function getMermaidDiagramDb(ui, type) { result = result.substring(firstSpaceIndex, lastSpaceIndex); if (result.indexOf(constants_1.formatKeyword) !== -1) { const formatIndex = result.indexOf(constants_1.formatKeyword); - formatValue = result.substring(formatIndex + constants_1.formatKeyword.length).trim(); + formatValue = result + .substring(formatIndex + constants_1.formatKeyword.length) + .trim(); result = result.substring(0, formatIndex); } if (result) { @@ -201722,22 +201788,23 @@ function getMermaidDiagramDb(ui, type) { }; const comment = generateComment(description, formatValue); if (comment) { - entity.name += comment; + entity.name += ` ${comment}`; } - // const comment = + // const comment = for (let c = 0; c < mxcell.children.length; c++) { const col = mxcell.children[c]; if (col.mxObjectId.indexOf("mxCell") !== -1) { - if (col.style && col.style.trim().startsWith("shape=partialRectangle")) { + if (col.style && + col.style.trim().startsWith("shape=partialRectangle")) { const columnQuantifiers = GetColumnQuantifiers(type); //Get delimiter of column name //Get full name const attribute = getDbLabel(col.value, columnQuantifiers); - const attributeKeyType = col.children.find(x => ["FK", "PK"].findIndex(k => k == x.value.toUpperCase()) !== -1 || - x.value.toUpperCase().indexOf("PK,") != -1); + const attributeKeyType = col.children.find((x) => ["FK", "PK"].findIndex((k) => k == x.value.toUpperCase()) !== -1 || x.value.toUpperCase().indexOf("PK,") != -1); if (attributeKeyType) { attribute.attributeKeyType = attributeKeyType.value; - if (attribute.attributeKeyType != "PK" && attribute.attributeKeyType.indexOf("PK") != -1) { + if (attribute.attributeKeyType != "PK" && + attribute.attributeKeyType.indexOf("PK") != -1) { attribute.attributeKeyType = "PK"; } } @@ -201747,53 +201814,106 @@ function getMermaidDiagramDb(ui, type) { for (let e = 0; e < col.edges.length; e++) { const edge = col.edges[e]; if (edge.mxObjectId.indexOf("mxCell") !== -1) { - if (edge.style && edge.style.indexOf("endArrow=") != -1 && edge.source && - edge.source.value && edge.target && edge.target.value) { + if (edge.style && + edge.style.indexOf("endArrow=") != -1 && + edge.source && + edge.source.value && + edge.target && + edge.target.value) { // need to check if end is open or certain value to determin relationship type // extract endArrow txt // check if both match and contain many or open // if both match and are many then create a new table const endCheck = "endArrow="; - const endArr = edge.style.indexOf(endCheck) != -1 ? - edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length, edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length).indexOf(";") + edge.style.indexOf(endCheck) + endCheck.length) + const endArr = edge.style.indexOf(endCheck) != -1 + ? edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length, edge.style + .substring(edge.style.indexOf(endCheck) + + endCheck.length) + .indexOf(";") + + edge.style.indexOf(endCheck) + + endCheck.length) : ""; const startCheck = "startArrow="; - const startArr = edge.style.indexOf(startCheck) != -1 ? - edge.style.substring(edge.style.indexOf(startCheck) + startCheck.length, edge.style.substring(edge.style.indexOf(startCheck) + startCheck.length).indexOf(";") + edge.style.indexOf(startCheck) + startCheck.length) + const startArr = edge.style.indexOf(startCheck) != -1 + ? edge.style.substring(edge.style.indexOf(startCheck) + + startCheck.length, edge.style + .substring(edge.style.indexOf(startCheck) + + startCheck.length) + .indexOf(";") + + edge.style.indexOf(startCheck) + + startCheck.length) : ""; const manyCheck = ["open", "many"]; - const sourceIsPrimary = endArr && manyCheck - .findIndex(x => endArr.toLocaleLowerCase().indexOf(x) != -1) != -1; - const targetIsPrimary = startArr && manyCheck - .findIndex(x => startArr.toLocaleLowerCase().indexOf(x) != -1) != -1; + const sourceIsPrimary = endArr && + manyCheck.findIndex((x) => endArr.toLocaleLowerCase().indexOf(x) != -1) != -1; + const targetIsPrimary = startArr && + manyCheck.findIndex((x) => startArr.toLocaleLowerCase().indexOf(x) != -1) != -1; // has to be one to many and not one to one if ((targetIsPrimary || sourceIsPrimary) && !(targetIsPrimary && sourceIsPrimary)) { let sourceId = edge.source.value; const sourceAttr = getDbLabel(sourceId, columnQuantifiers); sourceId = sourceAttr.attributeName; - const sourceEntity = RemoveNameQuantifiers(edge.source.parent.value); + let sourceEntity = edge.source.parent.value; + // extract comments + let commentsIndexes = getCommentIndexes(sourceEntity); + if (commentsIndexes.start != -1 && + commentsIndexes.end != -1) { + const sourceComment = sourceEntity + .substring(commentsIndexes.start, commentsIndexes.end) + .trim(); + sourceEntity = sourceEntity + .substring(0, commentsIndexes.beforeStart) + .trim(); + sourceEntity = `${RemoveNameQuantifiers(sourceEntity)} ${generateComment(sourceComment)}`; + } + else { + sourceEntity = RemoveNameQuantifiers(sourceEntity); + } let targetId = edge.target.value; const targetAttr = getDbLabel(targetId, columnQuantifiers); targetId = targetAttr.attributeName; - const targetEntity = RemoveNameQuantifiers(edge.target.parent.value); + let targetEntity = edge.target.parent.value; + commentsIndexes = getCommentIndexes(targetEntity); + if (commentsIndexes.start != -1 && + commentsIndexes.end != -1) { + const targetComment = targetEntity + .substring(commentsIndexes.start, commentsIndexes.end) + .trim(); + targetEntity = targetEntity + .substring(0, commentsIndexes.beforeStart) + .trim(); + targetEntity = `${RemoveNameQuantifiers(targetEntity)} ${generateComment(targetComment)}`; + } + else { + targetEntity = RemoveNameQuantifiers(targetEntity); + } + // const targetEntity = RemoveNameQuantifiers( + // edge.target.parent.value + // ); // entityA primary // entityB foreign const relationship = { - entityA: sourceIsPrimary ? sourceEntity : targetEntity, - entityB: sourceIsPrimary ? targetEntity : sourceEntity, + entityA: sourceIsPrimary + ? sourceEntity + : targetEntity, + entityB: sourceIsPrimary + ? targetEntity + : sourceEntity, // based off of styles? relSpec: { cardA: "ZERO_OR_MORE", cardB: "ONLY_ONE", - relType: "IDENTIFYING" + relType: "IDENTIFYING", }, - roleA: sourceIsPrimary ? - `[${sourceEntity}.${sourceId}] to [${targetEntity}.${targetId}]` : - `[${targetEntity}.${targetId}] to [${sourceEntity}.${sourceId}]` + roleA: sourceIsPrimary + ? `[${sourceEntity}.${sourceId}] to [${targetEntity}.${targetId}]` + : `[${targetEntity}.${targetId}] to [${sourceEntity}.${sourceId}]`, }; // check that is doesn't already exist - const exists = relationships.findIndex(r => r.entityA == relationship.entityA && r.entityB == relationship.entityB && r.roleA == relationship.roleA); + const exists = relationships.findIndex((r) => r.entityA == relationship.entityA && + r.entityB == relationship.entityB && + r.roleA == relationship.roleA); if (exists == -1) { relationships.push(relationship); } @@ -201811,8 +201931,10 @@ function getMermaidDiagramDb(ui, type) { targetId = targetAttr.attributeName; const targetEntity = RemoveNameQuantifiers(edge.target.parent.value); const compositeEntity = { - name: RemoveNameQuantifiers(sourceEntity) + "_" + RemoveNameQuantifiers(targetEntity), - attributes: [sourceAttr, targetAttr] + name: RemoveNameQuantifiers(sourceEntity) + + "_" + + RemoveNameQuantifiers(targetEntity), + attributes: [sourceAttr, targetAttr], }; // add composite entity if (entities[compositeEntity.name]) { @@ -201830,12 +201952,14 @@ function getMermaidDiagramDb(ui, type) { relSpec: { cardA: "ZERO_OR_MORE", cardB: "ONLY_ONE", - relType: "IDENTIFYING" + relType: "IDENTIFYING", }, - roleA: `[${sourceEntity}.${sourceId}] to [${compositeEntity.name}.${sourceId}]` + roleA: `[${sourceEntity}.${sourceId}] to [${compositeEntity.name}.${sourceId}]`, }; // check that is doesn't already exist - let exists = relationships.findIndex(r => r.entityA == relationship.entityA && r.entityB == relationship.entityB && r.roleA == relationship.roleA); + let exists = relationships.findIndex((r) => r.entityA == relationship.entityA && + r.entityB == relationship.entityB && + r.roleA == relationship.roleA); if (exists == -1) { relationships.push(relationship); } @@ -201846,12 +201970,14 @@ function getMermaidDiagramDb(ui, type) { relSpec: { cardA: "ZERO_OR_MORE", cardB: "ONLY_ONE", - relType: "IDENTIFYING" + relType: "IDENTIFYING", }, - roleA: `[${targetEntity}.${targetId}] to [${compositeEntity.name}.${targetId}]` + roleA: `[${targetEntity}.${targetId}] to [${compositeEntity.name}.${targetId}]`, }; // check that is doesn't already exist - exists = relationships.findIndex(r => r.entityA == relationship2.entityA && r.entityB == relationship2.entityB && r.roleA == relationship2.roleA); + exists = relationships.findIndex((r) => r.entityA == relationship2.entityA && + r.entityB == relationship2.entityB && + r.roleA == relationship2.roleA); if (exists == -1) { relationships.push(relationship2); } @@ -201881,6 +202007,12 @@ function getMermaidDiagramDb(ui, type) { const db = GenerateDatabaseModel(entities, relationships); return db; } +/** + * genearte a database model + * @param entities + * @param relationships + * @returns + */ function GenerateDatabaseModel(entities, relationships) { class DatabaseModel { constructor(entities, relationships) { @@ -201897,13 +202029,19 @@ function GenerateDatabaseModel(entities, relationships) { const db = new DatabaseModel(entities, relationships); return db; } +/** + * generate a comment using description and format + * @param description + * @param formatValue + * @returns + */ function generateComment(description, formatValue) { let result = ""; if (description) { result += `${description}`; } if (formatValue) { - result += ` @format ${formatValue}`; + result += ` ${constants_1.formatKeyword} ${formatValue}`; } if (result) { result = result.trim(); @@ -201911,5 +202049,174 @@ function generateComment(description, formatValue) { } return result; } +/** + * create uml tables from db models + * @param ui + * @param wndFromInput + * @param tableList + * @param cells + * @param rowCell + * @param tableCell + * @param foreignKeyList + * @param dx + * @param type + * @returns + */ +function CreateTableUI(ui, wndFromInput, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type) { + tableList.forEach(function (tableModel) { + //Define table size width + const maxNameLenght = 100 + tableModel.Name.length; + //Create Table + tableCell = new mxCell(tableModel.Name, new mxGeometry(dx, 0, maxNameLenght, 26), "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;"); + tableCell.vertex = true; + //Resize row + if (rowCell) { + const size = ui.editor.graph.getPreferredSizeForCell(rowCell); + if (size !== null) { + tableCell.geometry.width = size.width + maxNameLenght; + } + } + //Add Table to cells + cells.push(tableCell); + //Add properties + tableModel.Properties.forEach(function (propertyModel) { + //Add row + const addRowResult = AddRow(ui, propertyModel, tableModel.Name, rowCell, tableCell); + if (addRowResult) { + rowCell = addRowResult.rowCell; + tableCell = addRowResult.tableCell; + } + }); + //Close table + dx += tableCell.geometry.width + 40; + tableCell = null; + }); + if (cells.length > 0) { + const graph = ui.editor.graph; + const view = graph.view; + const bds = graph.getGraphBounds(); + // Computes unscaled, untranslated graph bounds + const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize); + const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + + 4 * graph.gridSize); + graph.setSelectionCells(graph.importCells(cells, x, y)); + // add foreign key edges + const model = graph.getModel(); + const columnQuantifiers = GetColumnQuantifiers(type); + // const pt = graph.getFreeInsertPoint(); + foreignKeyList.forEach(function (fk) { + if (fk.IsDestination && + fk.PrimaryKeyName && + fk.ReferencesPropertyName && + fk.PrimaryKeyTableName && + fk.ReferencesTableName) { + const insertEdge = mxUtils.bind(this, function (targetCell, sourceCell, edge) { + const label = ""; + const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; + const edgeCell = graph.insertEdge(null, null, label || "", edge.invert ? sourceCell : targetCell, edge.invert ? targetCell : sourceCell, edgeStyle); + }); + const edge = { + invert: true, + }; + let targetCell = null; + let sourceCell = null; + // locate edge source and target cells + for (const key in model.cells) { + if (targetCell && sourceCell) + break; + if (Object.hasOwnProperty.call(model.cells, key)) { + const mxcell = model.cells[key]; + if (mxcell.style && mxcell.style.trim().startsWith("swimlane;")) { + const entity = { + name: mxcell.value, + attributes: [], + }; + const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; + const isForeignTable = entity.name == fk.ReferencesTableName; + if (isPrimaryTable || isForeignTable) { + for (let c = 0; c < mxcell.children.length; c++) { + if (targetCell && sourceCell) + break; + const col = mxcell.children[c]; + if (col.mxObjectId.indexOf("mxCell") !== -1) { + if (col.style && + col.style.trim().startsWith("shape=partialRectangle")) { + const attribute = getDbLabel(col.value, columnQuantifiers); + if (isPrimaryTable && + dbTypeEnds(attribute.attributeName) == fk.PrimaryKeyName) { + targetCell = col; + // allow recursion + } + if (isForeignTable && + dbTypeEnds(attribute.attributeName) == + fk.ReferencesPropertyName) { + sourceCell = col; + } + if (targetCell && sourceCell) + break; + } + } + } + } + } + } + } + if (targetCell && sourceCell) + insertEdge(targetCell, sourceCell, edge); + } + }); + graph.scrollCellToVisible(graph.getSelectionCell()); + } + wndFromInput.setVisible(false); + return { + cells, + rowCell, + tableCell, + dx, + }; +} +/** + * add row to uml table + * @param ui + * @param propertyModel + * @param tableName + * @param rowCell + * @param tableCell + * @returns + */ +function AddRow(ui, propertyModel, tableName, rowCell, tableCell) { + const cellName = propertyModel.Name + + (propertyModel.ColumnProperties + ? " " + propertyModel.ColumnProperties + : ""); + rowCell = new mxCell(cellName, new mxGeometry(0, 0, 90, 26), "shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;"); + rowCell.vertex = true; + const columnType = propertyModel.IsPrimaryKey && propertyModel.IsForeignKey + ? "PK | FK" + : propertyModel.IsPrimaryKey + ? "PK" + : propertyModel.IsForeignKey + ? "FK" + : ""; + const left = sb.cloneCell(rowCell, columnType); + left.connectable = false; + left.style = + "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;"; + left.geometry.width = 54; + left.geometry.height = 26; + rowCell.insert(left); + const size = ui.editor.graph.getPreferredSizeForCell(rowCell); + if (tableCell) { + if (size !== null && tableCell.geometry.width < size.width + 10) { + tableCell.geometry.width = size.width + 10; + } + tableCell.insert(rowCell); + tableCell.geometry.height += 26; + } + return { + rowCell, + tableCell, + }; +} -},{"./constants":49}]},{},[48]); +},{"./constants":50}]},{},[48]); diff --git a/dist/nosql-ts.min.js b/dist/nosql-ts.min.js index 106d2af..2d076c9 100644 --- a/dist/nosql-ts.min.js +++ b/dist/nosql-ts.min.js @@ -347,17 +347,17 @@ Projects:: `;let t=0;r=e=>{n=(n+=` Project '${e.projectName}' (${A1e[e.projectKind]}) ${t} `)+e.filesToString(!0)+"\n-----------------------------------------------\n",t++};this.projectService.externalProjects.forEach(r),this.projectService.configuredProjects.forEach(r),this.projectService.inferredProjects.forEach(r)}}this.logger.msg(n,"Err")}send(e){"event"!==e.type||this.canUseEvents?this.writeMessage(e):this.logger.hasLevel(3)&&this.logger.info("Session does not support events: ignored event: "+uW(e))}writeMessage(e){e=ive(e,this.logger,this.byteLength,this.host.newLine);null!=er&&er.logEvent("Response message size: "+e.length),this.host.write(e)}event(e,t){this.send(ove(t,e))}doOutput(n,i,e,t,r){i={seq:0,type:"response",command:i,request_seq:e,success:t,performanceData:this.performanceData};if(t){let r;if(i3(n))i.body=n,r=n.metadata,delete n.metadata;else if("object"==typeof n)if(n.metadata){let{metadata:e,...t}=n;i.body=t,r=e}else i.body=n;else i.body=n;r&&(i.metadata=r)}else Y4.assert(void 0===n);r&&(i.message=r),this.send(i)}semanticCheck(e,t){null!=Z4&&Z4.push(Z4.Phase.Session,"semanticCheck",{file:e,configFilePath:t.canonicalConfigFilePath});var r=Yye(t,e)?Z0e:t.getLanguageService().getSemanticDiagnostics(e).filter(e=>!!e.file);this.sendDiagnosticsEvent(e,t,r,"semanticDiag"),null!=Z4&&Z4.pop()}syntacticCheck(e,t){null!=Z4&&Z4.push(Z4.Phase.Session,"syntacticCheck",{file:e,configFilePath:t.canonicalConfigFilePath}),this.sendDiagnosticsEvent(e,t,t.getLanguageService().getSyntacticDiagnostics(e),"syntaxDiag"),null!=Z4&&Z4.pop()}suggestionCheck(e,t){null!=Z4&&Z4.push(Z4.Phase.Session,"suggestionCheck",{file:e,configFilePath:t.canonicalConfigFilePath}),this.sendDiagnosticsEvent(e,t,t.getLanguageService().getSuggestionDiagnostics(e),"suggestionDiag"),null!=Z4&&Z4.pop()}sendDiagnosticsEvent(t,r,e,n){try{this.event({file:t,diagnostics:e.map(e=>Zye(t,r,e))},n)}catch(e){this.logError(e,n)}}updateErrorCheck(n,e,t,i=!0){Y4.assert(!this.suppressDiagnosticEvents);let a=this.changeSeq,r=Math.min(t,200),o=0,s=()=>{o++,e.length>o&&n.delay("checkOne",r,c)},c=()=>{if(this.changeSeq===a){let r=e[o];if(a3(r)&&!(r=this.toPendingErrorCheck(r)))s();else{let{fileName:e,project:t}=r;jye(t),t.containsFile(e,i)&&(this.syntacticCheck(e,t),this.changeSeq===a)&&(0!==t.projectService.serverMode?s():n.immediate("semanticCheck",()=>{this.semanticCheck(e,t),this.changeSeq===a&&(this.getPreferences(e).disableSuggestions?s():n.immediate("suggestionCheck",()=>{this.suggestionCheck(e,t),s()}))}))}}};e.length>o&&this.changeSeq===a&&n.delay("checkOne",t,c)}cleanProjects(e,t){if(t){this.logger.info("cleaning "+e);for(var r of t)r.getLanguageService(!1).cleanupSemanticCache(),r.cleanupProgram()}}cleanup(){this.cleanProjects("inferred projects",this.projectService.inferredProjects),this.cleanProjects("configured projects",ZT(this.projectService.configuredProjects.values())),this.cleanProjects("external projects",this.projectService.externalProjects),this.host.gc&&(this.logger.info("host.gc()"),this.host.gc())}getEncodedSyntacticClassifications(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e);return r.getEncodedSyntacticClassifications(t,e)}getEncodedSemanticClassifications(e){var{file:t,project:r}=this.getFileAndProject(e),n="2020"===e.format?"2020":"original";return r.getLanguageService().getEncodedSemanticClassifications(t,e,n)}getProject(e){return void 0===e?void 0:this.projectService.findProject(e)}getConfigFileAndProject(e){var t=this.getProject(e.projectFileName),e=r1e(e.file);return{configFile:t&&t.hasConfigFile(e)?e:void 0,project:t}}getConfigFileDiagnostics(t,e,r){e=NT(LT(e.getAllProjectErrors(),e.getLanguageService().getCompilerOptionsDiagnostics()),e=>!!e.file&&e.file.fileName===t);return r?this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(e):$4(e,e=>rve(e,!1))}convertToDiagnosticsWithLinePositionFromDiagnosticFile(e){return e.map(e=>({message:lJ(e.messageText,this.host.newLine),start:e.start,length:e.length,category:Fn(e),code:e.code,source:e.source,startLocation:e.file&&tve(O3(e.file,e.start)),endLocation:e.file&&tve(O3(e.file,e.start+e.length)),reportsUnnecessary:e.reportsUnnecessary,reportsDeprecated:e.reportsDeprecated,relatedInformation:$4(e.relatedInformation,eve)}))}getCompilerOptionsDiagnostics(e){e=this.getProject(e.projectFileName);return this.convertToDiagnosticsWithLinePosition(NT(e.getLanguageService().getCompilerOptionsDiagnostics(),e=>!e.file),void 0)}convertToDiagnosticsWithLinePosition(e,t){return e.map(e=>({message:lJ(e.messageText,this.host.newLine),start:e.start,length:e.length,category:Fn(e),code:e.code,source:e.source,startLocation:t&&t.positionToLineOffset(e.start),endLocation:t&&t.positionToLineOffset(e.start+e.length),reportsUnnecessary:e.reportsUnnecessary,reportsDeprecated:e.reportsDeprecated,relatedInformation:$4(e.relatedInformation,eve)}))}getDiagnosticsWorker(e,t,r,n){let{project:i,file:a}=this.getFileAndProject(e);return t&&Yye(i,a)?Z0e:(e=i.getScriptInfoForNormalizedPath(a),t=r(i,a),n?this.convertToDiagnosticsWithLinePosition(t,e):t.map(e=>Zye(a,i,e)))}getDefinition(e,t){var{file:r,project:n}=this.getFileAndProject(e),e=this.getPositionInFile(e,r),r=this.mapDefinitionInfoLocations(n.getLanguageService().getDefinitionAtPosition(r,e)||Z0e,n);return t?this.mapDefinitionInfo(r,n):r.map(Hve.mapToOriginalLocation)}mapDefinitionInfoLocations(e,r){return e.map(e=>{var t=fve(e,r);return t?{...t,containerKind:e.containerKind,containerName:e.containerName,kind:e.kind,name:e.name,failedAliasResolution:e.failedAliasResolution,...e.unverified&&{unverified:e.unverified}}:e})}getDefinitionAndBoundSpan(e,t){var{file:r,project:n}=this.getFileAndProject(e),e=this.getPositionInFile(e,r),i=Y4.checkDefined(n.getScriptInfo(r)),r=n.getLanguageService().getDefinitionAndBoundSpan(r,e);return r&&r.definitions?(e=this.mapDefinitionInfoLocations(r.definitions,n),r=r["textSpan"],t?{definitions:this.mapDefinitionInfo(e,n),textSpan:yve(r,i)}:{definitions:e.map(Hve.mapToOriginalLocation),textSpan:r}):{definitions:Z0e,textSpan:void 0}}findSourceDefinition(e){let r,{file:i,project:c}=this.getFileAndProject(e),a=this.getPositionInFile(e,i);e=c.getLanguageService().getDefinitionAtPosition(i,a);let n=this.mapDefinitionInfoLocations(e||Z0e,c).slice();if(0===this.projectService.serverMode&&(!X4(n,e=>r1e(e.fileName)!==i&&!e.isAmbient)||X4(n,e=>!!e.failedAliasResolution))){let t=oe(e=>e.textSpan.start,bG(this.host.useCaseSensitiveFileNames));null!=n&&n.forEach(e=>t.add(e));var o=c.getNoDtsResolutionProject(i),s=o.getLanguageService(),e=null==(r=s.getDefinitionAtPosition(i,a,!0,!1))?void 0:r.filter(e=>r1e(e.fileName)!==i);if(X4(e))for(var l of e){if(l.unverified){var _=function(e,t,r){e=r.getSourceFile(e.fileName);if(e){var n=XH(t.getSourceFile(i),a),t=t.getTypeChecker().getSymbolAtLocation(n),n=t&&F7(t,276);if(n)return g((null==(t=n.propertyName)?void 0:t.text)||n.name.text,e,r)}}(l,c.getLanguageService().getProgram(),s.getProgram());if(X4(_)){for(var u of _)t.add(u);continue}}t.add(l)}else{var d,e=n.filter(e=>r1e(e.fileName)!==i&&e.isAmbient);for(d of X4(e)?e:function(){let t=c.getLanguageService(),e=t.getProgram(),r=XH(e.getSourceFile(i),a);if((k7(r)||uT(r))&&lD(r.parent))return uf(r,e=>{return e!==r&&X4(e=null==(e=t.getDefinitionAtPosition(i,e.getStart(),!0,!1))?void 0:e.filter(e=>r1e(e.fileName)!==i&&e.isAmbient).map(e=>({fileName:e.fileName,name:Kw(r)})))?e:void 0})||Z0e;return Z0e}()){var p=function(e,r,n){var i=dg(e);if(i&&e.lastIndexOf(fO)===i.topLevelNodeModulesIndex){var a=e.substring(0,i.packageRootIndex),o=null==(o=c.getModuleResolutionCache())?void 0:o.getPackageJsonInfoCache(),s=c.getCompilationSettings(),a=DO(E3(a+"/package.json",c.getCurrentDirectory()),NO(o,c,s));if(!a)return;var o=wO(a,{moduleResolution:2},c,c.getModuleResolutionCache()),s=$O(XO(e.substring(i.topLevelPackageNameIndex+1,i.packageRootIndex)));let t=c.toPath(e);return o&&X4(o,e=>c.toPath(e)===t)?null==(a=n.resolutionCache.resolveSingleModuleNameWithoutWatching(s,r).resolvedModule)?void 0:a.resolvedFileName:(o=e.substring(i.packageRootIndex+1),a=s+"/"+qm(o),null==(e=n.resolutionCache.resolveSingleModuleNameWithoutWatching(a,r).resolvedModule)?void 0:e.resolvedFileName)}}(d.fileName,i,o);if(p){var f=this.projectService.getOrCreateScriptInfoNotOpenedByClient(p,o.currentDirectory,o.directoryStructureHost,!1);if(f){o.containsScriptInfo(f)||(o.addRoot(f),o.updateGraph());var m,f=s.getProgram(),p=Y4.checkDefined(f.getSourceFile(p));for(m of g(d.name,p,f))t.add(m)}}}}n=ZT(t.values())}return n=n.filter(e=>!e.isAmbient&&!e.failedAliasResolution),this.mapDefinitionInfo(n,c);function g(e,t,r){return AT(ope.Core.getTopMostDeclarationNamesInFile(e,t),e=>{var t=r.getTypeChecker().getSymbolAtLocation(e),e=Su(e);if(t&&e)return mfe.createDefinitionInfo(e,r.getTypeChecker(),t,e,!0)})}}getEmitOutput(e){var{file:t,project:r}=this.getFileAndProject(e);return r.shouldEmitFile(r.getScriptInfo(t))?(r=r.getLanguageService().getEmitOutput(t),e.richResponse?{...r,diagnostics:e.includeLinePosition?this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(r.diagnostics):r.diagnostics.map(e=>rve(e,!0))}:r):{emitSkipped:!0,outputFiles:[],diagnostics:[]}}mapJSDocTagInfo(e,t,r){return e?e.map(e=>{return{...e,text:r?this.mapDisplayParts(e.text,t):null==(e=e.text)?void 0:e.map(e=>e.text).join("")}}):[]}mapDisplayParts(e,t){return e?e.map(e=>"linkName"!==e.kind?e:{...e,target:this.toFileSpan(e.target.fileName,e.target.textSpan,t)}):[]}mapSignatureHelpItems(e,t,r){return e.map(e=>({...e,documentation:this.mapDisplayParts(e.documentation,t),parameters:e.parameters.map(e=>({...e,documentation:this.mapDisplayParts(e.documentation,t)})),tags:this.mapJSDocTagInfo(e.tags,t,r)}))}mapDefinitionInfo(e,t){return e.map(e=>({...this.toFileSpanWithContext(e.fileName,e.textSpan,e.contextSpan,t),...e.unverified&&{unverified:e.unverified}}))}static mapToOriginalLocation(e){return e.originalFileName?(Y4.assert(void 0!==e.originalTextSpan,"originalTextSpan should be present if originalFileName is"),{...e,fileName:e.originalFileName,textSpan:e.originalTextSpan,targetFileName:e.fileName,targetTextSpan:e.textSpan,contextSpan:e.originalContextSpan,targetContextSpan:e.contextSpan}):e}toFileSpan(e,t,r){var r=r.getLanguageService(),n=r.toLineColumnOffset(e,t.start),r=r.toLineColumnOffset(e,J3(t));return{file:e,start:{line:n.line+1,offset:n.character+1},end:{line:r.line+1,offset:r.character+1}}}toFileSpanWithContext(e,t,r,n){t=this.toFileSpan(e,t,n),e=r&&this.toFileSpan(e,r,n);return e?{...t,contextStart:e.start,contextEnd:e.end}:t}getTypeDefinition(e){var{file:t,project:r}=this.getFileAndProject(e),e=this.getPositionInFile(e,t),t=this.mapDefinitionInfoLocations(r.getLanguageService().getTypeDefinitionAtPosition(t,e)||Z0e,r);return this.mapDefinitionInfo(t,r)}mapImplementationLocations(e,r){return e.map(e=>{var t=fve(e,r);return t?{...t,kind:e.kind,displayParts:e.displayParts}:e})}getImplementation(e,t){let{file:r,project:n}=this.getFileAndProject(e);e=this.getPositionInFile(e,r),e=this.mapImplementationLocations(n.getLanguageService().getImplementationAtPosition(r,e)||Z0e,n);return t?e.map(({fileName:e,textSpan:t,contextSpan:r})=>this.toFileSpanWithContext(e,t,r,n)):e.map(Hve.mapToOriginalLocation)}getSyntacticDiagnosticsSync(e){var t=this.getConfigFileAndProject(e)["configFile"];return t?Z0e:this.getDiagnosticsWorker(e,!1,(e,t)=>e.getLanguageService().getSyntacticDiagnostics(t),!!e.includeLinePosition)}getSemanticDiagnosticsSync(e){var{configFile:t,project:r}=this.getConfigFileAndProject(e);return t?this.getConfigFileDiagnostics(t,r,!!e.includeLinePosition):this.getDiagnosticsWorker(e,!0,(e,t)=>e.getLanguageService().getSemanticDiagnostics(t).filter(e=>!!e.file),!!e.includeLinePosition)}getSuggestionDiagnosticsSync(e){var t=this.getConfigFileAndProject(e)["configFile"];return t?Z0e:this.getDiagnosticsWorker(e,!0,(e,t)=>e.getLanguageService().getSuggestionDiagnostics(t),!!e.includeLinePosition)}getJsxClosingTag(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),e=this.getPositionInFile(e,t),r=r.getJsxClosingTagAtPosition(t,e);return void 0===r?void 0:{newText:r.newText,caretOffset:0}}getLinkedEditingRange(e){var t,{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e),e=this.getPositionInFile(e,r),n=n.getLinkedEditingRangeAtPosition(r,e),e=this.projectService.getScriptInfoForNormalizedPath(r);if(void 0!==e&&void 0!==n)return t=e,e=(r=n).ranges.map(e=>({start:t.positionToLineOffset(e.start),end:t.positionToLineOffset(e.start+e.length)})),r.wordPattern?{ranges:e,wordPattern:r.wordPattern}:{ranges:e}}getDocumentHighlights(e,t){let{file:r,project:i}=this.getFileAndProject(e);var n=this.getPositionInFile(e,r),n=i.getLanguageService().getDocumentHighlights(r,n,e.filesToSearch);return n?t?n.map(({fileName:e,highlightSpans:t})=>{let n=i.getScriptInfo(e);return{file:e,highlightSpans:t.map(({textSpan:e,kind:t,contextSpan:r})=>({...vve(e,r,n),kind:t}))}}):n:Z0e}provideInlayHints(e){var{file:t,project:r}=this.getFileAndProject(e);let n=this.projectService.getScriptInfoForNormalizedPath(t);return r.getLanguageService().provideInlayHints(t,e,this.getPreferences(t)).map(e=>{var{position:t,displayParts:r}=e;return{...e,position:n.positionToLineOffset(t),displayParts:null==r?void 0:r.map(({text:e,span:t,file:r})=>{var n;return t?(Y4.assertIsDefined(r,"Target file should be defined together with its span."),{text:e,span:{start:(n=this.projectService.getScriptInfo(r)).positionToLineOffset(t.start),end:n.positionToLineOffset(t.start+t.length),file:r}}):{text:e}})}})}mapCode(e){var t=this.getHostFormatOptions(),r=this.getHostPreferences(),{file:n,languageService:i}=this.getFileAndLanguageServiceForSyntacticOperation(e);let a=this.projectService.getScriptInfoForNormalizedPath(n);var o=null==(o=e.mapping.focusLocations)?void 0:o.map(e=>e.map(e=>{var t=a.lineOffsetToPosition(e.start.line,e.start.offset);return{start:t,length:a.lineOffsetToPosition(e.end.line,e.end.offset)-t}})),i=i.mapCode(n,e.mapping.contents,o,t,r);return this.mapTextChangesToCodeEdits(i)}setCompilerOptionsForInferredProjects(e){this.projectService.setCompilerOptionsForInferredProjects(e.options,e.projectRootPath)}getProjectInfo(e){return this.getProjectInfoWorker(e.file,e.projectFileName,e.needFileNameList,!1)}getProjectInfoWorker(e,t,r,n){e=this.getFileAndProjectWorker(e,t).project,jye(e),t={configFileName:e.getProjectName(),languageServiceDisabled:!e.languageServiceEnabled,fileNames:r?e.getFileNames(!1,n):void 0};return t}getRenameInfo(e){var{file:t,project:r}=this.getFileAndProject(e),e=this.getPositionInFile(e,t),n=this.getPreferences(t);return r.getLanguageService().getRenameInfo(t,e,n)}getProjects(e,t,r){let n,i;if(e.projectFileName){var a=this.getProject(e.projectFileName);a&&(n=[a])}else{a=t?this.projectService.getScriptInfoEnsuringProjectsUptoDate(e.file):this.projectService.getScriptInfo(e.file);if(!a)return r?Z0e:(this.projectService.logErrorForScriptInfoNotFound(e.file),Q0e.ThrowNoProject());t||this.projectService.ensureDefaultProjectForFile(a),n=a.containingProjects,i=this.projectService.getSymlinkedProjects(a)}return n=NT(n,e=>e.languageServiceEnabled&&!e.isOrphan()),r||n&&n.length||i?i?{projects:n,symLinkedProjects:i}:n:(this.projectService.logErrorForScriptInfoNotFound(e.file??e.projectFileName),Q0e.ThrowNoProject())}getDefaultProject(e){if(e.projectFileName){var t=this.getProject(e.projectFileName);if(t)return t;if(!e.file)return Q0e.ThrowNoProject()}return this.projectService.getScriptInfo(e.file).getDefaultProject()}getRenameLocations(e,t){var r=r1e(e.file),n=this.getPositionInFile(e,r),i=this.getProjects(e),a=this.getDefaultProject(e),o=this.getPreferences(r),r=this.mapRenameInfo(a.getLanguageService().getRenameInfo(r,n,o),Y4.checkDefined(this.projectService.getScriptInfo(r)));return r.canRename?(i=function(e,t,r,n,i,a,o){if(i3(e=_ve(e,t,r,!0,(e,t)=>e.getLanguageService().findRenameLocations(t.fileName,t.pos,n,i,a),(e,t)=>t(dve(e)))))return e;let s=[],c=sve(o);return e.forEach((e,t)=>{for(var r of e)c.has(r)||pve(dve(r),t)||(s.push(r),c.add(r))}),s}(i,a,{fileName:e.file,pos:n},!!e.findInStrings,!!e.findInComments,o,this.host.useCaseSensitiveFileNames),t?{info:r,locs:this.toSpanGroups(i)}:i):t?{info:r,locs:[]}:[]}mapRenameInfo(e,t){var r,n,i,a,o,s,c;return e.canRename?({canRename:r,fileToRename:n,displayName:i,fullDisplayName:a,kind:o,kindModifiers:s,triggerSpan:c}=e,{canRename:r,fileToRename:n,displayName:i,fullDisplayName:a,kind:o,kindModifiers:s,triggerSpan:yve(c,t)}):e}toSpanGroups(e){var t,r,n,i,a,o,s,c=new Map;for({fileName:t,textSpan:r,contextSpan:n,originalContextSpan:i,originalTextSpan:a,originalFileName:o,...s}of e){let e=c.get(t);e||c.set(t,e={file:t,locs:[]});var l=Y4.checkDefined(this.projectService.getScriptInfo(t));e.locs.push({...vve(r,n,l),...s})}return ZT(c.values())}getReferences(e,t){var r=r1e(e.file),n=this.getProjects(e),i=this.getPositionInFile(e,r),n=cve(n,this.getDefaultProject(e),{fileName:e.file,pos:i},this.host.useCaseSensitiveFileNames,this.logger);if(!t)return n;let a=this.getPreferences(r);t=this.getDefaultProject(e),e=t.getScriptInfoForNormalizedPath(r),t=t.getLanguageService().getQuickInfoAtPosition(r,i),r=t?Ire(t.displayParts):"",i=t&&t.textSpan,t=i?e.positionToLineOffset(i.start).offset:0,e=i?e.getSnapshot().getText(i.start,J3(i)):"";return{refs:FT(n,e=>e.references.map(e=>Sve(this.projectService,e,a))),symbolName:e,symbolStartOffset:t,symbolDisplayString:r}}getFileReferences(e,t){var r=this.getProjects(e);let n=e.file,i=this.getPreferences(r1e(n)),a=[],o=sve(this.host.useCaseSensitiveFileNames);return lve(r,void 0,e=>{if(!e.getCancellationToken().isCancellationRequested()){e=e.getLanguageService().getFileReferences(n);if(e)for(var t of e)o.has(t)||(a.push(t),o.add(t))}}),t?{refs:a.map(e=>Sve(this.projectService,e,i)),symbolName:`"${e.file}"`}:a}openClientFile(e,t,r,n){this.projectService.openClientFileWithNormalizedPath(e,t,r,!1,n)}getPosition(e,t){return void 0!==e.position?e.position:t.lineOffsetToPosition(e.line,e.offset)}getPositionInFile(e,t){t=this.projectService.getScriptInfoForNormalizedPath(t);return this.getPosition(e,t)}getFileAndProject(e){return this.getFileAndProjectWorker(e.file,e.projectFileName)}getFileAndLanguageServiceForSyntacticOperation(e){var{file:e,project:t}=this.getFileAndProject(e);return{file:e,languageService:t.getLanguageService(!1)}}getFileAndProjectWorker(e,t){e=r1e(e);return{file:e,project:this.getProject(t)||this.projectService.ensureDefaultProjectForFile(e)}}getOutliningSpans(e,t){var{file:e,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),r=r.getOutliningSpans(e);if(t){let t=this.projectService.getScriptInfoForNormalizedPath(e);return r.map(e=>({textSpan:yve(e.textSpan,t),hintSpan:yve(e.hintSpan,t),bannerText:e.bannerText,autoCollapse:e.autoCollapse,kind:e.kind}))}return r}getTodoComments(e){var{file:t,project:r}=this.getFileAndProject(e);return r.getLanguageService().getTodoComments(t,e.descriptors)}getDocCommentTemplate(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),e=this.getPositionInFile(e,t);return r.getDocCommentTemplateAtPosition(t,e,this.getPreferences(t),this.getFormatOptions(t))}getSpanOfEnclosingComment(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),n=e.onlyMultiLine,e=this.getPositionInFile(e,t);return r.getSpanOfEnclosingComment(t,e,n)}getIndentation(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),n=this.getPositionInFile(e,t),e=e.options?mye(e.options):this.getFormatOptions(t);return{position:n,indentation:r.getIndentationAtPosition(t,n,e)}}getBreakpointStatement(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),e=this.getPositionInFile(e,t);return r.getBreakpointStatementAtPosition(t,e)}getNameOrDottedNameSpan(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),e=this.getPositionInFile(e,t);return r.getNameOrDottedNameSpan(t,e,e)}isValidBraceCompletion(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),n=this.getPositionInFile(e,t);return r.isValidBraceCompletionAtPosition(t,n,e.openingBrace.charCodeAt(0))}getQuickInfoWorker(e,t){var{file:r,project:n}=this.getFileAndProject(e),i=this.projectService.getScriptInfoForNormalizedPath(r),e=n.getLanguageService().getQuickInfoAtPosition(r,this.getPosition(e,i));if(e)return r=!!this.getPreferences(r).displayPartsForJSDoc,t?(t=Ire(e.displayParts),{kind:e.kind,kindModifiers:e.kindModifiers,start:i.positionToLineOffset(e.textSpan.start),end:i.positionToLineOffset(J3(e.textSpan)),displayString:t,documentation:r?this.mapDisplayParts(e.documentation,n):Ire(e.documentation),tags:this.mapJSDocTagInfo(e.tags,n,r)}):r?e:{...e,tags:this.mapJSDocTagInfo(e.tags,n,!1)}}getFormattingEditsForRange(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e);let n=this.projectService.getScriptInfoForNormalizedPath(t);var i=n.lineOffsetToPosition(e.line,e.offset),e=n.lineOffsetToPosition(e.endLine,e.endOffset),r=r.getFormattingEditsForRange(t,i,e,this.getFormatOptions(t));if(r)return r.map(e=>this.convertTextChangeToCodeEdit(e,n))}getFormattingEditsForRangeFull(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),n=e.options?mye(e.options):this.getFormatOptions(t);return r.getFormattingEditsForRange(t,e.position,e.endPosition,n)}getFormattingEditsForDocumentFull(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),e=e.options?mye(e.options):this.getFormatOptions(t);return r.getFormattingEditsForDocument(t,e)}getFormattingEditsAfterKeystrokeFull(e){var{file:t,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),n=e.options?mye(e.options):this.getFormatOptions(t);return r.getFormattingEditsAfterKeystroke(t,e.position,e.key,n)}getFormattingEditsAfterKeystroke(n){var{file:i,languageService:a}=this.getFileAndLanguageServiceForSyntacticOperation(n);let t=this.projectService.getScriptInfoForNormalizedPath(i);var r,o=t.lineOffsetToPosition(n.line,n.offset),s=this.getFormatOptions(i),c=a.getFormattingEditsAfterKeystroke(i,o,n.key,s);if("\n"===n.key&&(!c||0===c.length||(r=o,c.every(e=>J3(e.span)({start:t.positionToLineOffset(e.span.start),end:t.positionToLineOffset(J3(e.span)),newText:e.newText||""}))}getCompletions(e,t){var{file:r,project:n}=this.getFileAndProject(e);let h=this.projectService.getScriptInfoForNormalizedPath(r);var i=this.getPosition(e,h);let y=n.getLanguageService().getCompletionsAtPosition(r,i,{...xye(this.getPreferences(r)),triggerCharacter:e.triggerCharacter,triggerKind:e.triggerKind,includeExternalModuleExports:e.includeExternalModuleExports,includeInsertTextCompletions:e.includeInsertTextCompletions},n.projectService.getFormatCodeOptions(r));if(void 0!==y){if("completions-full"===t)return y;let g=e.prefix||"";i=AT(y.entries,e=>{var t,r,n,i,a,o,s,c,l,_,u,d,p,f,m;if(y.isMemberCompletion||f3(e.name.toLowerCase(),g.toLowerCase()))return{name:e,kind:t,kindModifiers:r,sortText:n,insertText:i,filterText:a,replacementSpan:o,hasAction:s,source:c,sourceDisplay:l,labelDetails:_,isSnippet:u,isRecommended:d,isPackageJsonImport:p,isImportStatementCompletion:f,data:m}=e,{name:e,kind:t,kindModifiers:r,sortText:n,insertText:i,filterText:a,replacementSpan:o?yve(o,h):void 0,isSnippet:u,hasAction:s||void 0,source:c,sourceDisplay:l,labelDetails:_,isRecommended:d,isPackageJsonImport:p,isImportStatementCompletion:f,data:m}});return"completions"===t?(y.metadata&&(i.metadata=y.metadata),i):{...y,optionalReplacementSpan:y.optionalReplacementSpan&&yve(y.optionalReplacementSpan,h),entries:i}}}getCompletionEntryDetails(e,t){let{file:n,project:i}=this.getFileAndProject(e);var r=this.projectService.getScriptInfoForNormalizedPath(n);let a=this.getPosition(e,r),o=i.projectService.getFormatCodeOptions(n),s=!!this.getPreferences(n).displayPartsForJSDoc;r=AT(e.entryNames,e=>{var{name:e,source:t,data:r}="string"==typeof e?{name:e,source:void 0,data:void 0}:e;return i.getLanguageService().getCompletionEntryDetails(n,a,e,o,t,this.getPreferences(n),r?s3(r,kve):void 0)});return t?s?r:r.map(e=>({...e,tags:this.mapJSDocTagInfo(e.tags,i,!1)})):r.map(e=>({...e,codeActions:$4(e.codeActions,e=>this.mapCodeAction(e)),documentation:this.mapDisplayParts(e.documentation,i),tags:this.mapJSDocTagInfo(e.tags,i,s)}))}getCompileOnSaveAffectedFileList(e){var t=this.getProjects(e,!0,!0),e=this.projectService.getScriptInfo(e.file);if(e){var r=e;var i=e=>this.projectService.getScriptInfoForPath(e);e=t;var a=(e,t)=>{if(e.compileOnSaveEnabled&&e.languageServiceEnabled&&!e.isOrphan()){var r,n=e.getCompilationSettings();if(!n.noEmit&&(!x9(t.fileName)||wD(r=n)||r.emitDecoratorMetadata))return{projectFileName:e.getProjectName(),fileNames:e.getCompileOnSaveAffectedFileList(t),projectUsesOutFile:!!n.outFile}}};let n=y(i3(e)?e:e.projects,e=>a(e,r));return!i3(e)&&e.symLinkedProjects&&e.symLinkedProjects.forEach((e,t)=>{let r=i(t);n.push(...FT(e,e=>a(e,r)))}),RT(n,c3)}return Z0e}emitFile(e){var{file:t,project:r}=this.getFileAndProject(e);return r||Q0e.ThrowNoProject(),r.languageServiceEnabled?(t=r.getScriptInfo(t),{emitSkipped:r,diagnostics:t}=r.emitFile(t,(e,t,r)=>this.host.writeFile(e,t,r)),e.richResponse?{emitSkipped:r,diagnostics:e.includeLinePosition?this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(t):t.map(e=>rve(e,!0))}:!r):!!e.richResponse&&{emitSkipped:!0,diagnostics:[]}}getSignatureHelpItems(e,t){let{file:r,project:n}=this.getFileAndProject(e);var i=this.projectService.getScriptInfoForNormalizedPath(r),a=this.getPosition(e,i),a=n.getLanguageService().getSignatureHelpItems(r,a,e),e=!!this.getPreferences(r).displayPartsForJSDoc;return a&&t?(t=a.applicableSpan,{...a,applicableSpan:{start:i.positionToLineOffset(t.start),end:i.positionToLineOffset(t.start+t.length)},items:this.mapSignatureHelpItems(a.items,n,e)}):e||!a?a:{...a,items:a.items.map(e=>({...e,tags:this.mapJSDocTagInfo(e.tags,n,!1)}))}}toPendingErrorCheck(e){var e=r1e(e),t=this.projectService.tryGetDefaultProjectForFile(e);return t&&{fileName:e,project:t}}getDiagnostics(e,t,r){this.suppressDiagnosticEvents||0({text:e.text,kind:e.kind,kindModifiers:e.kindModifiers,spans:e.spans.map(e=>yve(e,t)),childItems:this.mapLocationNavigationBarItems(e.childItems,t),indent:e.indent}))}getNavigationBarItems(e,t){var{file:e,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),r=r.getNavigationBarItems(e);return r?t?this.mapLocationNavigationBarItems(r,this.projectService.getScriptInfoForNormalizedPath(e)):r:void 0}toLocationNavigationTree(e,t){return{text:e.text,kind:e.kind,kindModifiers:e.kindModifiers,spans:e.spans.map(e=>yve(e,t)),nameSpan:e.nameSpan&&yve(e.nameSpan,t),childItems:$4(e.childItems,e=>this.toLocationNavigationTree(e,t))}}getNavigationTree(e,t){var{file:e,languageService:r}=this.getFileAndLanguageServiceForSyntacticOperation(e),r=r.getNavigationTree(e);return r?t?this.toLocationNavigationTree(r,this.projectService.getScriptInfoForNormalizedPath(e)):r:void 0}getNavigateToItems(e,t){e=this.getFullNavigateToItems(e);return FT(e,t?({project:r,navigateToItems:e})=>e.map(e=>{var t=r.getScriptInfo(e.fileName),t={name:e.name,kind:e.kind,kindModifiers:e.kindModifiers,isCaseSensitive:e.isCaseSensitive,matchKind:e.matchKind,file:e.fileName,start:t.positionToLineOffset(e.textSpan.start),end:t.positionToLineOffset(J3(e.textSpan))};return e.kindModifiers&&""!==e.kindModifiers&&(t.kindModifiers=e.kindModifiers),e.containerName&&0e)}getFullNavigateToItems(e){let{currentFileOnly:t,searchValue:r,maxResultCount:n,projectFileName:i}=e;var a,o;if(t)return Y4.assertIsDefined(e.file),{file:a,project:o}=this.getFileAndProject(e),[{project:o,navigateToItems:o.getLanguageService().getNavigateToItems(r,n,a)}];let s=this.getHostPreferences(),c=[],l=new Map;return e.file||i?lve(this.getProjects(e),void 0,e=>_(e)):(this.projectService.loadAncestorProjectTree(),this.projectService.forEachEnabledProject(e=>_(e))),c;function _(t){var e=NT(t.getLanguageService().getNavigateToItems(r,n,void 0,t.isNonTsProject(),s.excludeLibrarySymbolsInNavTo),e=>function(e){var t=e.name;if(l.has(t)){var r,n=l.get(t);for(r of n)if(function(e,t){return e===t||!(!e||!t)&&e.containerKind===t.containerKind&&e.containerName===t.containerName&&e.fileName===t.fileName&&e.isCaseSensitive===t.isCaseSensitive&&e.kind===t.kind&&e.kindModifiers===t.kindModifiers&&e.matchKind===t.matchKind&&e.name===t.name&&e.textSpan.start===t.textSpan.start&&e.textSpan.length===t.textSpan.length}(r,e))return!1;n.push(e)}else l.set(t,[e]);return!0}(e)&&!pve(dve(e),t));e.length&&c.push({project:t,navigateToItems:e})}}getSupportedCodeFixes(e){var t,r;return e?e.file?({file:t,project:r}=this.getFileAndProject(e),r.getLanguageService().getSupportedCodeFixes(t)):((r=this.getProject(e.projectFileName))||Q0e.ThrowNoProject(),r.getLanguageService().getSupportedCodeFixes()):Lre()}isLocation(e){return void 0!==e.line}extractPositionOrRange(e,t){let r,n;var i;return this.isLocation(e)?r=void 0!==(i=e).position?i.position:t.lineOffsetToPosition(i.line,i.offset):n=this.getRange(e,t),Y4.checkDefined(void 0===r?n:r)}getRange(e,t){var{startPosition:e,endPosition:t}=this.getStartAndEndPosition(e,t);return{pos:e,end:t}}getApplicableRefactors(e){var{file:t,project:r}=this.getFileAndProject(e),n=r.getScriptInfoForNormalizedPath(t);return r.getLanguageService().getApplicableRefactors(t,this.extractPositionOrRange(e,n),this.getPreferences(t),e.triggerReason,e.kind,e.includeInteractiveActions).map(e=>({...e,actions:e.actions.map(e=>({...e,range:e.range?{start:tve({line:e.range.start.line,character:e.range.start.offset}),end:tve({line:e.range.end.line,character:e.range.end.offset})}:void 0}))}))}getEditsForRefactor(t,r){var{file:n,project:i}=this.getFileAndProject(t),a=i.getScriptInfoForNormalizedPath(n),a=i.getLanguageService().getEditsForRefactor(n,this.getFormatOptions(n),this.extractPositionOrRange(t,a),t.refactor,t.action,this.getPreferences(n),t.interactiveRefactorArguments);if(void 0===a)return{edits:[]};if(r){var{renameFilename:n,renameLocation:t,edits:r}=a;let e;return void 0!==n&&void 0!==t&&(i=i.getScriptInfoForNormalizedPath(r1e(n)),e=xve(KK(i.getSnapshot()),n,t,r)),{renameLocation:e,renameFilename:n,edits:this.mapTextChangesToCodeEdits(r),notApplicableReason:a.notApplicableReason}}return a}getMoveToRefactoringFileSuggestions(e){var{file:t,project:r}=this.getFileAndProject(e),n=r.getScriptInfoForNormalizedPath(t);return r.getLanguageService().getMoveToRefactoringFileSuggestions(t,this.extractPositionOrRange(e,n),this.getPreferences(t))}getPasteEdits(t){let{file:r,project:n}=this.getFileAndProject(t);var e=t.copiedFrom?{file:t.copiedFrom.file,range:t.copiedFrom.spans.map(e=>this.getRange({file:t.copiedFrom.file,startLine:e.start.line,startOffset:e.start.offset,endLine:e.end.line,endOffset:e.end.offset},n.getScriptInfoForNormalizedPath(r1e(t.copiedFrom.file))))}:void 0,e=n.getLanguageService().getPasteEdits({targetFile:r,pastedText:t.pastedText,pasteLocations:t.pasteLocations.map(e=>this.getRange({file:r,startLine:e.start.line,startOffset:e.start.offset,endLine:e.end.line,endOffset:e.end.offset},n.getScriptInfoForNormalizedPath(r))),copiedFrom:e,preferences:this.getPreferences(r)},this.getFormatOptions(r));return e&&this.mapPasteEditsAction(e)}organizeImports(e,t){Y4.assert("file"===e.scope.type);var{file:r,project:n}=this.getFileAndProject(e.scope.args),n=n.getLanguageService().organizeImports({fileName:r,mode:e.mode??(e.skipDestructiveCodeActions?"SortAndCombine":void 0),type:"file"},this.getFormatOptions(r),this.getPreferences(r));return t?this.mapTextChangesToCodeEdits(n):n}getEditsForFileRename(e,t){let i=r1e(e.oldFilePath),a=r1e(e.newFilePath),o=this.getHostFormatOptions(),s=this.getHostPreferences(),c=new Set,l=[];return this.projectService.loadAncestorProjectTree(),this.projectService.forEachEnabledProject(e=>{var t,r,n=[];for(t of e.getLanguageService().getEditsForFileRename(i,a,o,s))c.has(t.fileName)||(l.push(t),n.push(t.fileName));for(r of n)c.add(r)}),t?l.map(e=>this.mapTextChangeToCodeEdit(e)):l}getCodeFixes(r,e){var{file:n,project:i}=this.getFileAndProject(r),a=i.getScriptInfoForNormalizedPath(n);let{startPosition:o,endPosition:s}=this.getStartAndEndPosition(r,a),t;try{t=i.getLanguageService().getCodeFixesAtPosition(n,o,s,r.errorCodes,this.getFormatOptions(n),this.getPreferences(n))}catch(e){a=i.getLanguageService();let t=[...a.getSyntacticDiagnostics(n),...a.getSemanticDiagnostics(n),...a.getSuggestionDiagnostics(n)].map(e=>Go(o,s-o,e.start,e.length)&&e.code);i=r.errorCodes.find(e=>!t.includes(e));throw void 0!==i&&(e.message=`BADCLIENT: Bad error code, ${i} not found in range ${o}..${s} (found: ${t.join(", ")}); could have caused this error: -`+e.message),e}return e?t.map(e=>this.mapCodeFixAction(e)):t}getCombinedCodeFix({scope:e,fixId:t},r){Y4.assert("file"===e.type);var{file:e,project:n}=this.getFileAndProject(e.args),n=n.getLanguageService().getCombinedCodeFix({type:"file",fileName:e},t,this.getFormatOptions(e),this.getPreferences(e));return r?{changes:this.mapTextChangesToCodeEdits(n.changes),commands:n.commands}:n}applyCodeActionCommand(e){var t;for(t of se(e.command)){var{file:r,project:n}=this.getFileAndProject(t);n.getLanguageService().applyCodeActionCommand(t,this.getFormatOptions(r)).then(e=>{},e=>{})}return{}}getStartAndEndPosition(e,t){let r,n;return void 0!==e.startPosition?r=e.startPosition:(r=t.lineOffsetToPosition(e.startLine,e.startOffset),e.startPosition=r),void 0!==e.endPosition?n=e.endPosition:(n=t.lineOffsetToPosition(e.endLine,e.endOffset),e.endPosition=n),{startPosition:r,endPosition:n}}mapCodeAction({description:e,changes:t,commands:r}){return{description:e,changes:this.mapTextChangesToCodeEdits(t),commands:r}}mapCodeFixAction({fixName:e,description:t,changes:r,commands:n,fixId:i,fixAllDescription:a}){return{fixName:e,description:t,changes:this.mapTextChangesToCodeEdits(r),commands:n,fixId:i,fixAllDescription:a}}mapPasteEditsAction({edits:e,fixId:t}){return{edits:this.mapTextChangesToCodeEdits(e),fixId:t}}mapTextChangesToCodeEdits(e){return e.map(e=>this.mapTextChangeToCodeEdit(e))}mapTextChangeToCodeEdit(e){let r=this.projectService.getScriptInfoOrConfig(e.fileName);return!!e.isNewFile==!!r&&(r||this.projectService.logErrorForScriptInfoNotFound(e.fileName),Y4.fail("Expected isNewFile for (only) new files. "+JSON.stringify({isNewFile:!!e.isNewFile,hasScriptInfo:!!r}))),r?{fileName:e.fileName,textChanges:e.textChanges.map(e=>{return e=e,{start:bve(t=r,e.span.start),end:bve(t,J3(e.span)),newText:e.newText};var t})}:(e=e,Y4.assert(1===e.textChanges.length),t=WT(e.textChanges),Y4.assert(0===t.span.start&&0===t.span.length),{fileName:e.fileName,textChanges:[{start:{line:0,offset:0},end:{line:0,offset:0},newText:t.newText}]});var t}convertTextChangeToCodeEdit(e,t){return{start:t.positionToLineOffset(e.span.start),end:t.positionToLineOffset(e.span.start+e.span.length),newText:e.newText||""}}getBraceMatching(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e);let i=this.projectService.getScriptInfoForNormalizedPath(r);e=this.getPosition(e,i),n=n.getBraceMatchingAtPosition(r,e);return n?t?n.map(e=>yve(e,i)):n:void 0}getDiagnosticsForProject(e,r,n){if(!this.suppressDiagnosticEvents){var{fileNames:i,languageServiceDisabled:a}=this.getProjectInfoWorker(n,void 0,!0,!0);if(!a){a=i.filter(e=>!e.includes("lib.d.ts"));if(0!==a.length){var o,s=[],c=[],l=[],_=[],i=r1e(n);let t=this.projectService.ensureDefaultProjectForFile(i);for(o of a)(this.getCanonicalFileName(o)===this.getCanonicalFileName(n)?s:this.projectService.getScriptInfo(o).isScriptOpen()?c:x9(o)?_:l).push(o);i=[...s,...c,...l,..._].map(e=>({fileName:e,project:t}));this.updateErrorCheck(e,i,r,!1)}}}}configurePlugin(e){this.projectService.configurePlugin(e)}getSmartSelectionRange(e,t){var r=e["locations"];let{file:n,languageService:i}=this.getFileAndLanguageServiceForSyntacticOperation(e),a=Y4.checkDefined(this.projectService.getScriptInfo(n));return $4(r,e=>{e=this.getPosition(e,a),e=i.getSmartSelectionRange(n,e);return t?this.mapSelectionRange(e,a):e})}toggleLineComment(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e),i=this.projectService.getScriptInfo(r),e=this.getRange(e,i),i=n.toggleLineComment(r,e);if(t){let t=this.projectService.getScriptInfoForNormalizedPath(r);return i.map(e=>this.convertTextChangeToCodeEdit(e,t))}return i}toggleMultilineComment(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e),i=this.projectService.getScriptInfoForNormalizedPath(r),e=this.getRange(e,i),i=n.toggleMultilineComment(r,e);if(t){let t=this.projectService.getScriptInfoForNormalizedPath(r);return i.map(e=>this.convertTextChangeToCodeEdit(e,t))}return i}commentSelection(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e),i=this.projectService.getScriptInfoForNormalizedPath(r),e=this.getRange(e,i),i=n.commentSelection(r,e);if(t){let t=this.projectService.getScriptInfoForNormalizedPath(r);return i.map(e=>this.convertTextChangeToCodeEdit(e,t))}return i}uncommentSelection(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e),i=this.projectService.getScriptInfoForNormalizedPath(r),e=this.getRange(e,i),i=n.uncommentSelection(r,e);if(t){let t=this.projectService.getScriptInfoForNormalizedPath(r);return i.map(e=>this.convertTextChangeToCodeEdit(e,t))}return i}mapSelectionRange(e,t){var r={textSpan:yve(e.textSpan,t)};return e.parent&&(r.parent=this.mapSelectionRange(e.parent,t)),r}getScriptInfoFromProjectService(e){var e=r1e(e),t=this.projectService.getScriptInfoForNormalizedPath(e);return t||(this.projectService.logErrorForScriptInfoNotFound(e),Q0e.ThrowNoProject())}toProtocolCallHierarchyItem(e){var t=this.getScriptInfoFromProjectService(e.file);return{name:e.name,kind:e.kind,kindModifiers:e.kindModifiers,file:e.file,containerName:e.containerName,span:yve(e.span,t),selectionSpan:yve(e.selectionSpan,t)}}toProtocolCallHierarchyIncomingCall(e){let t=this.getScriptInfoFromProjectService(e.from.file);return{from:this.toProtocolCallHierarchyItem(e.from),fromSpans:e.fromSpans.map(e=>yve(e,t))}}toProtocolCallHierarchyOutgoingCall(e,t){return{to:this.toProtocolCallHierarchyItem(e.to),fromSpans:e.fromSpans.map(e=>yve(e,t))}}prepareCallHierarchy(e){var{file:t,project:r}=this.getFileAndProject(e),n=this.projectService.getScriptInfoForNormalizedPath(t);if(n)return e=this.getPosition(e,n),(n=r.getLanguageService().prepareCallHierarchy(t,e))&&tX(n,e=>this.toProtocolCallHierarchyItem(e))}provideCallHierarchyIncomingCalls(e){var{file:t,project:r}=this.getFileAndProject(e),n=this.getScriptInfoFromProjectService(t);return r.getLanguageService().provideCallHierarchyIncomingCalls(t,this.getPosition(e,n)).map(e=>this.toProtocolCallHierarchyIncomingCall(e))}provideCallHierarchyOutgoingCalls(e){var{file:t,project:r}=this.getFileAndProject(e);let n=this.getScriptInfoFromProjectService(t);return r.getLanguageService().provideCallHierarchyOutgoingCalls(t,this.getPosition(e,n)).map(e=>this.toProtocolCallHierarchyOutgoingCall(e,n))}getCanonicalFileName(e){return ua(this.host.useCaseSensitiveFileNames?e:br(e))}exit(){}notRequired(){return{responseRequired:!1}}requiredResponse(e){return{response:e,responseRequired:!0}}addProtocolHandler(e,t){if(this.handlers.has(e))throw new Error(`Protocol handler already exists for command "${e}"`);this.handlers.set(e,t)}setCurrentRequest(e){Y4.assert(void 0===this.currentRequestId),this.currentRequestId=e,this.cancellationToken.setRequest(e)}resetCurrentRequest(e){Y4.assert(this.currentRequestId===e),this.currentRequestId=void 0,this.cancellationToken.resetRequest(e)}executeWithRequestId(e,t){try{return this.setCurrentRequest(e),t()}finally{this.resetCurrentRequest(e)}}executeCommand(e){let t=this.handlers.get(e.command);var r;return t?(r=this.executeWithRequestId(e.seq,()=>t(e)),this.projectService.enableRequestedPlugins(),r):(this.logger.msg("Unrecognized JSON command:"+uW(e),"Err"),this.doOutput(void 0,"unknown",e.seq,!1,"Unrecognized JSON command: "+e.command),{responseRequired:!1})}onMessage(t){var e;this.gcTimer.scheduleCollect(),this.performanceData=void 0;let r;this.logger.hasLevel(2)&&(r=this.hrtime(),this.logger.hasLevel(3))&&this.logger.info("request:"+_W(this.toStringMessage(t)));let n,i;try{n=this.parseMessage(t),i=n.arguments&&n.arguments.file?n.arguments:void 0,null!=Z4&&Z4.instant(Z4.Phase.Session,"request",{seq:n.seq,command:n.command}),null!=er&&er.logStartCommand(""+n.command,this.toStringMessage(t).substring(0,100)),null!=Z4&&Z4.push(Z4.Phase.Session,"executeCommand",{seq:n.seq,command:n.command},!0);var a,{response:o,responseRequired:s}=this.executeCommand(n);null!=Z4&&Z4.pop(),this.logger.hasLevel(2)&&(a=((1e9*(e=this.hrtime(r))[0]+e[1])/1e6).toFixed(4),s?this.logger.perftrc(`${n.seq}::${n.command}: elapsed time (in milliseconds) `+a):this.logger.perftrc(`${n.seq}::${n.command}: async elapsed time (in milliseconds) `+a)),null!=er&&er.logStopCommand(""+n.command,"Success"),null!=Z4&&Z4.instant(Z4.Phase.Session,"response",{seq:n.seq,command:n.command,success:!!o}),o?this.doOutput(o,n.command,n.seq,!0):s&&this.doOutput(void 0,n.command,n.seq,!1,"No content available.")}catch(e){null!=Z4&&Z4.popAll(),e instanceof Vr?(null!=er&&er.logStopCommand(""+(n&&n.command),"Canceled: "+e),null!=Z4&&Z4.instant(Z4.Phase.Session,"commandCanceled",{seq:null==n?void 0:n.seq,command:null==n?void 0:n.command}),this.doOutput({canceled:!0},n.command,n.seq,!0)):(this.logErrorWorker(e,this.toStringMessage(t),i),null!=er&&er.logStopCommand(""+(n&&n.command),"Error: "+e),null!=Z4&&Z4.instant(Z4.Phase.Session,"commandError",{seq:null==n?void 0:n.seq,command:null==n?void 0:n.command,message:e.message}),this.doOutput(void 0,n?n.command:"unknown",n?n.seq:0,!1,"Error processing request. "+e.message+"\n"+e.stack))}}parseMessage(e){return JSON.parse(e)}toStringMessage(e){return e}getFormatOptions(e){return this.projectService.getFormatCodeOptions(e)}getPreferences(e){return this.projectService.getPreferences(e)}getHostFormatOptions(){return this.projectService.getHostFormatCodeOptions()}getHostPreferences(){return this.projectService.getHostPreferences()}};function yve(e,t){return{start:t.positionToLineOffset(e.start),end:t.positionToLineOffset(J3(e))}}function vve(e,t,r){e=yve(e,r),t=t&&yve(t,r);return t?{...e,contextStart:t.start,contextEnd:t.end}:e}function bve(e,t){return Kye(e)?{line:(r=e.getLineAndCharacterOfPosition(t)).line+1,offset:r.character+1}:e.positionToLineOffset(t);var r}function xve(e,t,r,n){var{line:e,character:t}=no(Za(function(t,e,r){for(var{fileName:n,textChanges:i}of r)if(n===e)for(let e=i.length-1;0<=e;e--){var{newText:a,span:{start:o,length:s}}=i[e];t=t.slice(0,o)+a+t.slice(o+s)}return t}(e,t,n)),r);return{line:e+1,offset:t+1}}function Sve(e,{fileName:t,textSpan:r,contextSpan:n,isWriteAccess:i,isDefinition:a},{disableLineTextInReferences:o}){e=Y4.checkDefined(e.getScriptInfo(t)),r=vve(r,n,e),n=o?void 0:function(e,t){t=e.lineToTextSpan(t.start.line-1);return e.getSnapshot().getText(t.start,J3(t)).replace(/\r|\n/g,"")}(e,r);return{file:t,...r,lineText:n,isWriteAccess:i,isDefinition:a}}function kve(e){return void 0===e||e&&"object"==typeof e&&"string"==typeof e.exportName&&(void 0===e.fileName||"string"==typeof e.fileName)&&(void 0===e.ambientModuleName||"string"==typeof e.ambientModuleName&&(void 0===e.isPackageJsonImport||"boolean"==typeof e.isPackageJsonImport))}var Tve=(e=>(e[e.PreStart=0]="PreStart",e[e.Start=1]="Start",e[e.Entire=2]="Entire",e[e.Mid=3]="Mid",e[e.End=4]="End",e[e.PostEnd=5]="PostEnd",e))(Tve||{}),Cve=class{constructor(){this.goSubtree=!0,this.lineIndex=new Eve,this.endBranch=[],this.state=2,this.initialText="",this.trailingText="",this.lineIndex.root=new Fve,this.startPath=[this.lineIndex.root],this.stack=[this.lineIndex.root]}get done(){return!1}insertLines(e,i){i&&(this.trailingText=""),e=e?this.initialText+e+this.trailingText:this.initialText+this.trailingText;var a=Eve.linesFromText(e).lines;1this.currentVersion))return e%Nve.maxVersions}currentVersionToIndex(){return this.currentVersion%Nve.maxVersions}edit(e,t,r){this.changes.push(new wve(e,t,r)),(this.changes.length>Nve.changeNumberThreshold||t>Nve.changeLengthThreshold||r&&r.length>Nve.changeLengthThreshold)&&this.getSnapshot()}getSnapshot(){return this._getSnapshot()}_getSnapshot(){let t=this.versions[this.currentVersionToIndex()];if(0=Nve.maxVersions&&(this.minVersion=this.currentVersion-Nve.maxVersions+1)}return t}getSnapshotVersion(){return this._getSnapshot().version}getAbsolutePositionAndLineText(e){return this._getSnapshot().index.lineNumberToInfo(e)}lineOffsetToPosition(e,t){return this._getSnapshot().index.absolutePositionOfStartOfLine(e)+(t-1)}positionToLineOffset(e){return this._getSnapshot().index.positionToLineOffset(e)}lineToTextSpan(e){var t=this._getSnapshot().index,{lineText:r,absolutePosition:n}=t.lineNumberToInfo(e+1);return Qo(n,void 0!==r?r.length:t.absolutePositionOfStartOfLine(e+2)-n)}getTextChangesBetweenVersions(t,r){if(!(t=this.minVersion){var n,i=[];for(let e=t+1;e<=r;e++)for(n of this.versions[this.versionToIndex(e)].changesSincePreviousVersion)i.push(n.getTextChangeRange());return ns(i)}}getLineCount(){return this._getSnapshot().index.getLineCount()}static fromString(e){var t=new Nve,r=new Pve(0,t,new Eve),e=(t.versions[t.currentVersion]=r,Eve.linesFromText(e));return r.index.load(e.lines),t}},Dve=(Nve.changeNumberThreshold=8,Nve.changeLengthThreshold=256,Nve.maxVersions=8,Nve),Pve=class Kve{constructor(e,t,r,n=Z0e){this.version=e,this.cache=t,this.index=r,this.changesSincePreviousVersion=n}getText(e,t){return this.index.getText(e,t-e)}getLength(){return this.index.getLength()}getChangeRange(e){if(e instanceof Kve&&this.cache===e.cache)return this.version<=e.version?rs:this.cache.getTextChangesBetweenVersions(e.version,this.version)}},Eve=class Gve{constructor(){this.checkEdits=!1}absolutePositionOfStartOfLine(e){return this.lineNumberToInfo(e).absolutePosition}positionToLineOffset(e){var{oneBasedLine:e,zeroBasedColumn:t}=this.root.charOffsetToLineInfo(1,e);return{line:e,offset:t+1}}positionToColumnAndLineText(e){return this.root.charOffsetToLineInfo(1,e)}getLineCount(){return this.root.lineCount()}lineNumberToInfo(e){var t;return e<=this.getLineCount()?({position:e,leaf:t}=this.root.lineNumberToInfo(e,0),{absolutePosition:e,lineText:t&&t.text}):{absolutePosition:this.root.charCount(),lineText:void 0}}load(t){if(0{n=n.concat(r.text.substring(e,e+t))}}),n}getLength(){return this.root.charCount()}every(n,e,t){t=t||this.root.charCount();var r={goSubtree:!0,done:!1,leaf(e,t,r){n(r,e,t)||(this.done=!0)}};return this.walk(e,t-e,r),!r.done}edit(r,n,i){if(0!==this.root.charCount()){let e;this.checkEdits&&(s=this.getText(0,this.root.charCount()),e=s.slice(0,r)+i+s.slice(r+n));var a,o,s=new Cve;let t=!1;return r>=this.root.charCount()?(r=this.root.charCount()-1,o=this.getText(r,1),i=i?o+i:o,n=0,t=!0):0=a;)this.skipChild(o,r,i,n,0),o-=a,i++,a=this.children[i].charCount();if(o+r<=a){if(this.execWalk(o,r,n,i,2))return}else{if(this.execWalk(o,a-o,n,i,1))return;let e=r-(a-o);i++;t=this.children[i];for(a=t.charCount();e>a;){if(this.execWalk(0,a,n,i,3))return;e-=a,i++,a=this.children[i].charCount()}if(0t)return r.isLeaf()?{oneBasedLine:e,zeroBasedColumn:t,lineText:r.text}:r.charOffsetToLineInfo(e,t);t-=r.charCount(),e+=r.lineCount()}var n=this.lineCount();return 0===n?{oneBasedLine:1,zeroBasedColumn:0,lineText:void 0}:{oneBasedLine:n,zeroBasedColumn:Y4.checkDefined(this.lineNumberToInfo(n,0).leaf).charCount(),lineText:void 0}}lineNumberToInfo(e,t){for(var r of this.children){var n=r.lineCount();if(e<=n)return r.isLeaf()?{position:t,leaf:r}:r.lineNumberToInfo(e,t);e-=n,t+=r.charCount()}return{position:t,leaf:void 0}}splitAfter(e){let t;var r=this.children.length,n=++e;if(e{(this.packageInstalledPromise??(this.packageInstalledPromise=new Map)).set(this.packageInstallId,{resolve:e,reject:t})});return this.installer.send(e),t}attach(e){this.projectService=e,this.installer=this.createInstallerProcess()}onProjectClosed(e){this.installer.send({projectName:e.getProjectName(),kind:"closeProject"})}enqueueInstallTypingsRequest(e,t,r){e=t1e(e,t,r);this.logger.hasLevel(3)&&this.logger.info("TIAdapter:: Scheduling throttled operation:"+uW(e)),this.activeRequestCount{this.logger.hasLevel(3)&&this.logger.info("TIAdapter:: Sending request:"+uW(e)),this.installer.send(e)},Ive.requestDelayMillis,e.projectName+"::"+e.kind)}},Ove=(Ive.requestDelayMillis=100,Ive),Lve={};r(Lve,{ActionInvalidate:()=>ZV,ActionPackageInstalled:()=>eW,ActionSet:()=>YV,ActionWatchTypingLocations:()=>aW,Arguments:()=>XV,AutoImportProviderProject:()=>q1e,AuxiliaryProject:()=>J1e,CharRangeSection:()=>Tve,CloseFileWatcherEvent:()=>cye,CommandNames:()=>nve,ConfigFileDiagEvent:()=>rye,ConfiguredProject:()=>U1e,ConfiguredProjectLoadKind:()=>Dye,CreateDirectoryWatcherEvent:()=>sye,CreateFileWatcherEvent:()=>oye,Errors:()=>Q0e,EventBeginInstallTypes:()=>rW,EventEndInstallTypes:()=>nW,EventInitializationFailed:()=>iW,EventTypesRegistry:()=>tW,ExternalProject:()=>V1e,GcTimer:()=>d1e,InferredProject:()=>B1e,LargeFileReferencedEvent:()=>tye,LineIndex:()=>Eve,LineLeaf:()=>Ave,LineNode:()=>Fve,LogLevel:()=>Y0e,Msg:()=>e1e,OpenFileInfoTelemetryEvent:()=>aye,Project:()=>M1e,ProjectInfoTelemetryEvent:()=>iye,ProjectKind:()=>A1e,ProjectLanguageServiceStateEvent:()=>nye,ProjectLoadingFinishEvent:()=>eye,ProjectLoadingStartEvent:()=>Z1e,ProjectService:()=>Hye,ProjectsUpdatedInBackgroundEvent:()=>Y1e,ScriptInfo:()=>D1e,ScriptVersionCache:()=>Dve,Session:()=>hve,TextStorage:()=>w1e,ThrottledOperations:()=>u1e,TypingsCache:()=>F1e,TypingsInstallerAdapter:()=>Ove,allFilesAreJsOrDts:()=>L1e,allRootFilesAreJsOrDts:()=>O1e,asNormalizedPath:()=>i1e,convertCompilerOptions:()=>gye,convertFormatOptions:()=>mye,convertScriptKindName:()=>bye,convertTypeAcquisition:()=>yye,convertUserPreferences:()=>xye,convertWatchOptions:()=>hye,countEachFileTypes:()=>I1e,createInstallTypingsRequest:()=>t1e,createModuleSpecifierCache:()=>$ye,createNormalizedPathMap:()=>a1e,createPackageJsonCache:()=>Xye,createSortedArray:()=>_1e,emptyArray:()=>Z0e,findArgument:()=>sW,forEachResolvedProjectReferenceProject:()=>Pye,formatDiagnosticToProtocol:()=>rve,formatMessage:()=>ive,getBaseConfigFileName:()=>p1e,getLocationInNewDocument:()=>xve,hasArgument:()=>oW,hasNoTypeScriptSource:()=>j1e,indent:()=>_W,isBackgroundProject:()=>G1e,isConfigFile:()=>Kye,isConfiguredProject:()=>H1e,isDynamicFileName:()=>N1e,isExternalProject:()=>K1e,isInferredProject:()=>W1e,isInferredProjectName:()=>o1e,isProjectDeferredClose:()=>$1e,makeAutoImportProviderProjectName:()=>c1e,makeAuxiliaryProjectName:()=>l1e,makeInferredProjectName:()=>s1e,maxFileSize:()=>Q1e,maxProgramSizeForNonTsFiles:()=>X1e,normalizedPathToPath:()=>n1e,nowString:()=>cW,nullCancellationToken:()=>Qye,nullTypingsInstaller:()=>P1e,protocol:()=>m1e,removeSorted:()=>f1e,stringifyIndented:()=>uW,toEvent:()=>ove,toNormalizedPath:()=>r1e,tryConvertScriptKindName:()=>vye,typingsInstaller:()=>W0e,updateProjectIfDirty:()=>jye}),"undefined"!=typeof console&&(Y4.loggingHost={log(e,t){switch(e){case 1:return console.error(t);case 2:return console.warn(t);case 3:case 4:return console.log(t)}}})}.call(this)}.call(this,t2e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},t2e("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/node_modules/typescript/lib/typescript.js","/node_modules/typescript/lib")},{_process:46,buffer:1,crypto:1,fs:1,inspector:1,os:1,path:1,perf_hooks:1,"source-map-support":1}],48:[function(e,t,r){Object.defineProperty(r,"__esModule",{value:!0});let w=e("core-types-json-schema"),N=e("core-types-ts/dist/lib/ts-to-core-types"),g=e("core-types-ts"),D=e("./utils/sharedUtils"),P=e("./utils/constants"),E=e("./utils/nosqlUtils");Draw.loadPlugin(function(v){var e=document.createElement("div");e.style.userSelect="none",e.style.overflow="hidden",e.style.padding="10px",e.style.height="100%";let i=document.createElement("textarea"),t=(i.style.height="200px",i.style.width="100%","-- click a nosql type button");i.value=t,mxUtils.br(e),e.appendChild(i);var r=v.menus.get("exportAs");let n="tonosql=To NoSQL",a=(r&&!window.VsCodeApi||(n="tonosql=Export As NoSQL"),mxResources.parse(n),new mxWindow(mxResources.get("tonosql"),e,document.body.offsetWidth-480,140,320,320,!0,!0));function o(e){var t,r=(0,D.getMermaidDiagramDb)(v,e),r=(0,E.dbToOpenApi)(r);let n="";"ts"==e?(t=(0,w.convertOpenApiToCoreTypes)(r)["data"],t=(0,g.convertCoreTypesToTypeScript)(t)["data"],n=`/* +`+e.message),e}return e?t.map(e=>this.mapCodeFixAction(e)):t}getCombinedCodeFix({scope:e,fixId:t},r){Y4.assert("file"===e.type);var{file:e,project:n}=this.getFileAndProject(e.args),n=n.getLanguageService().getCombinedCodeFix({type:"file",fileName:e},t,this.getFormatOptions(e),this.getPreferences(e));return r?{changes:this.mapTextChangesToCodeEdits(n.changes),commands:n.commands}:n}applyCodeActionCommand(e){var t;for(t of se(e.command)){var{file:r,project:n}=this.getFileAndProject(t);n.getLanguageService().applyCodeActionCommand(t,this.getFormatOptions(r)).then(e=>{},e=>{})}return{}}getStartAndEndPosition(e,t){let r,n;return void 0!==e.startPosition?r=e.startPosition:(r=t.lineOffsetToPosition(e.startLine,e.startOffset),e.startPosition=r),void 0!==e.endPosition?n=e.endPosition:(n=t.lineOffsetToPosition(e.endLine,e.endOffset),e.endPosition=n),{startPosition:r,endPosition:n}}mapCodeAction({description:e,changes:t,commands:r}){return{description:e,changes:this.mapTextChangesToCodeEdits(t),commands:r}}mapCodeFixAction({fixName:e,description:t,changes:r,commands:n,fixId:i,fixAllDescription:a}){return{fixName:e,description:t,changes:this.mapTextChangesToCodeEdits(r),commands:n,fixId:i,fixAllDescription:a}}mapPasteEditsAction({edits:e,fixId:t}){return{edits:this.mapTextChangesToCodeEdits(e),fixId:t}}mapTextChangesToCodeEdits(e){return e.map(e=>this.mapTextChangeToCodeEdit(e))}mapTextChangeToCodeEdit(e){let r=this.projectService.getScriptInfoOrConfig(e.fileName);return!!e.isNewFile==!!r&&(r||this.projectService.logErrorForScriptInfoNotFound(e.fileName),Y4.fail("Expected isNewFile for (only) new files. "+JSON.stringify({isNewFile:!!e.isNewFile,hasScriptInfo:!!r}))),r?{fileName:e.fileName,textChanges:e.textChanges.map(e=>{return e=e,{start:bve(t=r,e.span.start),end:bve(t,J3(e.span)),newText:e.newText};var t})}:(e=e,Y4.assert(1===e.textChanges.length),t=WT(e.textChanges),Y4.assert(0===t.span.start&&0===t.span.length),{fileName:e.fileName,textChanges:[{start:{line:0,offset:0},end:{line:0,offset:0},newText:t.newText}]});var t}convertTextChangeToCodeEdit(e,t){return{start:t.positionToLineOffset(e.span.start),end:t.positionToLineOffset(e.span.start+e.span.length),newText:e.newText||""}}getBraceMatching(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e);let i=this.projectService.getScriptInfoForNormalizedPath(r);e=this.getPosition(e,i),n=n.getBraceMatchingAtPosition(r,e);return n?t?n.map(e=>yve(e,i)):n:void 0}getDiagnosticsForProject(e,r,n){if(!this.suppressDiagnosticEvents){var{fileNames:i,languageServiceDisabled:a}=this.getProjectInfoWorker(n,void 0,!0,!0);if(!a){a=i.filter(e=>!e.includes("lib.d.ts"));if(0!==a.length){var o,s=[],c=[],l=[],_=[],i=r1e(n);let t=this.projectService.ensureDefaultProjectForFile(i);for(o of a)(this.getCanonicalFileName(o)===this.getCanonicalFileName(n)?s:this.projectService.getScriptInfo(o).isScriptOpen()?c:x9(o)?_:l).push(o);i=[...s,...c,...l,..._].map(e=>({fileName:e,project:t}));this.updateErrorCheck(e,i,r,!1)}}}}configurePlugin(e){this.projectService.configurePlugin(e)}getSmartSelectionRange(e,t){var r=e["locations"];let{file:n,languageService:i}=this.getFileAndLanguageServiceForSyntacticOperation(e),a=Y4.checkDefined(this.projectService.getScriptInfo(n));return $4(r,e=>{e=this.getPosition(e,a),e=i.getSmartSelectionRange(n,e);return t?this.mapSelectionRange(e,a):e})}toggleLineComment(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e),i=this.projectService.getScriptInfo(r),e=this.getRange(e,i),i=n.toggleLineComment(r,e);if(t){let t=this.projectService.getScriptInfoForNormalizedPath(r);return i.map(e=>this.convertTextChangeToCodeEdit(e,t))}return i}toggleMultilineComment(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e),i=this.projectService.getScriptInfoForNormalizedPath(r),e=this.getRange(e,i),i=n.toggleMultilineComment(r,e);if(t){let t=this.projectService.getScriptInfoForNormalizedPath(r);return i.map(e=>this.convertTextChangeToCodeEdit(e,t))}return i}commentSelection(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e),i=this.projectService.getScriptInfoForNormalizedPath(r),e=this.getRange(e,i),i=n.commentSelection(r,e);if(t){let t=this.projectService.getScriptInfoForNormalizedPath(r);return i.map(e=>this.convertTextChangeToCodeEdit(e,t))}return i}uncommentSelection(e,t){var{file:r,languageService:n}=this.getFileAndLanguageServiceForSyntacticOperation(e),i=this.projectService.getScriptInfoForNormalizedPath(r),e=this.getRange(e,i),i=n.uncommentSelection(r,e);if(t){let t=this.projectService.getScriptInfoForNormalizedPath(r);return i.map(e=>this.convertTextChangeToCodeEdit(e,t))}return i}mapSelectionRange(e,t){var r={textSpan:yve(e.textSpan,t)};return e.parent&&(r.parent=this.mapSelectionRange(e.parent,t)),r}getScriptInfoFromProjectService(e){var e=r1e(e),t=this.projectService.getScriptInfoForNormalizedPath(e);return t||(this.projectService.logErrorForScriptInfoNotFound(e),Q0e.ThrowNoProject())}toProtocolCallHierarchyItem(e){var t=this.getScriptInfoFromProjectService(e.file);return{name:e.name,kind:e.kind,kindModifiers:e.kindModifiers,file:e.file,containerName:e.containerName,span:yve(e.span,t),selectionSpan:yve(e.selectionSpan,t)}}toProtocolCallHierarchyIncomingCall(e){let t=this.getScriptInfoFromProjectService(e.from.file);return{from:this.toProtocolCallHierarchyItem(e.from),fromSpans:e.fromSpans.map(e=>yve(e,t))}}toProtocolCallHierarchyOutgoingCall(e,t){return{to:this.toProtocolCallHierarchyItem(e.to),fromSpans:e.fromSpans.map(e=>yve(e,t))}}prepareCallHierarchy(e){var{file:t,project:r}=this.getFileAndProject(e),n=this.projectService.getScriptInfoForNormalizedPath(t);if(n)return e=this.getPosition(e,n),(n=r.getLanguageService().prepareCallHierarchy(t,e))&&tX(n,e=>this.toProtocolCallHierarchyItem(e))}provideCallHierarchyIncomingCalls(e){var{file:t,project:r}=this.getFileAndProject(e),n=this.getScriptInfoFromProjectService(t);return r.getLanguageService().provideCallHierarchyIncomingCalls(t,this.getPosition(e,n)).map(e=>this.toProtocolCallHierarchyIncomingCall(e))}provideCallHierarchyOutgoingCalls(e){var{file:t,project:r}=this.getFileAndProject(e);let n=this.getScriptInfoFromProjectService(t);return r.getLanguageService().provideCallHierarchyOutgoingCalls(t,this.getPosition(e,n)).map(e=>this.toProtocolCallHierarchyOutgoingCall(e,n))}getCanonicalFileName(e){return ua(this.host.useCaseSensitiveFileNames?e:br(e))}exit(){}notRequired(){return{responseRequired:!1}}requiredResponse(e){return{response:e,responseRequired:!0}}addProtocolHandler(e,t){if(this.handlers.has(e))throw new Error(`Protocol handler already exists for command "${e}"`);this.handlers.set(e,t)}setCurrentRequest(e){Y4.assert(void 0===this.currentRequestId),this.currentRequestId=e,this.cancellationToken.setRequest(e)}resetCurrentRequest(e){Y4.assert(this.currentRequestId===e),this.currentRequestId=void 0,this.cancellationToken.resetRequest(e)}executeWithRequestId(e,t){try{return this.setCurrentRequest(e),t()}finally{this.resetCurrentRequest(e)}}executeCommand(e){let t=this.handlers.get(e.command);var r;return t?(r=this.executeWithRequestId(e.seq,()=>t(e)),this.projectService.enableRequestedPlugins(),r):(this.logger.msg("Unrecognized JSON command:"+uW(e),"Err"),this.doOutput(void 0,"unknown",e.seq,!1,"Unrecognized JSON command: "+e.command),{responseRequired:!1})}onMessage(t){var e;this.gcTimer.scheduleCollect(),this.performanceData=void 0;let r;this.logger.hasLevel(2)&&(r=this.hrtime(),this.logger.hasLevel(3))&&this.logger.info("request:"+_W(this.toStringMessage(t)));let n,i;try{n=this.parseMessage(t),i=n.arguments&&n.arguments.file?n.arguments:void 0,null!=Z4&&Z4.instant(Z4.Phase.Session,"request",{seq:n.seq,command:n.command}),null!=er&&er.logStartCommand(""+n.command,this.toStringMessage(t).substring(0,100)),null!=Z4&&Z4.push(Z4.Phase.Session,"executeCommand",{seq:n.seq,command:n.command},!0);var a,{response:o,responseRequired:s}=this.executeCommand(n);null!=Z4&&Z4.pop(),this.logger.hasLevel(2)&&(a=((1e9*(e=this.hrtime(r))[0]+e[1])/1e6).toFixed(4),s?this.logger.perftrc(`${n.seq}::${n.command}: elapsed time (in milliseconds) `+a):this.logger.perftrc(`${n.seq}::${n.command}: async elapsed time (in milliseconds) `+a)),null!=er&&er.logStopCommand(""+n.command,"Success"),null!=Z4&&Z4.instant(Z4.Phase.Session,"response",{seq:n.seq,command:n.command,success:!!o}),o?this.doOutput(o,n.command,n.seq,!0):s&&this.doOutput(void 0,n.command,n.seq,!1,"No content available.")}catch(e){null!=Z4&&Z4.popAll(),e instanceof Vr?(null!=er&&er.logStopCommand(""+(n&&n.command),"Canceled: "+e),null!=Z4&&Z4.instant(Z4.Phase.Session,"commandCanceled",{seq:null==n?void 0:n.seq,command:null==n?void 0:n.command}),this.doOutput({canceled:!0},n.command,n.seq,!0)):(this.logErrorWorker(e,this.toStringMessage(t),i),null!=er&&er.logStopCommand(""+(n&&n.command),"Error: "+e),null!=Z4&&Z4.instant(Z4.Phase.Session,"commandError",{seq:null==n?void 0:n.seq,command:null==n?void 0:n.command,message:e.message}),this.doOutput(void 0,n?n.command:"unknown",n?n.seq:0,!1,"Error processing request. "+e.message+"\n"+e.stack))}}parseMessage(e){return JSON.parse(e)}toStringMessage(e){return e}getFormatOptions(e){return this.projectService.getFormatCodeOptions(e)}getPreferences(e){return this.projectService.getPreferences(e)}getHostFormatOptions(){return this.projectService.getHostFormatCodeOptions()}getHostPreferences(){return this.projectService.getHostPreferences()}};function yve(e,t){return{start:t.positionToLineOffset(e.start),end:t.positionToLineOffset(J3(e))}}function vve(e,t,r){e=yve(e,r),t=t&&yve(t,r);return t?{...e,contextStart:t.start,contextEnd:t.end}:e}function bve(e,t){return Kye(e)?{line:(r=e.getLineAndCharacterOfPosition(t)).line+1,offset:r.character+1}:e.positionToLineOffset(t);var r}function xve(e,t,r,n){var{line:e,character:t}=no(Za(function(t,e,r){for(var{fileName:n,textChanges:i}of r)if(n===e)for(let e=i.length-1;0<=e;e--){var{newText:a,span:{start:o,length:s}}=i[e];t=t.slice(0,o)+a+t.slice(o+s)}return t}(e,t,n)),r);return{line:e+1,offset:t+1}}function Sve(e,{fileName:t,textSpan:r,contextSpan:n,isWriteAccess:i,isDefinition:a},{disableLineTextInReferences:o}){e=Y4.checkDefined(e.getScriptInfo(t)),r=vve(r,n,e),n=o?void 0:function(e,t){t=e.lineToTextSpan(t.start.line-1);return e.getSnapshot().getText(t.start,J3(t)).replace(/\r|\n/g,"")}(e,r);return{file:t,...r,lineText:n,isWriteAccess:i,isDefinition:a}}function kve(e){return void 0===e||e&&"object"==typeof e&&"string"==typeof e.exportName&&(void 0===e.fileName||"string"==typeof e.fileName)&&(void 0===e.ambientModuleName||"string"==typeof e.ambientModuleName&&(void 0===e.isPackageJsonImport||"boolean"==typeof e.isPackageJsonImport))}var Tve=(e=>(e[e.PreStart=0]="PreStart",e[e.Start=1]="Start",e[e.Entire=2]="Entire",e[e.Mid=3]="Mid",e[e.End=4]="End",e[e.PostEnd=5]="PostEnd",e))(Tve||{}),Cve=class{constructor(){this.goSubtree=!0,this.lineIndex=new Eve,this.endBranch=[],this.state=2,this.initialText="",this.trailingText="",this.lineIndex.root=new Fve,this.startPath=[this.lineIndex.root],this.stack=[this.lineIndex.root]}get done(){return!1}insertLines(e,i){i&&(this.trailingText=""),e=e?this.initialText+e+this.trailingText:this.initialText+this.trailingText;var a=Eve.linesFromText(e).lines;1this.currentVersion))return e%Nve.maxVersions}currentVersionToIndex(){return this.currentVersion%Nve.maxVersions}edit(e,t,r){this.changes.push(new wve(e,t,r)),(this.changes.length>Nve.changeNumberThreshold||t>Nve.changeLengthThreshold||r&&r.length>Nve.changeLengthThreshold)&&this.getSnapshot()}getSnapshot(){return this._getSnapshot()}_getSnapshot(){let t=this.versions[this.currentVersionToIndex()];if(0=Nve.maxVersions&&(this.minVersion=this.currentVersion-Nve.maxVersions+1)}return t}getSnapshotVersion(){return this._getSnapshot().version}getAbsolutePositionAndLineText(e){return this._getSnapshot().index.lineNumberToInfo(e)}lineOffsetToPosition(e,t){return this._getSnapshot().index.absolutePositionOfStartOfLine(e)+(t-1)}positionToLineOffset(e){return this._getSnapshot().index.positionToLineOffset(e)}lineToTextSpan(e){var t=this._getSnapshot().index,{lineText:r,absolutePosition:n}=t.lineNumberToInfo(e+1);return Qo(n,void 0!==r?r.length:t.absolutePositionOfStartOfLine(e+2)-n)}getTextChangesBetweenVersions(t,r){if(!(t=this.minVersion){var n,i=[];for(let e=t+1;e<=r;e++)for(n of this.versions[this.versionToIndex(e)].changesSincePreviousVersion)i.push(n.getTextChangeRange());return ns(i)}}getLineCount(){return this._getSnapshot().index.getLineCount()}static fromString(e){var t=new Nve,r=new Pve(0,t,new Eve),e=(t.versions[t.currentVersion]=r,Eve.linesFromText(e));return r.index.load(e.lines),t}},Dve=(Nve.changeNumberThreshold=8,Nve.changeLengthThreshold=256,Nve.maxVersions=8,Nve),Pve=class Kve{constructor(e,t,r,n=Z0e){this.version=e,this.cache=t,this.index=r,this.changesSincePreviousVersion=n}getText(e,t){return this.index.getText(e,t-e)}getLength(){return this.index.getLength()}getChangeRange(e){if(e instanceof Kve&&this.cache===e.cache)return this.version<=e.version?rs:this.cache.getTextChangesBetweenVersions(e.version,this.version)}},Eve=class Gve{constructor(){this.checkEdits=!1}absolutePositionOfStartOfLine(e){return this.lineNumberToInfo(e).absolutePosition}positionToLineOffset(e){var{oneBasedLine:e,zeroBasedColumn:t}=this.root.charOffsetToLineInfo(1,e);return{line:e,offset:t+1}}positionToColumnAndLineText(e){return this.root.charOffsetToLineInfo(1,e)}getLineCount(){return this.root.lineCount()}lineNumberToInfo(e){var t;return e<=this.getLineCount()?({position:e,leaf:t}=this.root.lineNumberToInfo(e,0),{absolutePosition:e,lineText:t&&t.text}):{absolutePosition:this.root.charCount(),lineText:void 0}}load(t){if(0{n=n.concat(r.text.substring(e,e+t))}}),n}getLength(){return this.root.charCount()}every(n,e,t){t=t||this.root.charCount();var r={goSubtree:!0,done:!1,leaf(e,t,r){n(r,e,t)||(this.done=!0)}};return this.walk(e,t-e,r),!r.done}edit(r,n,i){if(0!==this.root.charCount()){let e;this.checkEdits&&(s=this.getText(0,this.root.charCount()),e=s.slice(0,r)+i+s.slice(r+n));var a,o,s=new Cve;let t=!1;return r>=this.root.charCount()?(r=this.root.charCount()-1,o=this.getText(r,1),i=i?o+i:o,n=0,t=!0):0=a;)this.skipChild(o,r,i,n,0),o-=a,i++,a=this.children[i].charCount();if(o+r<=a){if(this.execWalk(o,r,n,i,2))return}else{if(this.execWalk(o,a-o,n,i,1))return;let e=r-(a-o);i++;t=this.children[i];for(a=t.charCount();e>a;){if(this.execWalk(0,a,n,i,3))return;e-=a,i++,a=this.children[i].charCount()}if(0t)return r.isLeaf()?{oneBasedLine:e,zeroBasedColumn:t,lineText:r.text}:r.charOffsetToLineInfo(e,t);t-=r.charCount(),e+=r.lineCount()}var n=this.lineCount();return 0===n?{oneBasedLine:1,zeroBasedColumn:0,lineText:void 0}:{oneBasedLine:n,zeroBasedColumn:Y4.checkDefined(this.lineNumberToInfo(n,0).leaf).charCount(),lineText:void 0}}lineNumberToInfo(e,t){for(var r of this.children){var n=r.lineCount();if(e<=n)return r.isLeaf()?{position:t,leaf:r}:r.lineNumberToInfo(e,t);e-=n,t+=r.charCount()}return{position:t,leaf:void 0}}splitAfter(e){let t;var r=this.children.length,n=++e;if(e{(this.packageInstalledPromise??(this.packageInstalledPromise=new Map)).set(this.packageInstallId,{resolve:e,reject:t})});return this.installer.send(e),t}attach(e){this.projectService=e,this.installer=this.createInstallerProcess()}onProjectClosed(e){this.installer.send({projectName:e.getProjectName(),kind:"closeProject"})}enqueueInstallTypingsRequest(e,t,r){e=t1e(e,t,r);this.logger.hasLevel(3)&&this.logger.info("TIAdapter:: Scheduling throttled operation:"+uW(e)),this.activeRequestCount{this.logger.hasLevel(3)&&this.logger.info("TIAdapter:: Sending request:"+uW(e)),this.installer.send(e)},Ive.requestDelayMillis,e.projectName+"::"+e.kind)}},Ove=(Ive.requestDelayMillis=100,Ive),Lve={};r(Lve,{ActionInvalidate:()=>ZV,ActionPackageInstalled:()=>eW,ActionSet:()=>YV,ActionWatchTypingLocations:()=>aW,Arguments:()=>XV,AutoImportProviderProject:()=>q1e,AuxiliaryProject:()=>J1e,CharRangeSection:()=>Tve,CloseFileWatcherEvent:()=>cye,CommandNames:()=>nve,ConfigFileDiagEvent:()=>rye,ConfiguredProject:()=>U1e,ConfiguredProjectLoadKind:()=>Dye,CreateDirectoryWatcherEvent:()=>sye,CreateFileWatcherEvent:()=>oye,Errors:()=>Q0e,EventBeginInstallTypes:()=>rW,EventEndInstallTypes:()=>nW,EventInitializationFailed:()=>iW,EventTypesRegistry:()=>tW,ExternalProject:()=>V1e,GcTimer:()=>d1e,InferredProject:()=>B1e,LargeFileReferencedEvent:()=>tye,LineIndex:()=>Eve,LineLeaf:()=>Ave,LineNode:()=>Fve,LogLevel:()=>Y0e,Msg:()=>e1e,OpenFileInfoTelemetryEvent:()=>aye,Project:()=>M1e,ProjectInfoTelemetryEvent:()=>iye,ProjectKind:()=>A1e,ProjectLanguageServiceStateEvent:()=>nye,ProjectLoadingFinishEvent:()=>eye,ProjectLoadingStartEvent:()=>Z1e,ProjectService:()=>Hye,ProjectsUpdatedInBackgroundEvent:()=>Y1e,ScriptInfo:()=>D1e,ScriptVersionCache:()=>Dve,Session:()=>hve,TextStorage:()=>w1e,ThrottledOperations:()=>u1e,TypingsCache:()=>F1e,TypingsInstallerAdapter:()=>Ove,allFilesAreJsOrDts:()=>L1e,allRootFilesAreJsOrDts:()=>O1e,asNormalizedPath:()=>i1e,convertCompilerOptions:()=>gye,convertFormatOptions:()=>mye,convertScriptKindName:()=>bye,convertTypeAcquisition:()=>yye,convertUserPreferences:()=>xye,convertWatchOptions:()=>hye,countEachFileTypes:()=>I1e,createInstallTypingsRequest:()=>t1e,createModuleSpecifierCache:()=>$ye,createNormalizedPathMap:()=>a1e,createPackageJsonCache:()=>Xye,createSortedArray:()=>_1e,emptyArray:()=>Z0e,findArgument:()=>sW,forEachResolvedProjectReferenceProject:()=>Pye,formatDiagnosticToProtocol:()=>rve,formatMessage:()=>ive,getBaseConfigFileName:()=>p1e,getLocationInNewDocument:()=>xve,hasArgument:()=>oW,hasNoTypeScriptSource:()=>j1e,indent:()=>_W,isBackgroundProject:()=>G1e,isConfigFile:()=>Kye,isConfiguredProject:()=>H1e,isDynamicFileName:()=>N1e,isExternalProject:()=>K1e,isInferredProject:()=>W1e,isInferredProjectName:()=>o1e,isProjectDeferredClose:()=>$1e,makeAutoImportProviderProjectName:()=>c1e,makeAuxiliaryProjectName:()=>l1e,makeInferredProjectName:()=>s1e,maxFileSize:()=>Q1e,maxProgramSizeForNonTsFiles:()=>X1e,normalizedPathToPath:()=>n1e,nowString:()=>cW,nullCancellationToken:()=>Qye,nullTypingsInstaller:()=>P1e,protocol:()=>m1e,removeSorted:()=>f1e,stringifyIndented:()=>uW,toEvent:()=>ove,toNormalizedPath:()=>r1e,tryConvertScriptKindName:()=>vye,typingsInstaller:()=>W0e,updateProjectIfDirty:()=>jye}),"undefined"!=typeof console&&(Y4.loggingHost={log(e,t){switch(e){case 1:return console.error(t);case 2:return console.warn(t);case 3:case 4:return console.log(t)}}})}.call(this)}.call(this,t2e("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},t2e("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/node_modules/typescript/lib/typescript.js","/node_modules/typescript/lib")},{_process:46,buffer:1,crypto:1,fs:1,inspector:1,os:1,path:1,perf_hooks:1,"source-map-support":1}],48:[function(e,t,r){Object.defineProperty(r,"__esModule",{value:!0});let k=e("core-types-json-schema"),T=e("core-types-ts/dist/lib/ts-to-core-types"),u=e("core-types-ts"),C=e("./utils/sharedUtils"),w=e("./utils/constants"),N=e("./utils/nosqlUtils"),d=e("./utils/constants-nosql");Draw.loadPlugin(function(p){var e=document.createElement("div");e.style.userSelect="none",e.style.overflow="hidden",e.style.padding="10px",e.style.height="100%";let i=document.createElement("textarea"),t=(i.style.height="200px",i.style.width="100%","-- click a nosql type button");i.value=t,mxUtils.br(e),e.appendChild(i);var r=p.menus.get("exportAs");let n="tonosql=To NoSQL",a=(r&&!window.VsCodeApi||(n="tonosql=Export As NoSQL"),mxResources.parse(n),new mxWindow(mxResources.get("tonosql"),e,document.body.offsetWidth-480,140,320,320,!0,!0));function o(e){var t,r=(0,C.getMermaidDiagramDb)(p,e),r=(0,N.dbToOpenApi)(r);let n="";"ts"==e?(t=(0,k.convertOpenApiToCoreTypes)(r)["data"],t=(0,u.convertCoreTypesToTypeScript)(t)["data"],n=`/* Generated in drawio Database: ${e} Plugin: nosql - Version: ${P.pluginVersion} + Version: ${w.pluginVersion} */ -`+n,n+=t):"openapi"==e&&(n=JSON.stringify(r,null,2)),i.value=n}a.destroyOnClose=!1,a.setMaximizable(!1),a.setResizable(!1),a.setClosable(!0),mxUtils.br(e);var s=mxUtils.button(mxResources.get("reset"),function(){i.value=t});s.style.marginTop="8px",s.style.marginRight="4px",s.style.padding="4px",e.appendChild(s);let c=mxUtils.button("TS",function(){o("ts")}),b=(c.style.marginTop="8px",c.style.padding="4px",e.appendChild(c),(c=mxUtils.button("OpenAPI",function(){o("openapi")})).style.marginTop="8px",c.style.padding="4px",e.appendChild(c),v.actions.addAction("tonosql",function(){a.setVisible(!a.isVisible()),a.isVisible()&&i.focus()}),[]),d=[],p=[],x=[],f=null,S=null,k=0,T=0;s=document.createElement("div");s.style.userSelect="none",s.style.overflow="hidden",s.style.padding="10px",s.style.height="100%";let l=document.createElement("textarea"),_=(l.style.height="200px",l.style.width="100%",`/* +`+n,n+=t):"openapi"==e&&(n=JSON.stringify(r,null,2)),i.value=n}a.destroyOnClose=!1,a.setMaximizable(!1),a.setResizable(!1),a.setClosable(!0),mxUtils.br(e);var s=mxUtils.button(mxResources.get("reset"),function(){i.value=t});s.style.marginTop="8px",s.style.marginRight="4px",s.style.padding="4px",e.appendChild(s);let c=mxUtils.button("TS",function(){o("ts")}),f=(c.style.marginTop="8px",c.style.padding="4px",e.appendChild(c),(c=mxUtils.button("OpenAPI",function(){o("openapi")})).style.marginTop="8px",c.style.padding="4px",e.appendChild(c),p.actions.addAction("tonosql",function(){a.setVisible(!a.isVisible()),a.isVisible()&&i.focus()}),[]),m=[],g=[],h=[],y=null,v=null,b=0,x=0;s=document.createElement("div");s.style.userSelect="none",s.style.overflow="hidden",s.style.padding="10px",s.style.height="100%";let l=document.createElement("textarea"),S=(l.style.height="200px",l.style.width="100%",l.value=d.defaultReset,mxUtils.br(s),s.appendChild(l),mxResources.parse("fromNoSql=From NoSQL"),new mxWindow(mxResources.get("fromNoSql"),s,document.body.offsetWidth-480,140,320,320,!0,!0));function _(t,r){var n;h=[],y=null,v=null;try{let e=null;var i,a,o,s,c,l,_,u={title:"nosql default options",version:w.pluginVersion},d=("openapi"==r?(i=JSON.parse(t),a=(0,k.convertOpenApiToCoreTypes)(i)["data"],o=(0,k.convertCoreTypesToJsonSchema)(a)["data"],(0,k.jsonSchemaDocumentToOpenApi)(o,u),e=i):"ts"==r&&(s=(0,T.convertTypeScriptToCoreTypes)(t)["data"],c=(0,k.convertCoreTypesToJsonSchema)(s)["data"],e=(0,k.jsonSchemaDocumentToOpenApi)(c,u)),null==(n=null===e||void 0===e?void 0:e.components)?void 0:n.schemas);d&&(l=(0,N.ConvertOpenApiToDatabaseModel)(d),f=l.ForeignKeyList,m=l.PrimaryKeyList,g=l.TableList,x=g.length,_=(0,C.CreateTableUI)(p,S,g,h,v,y,f,b,r))&&(h=_.cells,b=_.dx,y=_.tableCell,v=_.rowCell)}catch(e){console.log("unable to serialize the response:"+r),console.log(e)}}S.destroyOnClose=!1,S.setMaximizable(!1),S.setResizable(!1),S.setClosable(!0),mxUtils.br(s);e=mxUtils.button(mxResources.get("Reset TS"),function(){l.value=d.defaultReset}),e.style.marginTop="8px",e.style.marginRight="4px",e.style.padding="4px",s.appendChild(e),e=mxUtils.button("Reset OpenAPI",function(){l.value=d.defaultResetOpenApi}),e.style.marginTop="8px",e.style.marginRight="4px",e.style.padding="4px",s.appendChild(e),e=mxUtils.button("Insert TS",function(){_(l.value,"ts")}),e.style.marginTop="8px",e.style.padding="4px",s.appendChild(e),e=mxUtils.button("Insert OpenAPI",function(){_(l.value,"openapi")}),e.style.marginTop="8px",e.style.padding="4px",s.appendChild(e),p.actions.addAction("fromNoSql",function(){S.setVisible(!S.isVisible()),S.isVisible()&&l.focus()}),s=p.menus.get("insert");if(s){let n=s.funct;s.funct=function(...e){var[t,r]=e;n.apply(this,e),p.menus.addMenuItems(t,["fromNoSql"],r)}}if(r&&!window.VsCodeApi){let n=r.funct;r.funct=function(...e){var[t,r]=e;n.apply(this,e),p.menus.addMenuItems(t,["tonosql"],r)}}else{e=p.menus.get("file");if(e&&e.enabled){let n=e.funct;e.funct=function(...e){var[t,r]=e;n.apply(this,e),p.menus.addMenuItems(t,["tonosql"],r)}}}})},{"./utils/constants":50,"./utils/constants-nosql":49,"./utils/nosqlUtils":51,"./utils/sharedUtils":52,"core-types-json-schema":2,"core-types-ts":25,"core-types-ts/dist/lib/ts-to-core-types":29}],49:[function(e,t,r){Object.defineProperty(r,"__esModule",{value:!0}),r.validJSONSchemaTypes=r.defaultResetOpenApi=r.defaultReset=void 0;e=e("./constants");r.defaultReset=`/* Drawio default value Plugin: nosql - Version: ${P.pluginVersion} + Version: ${e.pluginVersion} */ @@ -376,12 +376,12 @@ export interface WeatherForecast { export interface Child { name: string } - `),u=` + `,r.defaultResetOpenApi=` { "openapi": "3.0.0", "info": { "title": "nosql plugin sample", - "version": "${P.pluginVersion}", + "version": "${e.pluginVersion}", "x-comment": "Generated by core-types-json-schema (https://github.com/grantila/core-types-json-schema)" }, "paths": {}, @@ -446,4 +446,4 @@ export interface Child { } } } - `,C=(l.value=_,mxUtils.br(s),s.appendChild(l),mxResources.parse("fromNoSql=From NoSQL"),new mxWindow(mxResources.get("fromNoSql"),s,document.body.offsetWidth-480,140,320,320,!0,!0));function m(t,r){var n;x=[],f=null,S=null;try{let e=null;var i,a,o,s,c,l={title:"nosql default options",version:P.pluginVersion},_=("openapi"==r?(i=JSON.parse(t),a=(0,w.convertOpenApiToCoreTypes)(i)["data"],o=(0,w.convertCoreTypesToJsonSchema)(a)["data"],(0,w.jsonSchemaDocumentToOpenApi)(o,l),e=i):"ts"==r&&(s=(0,N.convertTypeScriptToCoreTypes)(t)["data"],c=(0,w.convertCoreTypesToJsonSchema)(s)["data"],e=(0,w.jsonSchemaDocumentToOpenApi)(c,l)),null==(n=null===e||void 0===e?void 0:e.components)?void 0:n.schemas);if(_){var u=(0,E.ConvertOpenApiToDatabaseModel)(_),m=(b=u.ForeignKeyList,d=u.PrimaryKeyList,p=u.TableList,T=p.length,r);if(p.forEach(function(r){var e,t=100+r.Name.length;(f=new mxCell(r.Name,new mxGeometry(k,0,t,26),"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;")).vertex=!0,S&&null!==(e=v.editor.graph.getPreferredSizeForCell(S))&&(f.geometry.width=e.width+t),x.push(f),r.Properties.forEach(function(e){var t;e=e,r.Name,t=e.Name+(e.ColumnProperties?" "+e.ColumnProperties:""),(S=new mxCell(t,new mxGeometry(0,0,90,26),"shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;")).vertex=!0,t=e.IsPrimaryKey&&e.IsForeignKey?"PK | FK":e.IsPrimaryKey?"PK":e.IsForeignKey?"FK":"",(e=sb.cloneCell(S,t)).connectable=!1,e.style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;",e.geometry.width=54,e.geometry.height=26,S.insert(e),t=v.editor.graph.getPreferredSizeForCell(S),f&&(null!==t&&f.geometry.widthe.Name==t.ReferencesTableName))?void 0:u.Properties[0])&&(r.ForeignKeyList[e].ReferencesPropertyName=u.Name),t.PrimaryKeyName||(d=null==(u=r.TableList.find(e=>e.Name==t.PrimaryKeyTableName))?void 0:u.Properties[0])&&(r.ForeignKeyList[e].PrimaryKeyName=d.Name)}return r};let g=e("./constants"),h=e("./sharedUtils");function p(e,t,r){let n,i=(null!=(n=r.type)?n:"object").toString();r.enum?i=""+JSON.stringify(r.enum):r.nullable&&(i+=" nullable");r=(0,h.generateComment)(r.description,r.format),r&&(i+=" "+r),r={Name:(0,h.dbTypeEnds)(t),IsPrimaryKey:!1,IsForeignKey:!1,ColumnProperties:i,TableName:(0,h.dbTypeEnds)(e),ForeignKey:[]};return r}},{"./constants":49,"./sharedUtils":51}],51:[function(e,t,r){Object.defineProperty(r,"__esModule",{value:!0}),r.GetColumnQuantifiers=C,r.removeHtml=n,r.dbTypeEnds=function(e){return`\`${e}\``},r.RemoveNameQuantifiers=w,r.getDbLabel=N,r.entityName=function(e,t){let r="";e&&(r+=""+e);t&&(r+=" @format "+t);r=r&&`/** ${r=r.trim()} */`;return r},r.getCommentIndexes=D,r.getMermaidDiagramDb=function(e,i){var t=e.editor.graph.getModel(),a={},o=[];for(var s in t.cells)if(Object.hasOwnProperty.call(t.cells,s)){var c=t.cells[s];if(-1!==c.mxObjectId.indexOf("mxCell")&&c.style&&c.style.trim().startsWith("swimlane;")){let t=c.value.toString(),r="",n="";if(null!==t&&void 0!==t&&t.includes(T.commentColumnQuantifiers.Start)&&null!==t&&void 0!==t&&t.includes(T.commentColumnQuantifiers.End)){let e=t.toString();var s=D(e),l=s.start,_=s.end;t=e.substring(0,s.beforeStart),-1!==(e=e.substring(l,_)).indexOf(T.formatKeyword)&&(s=e.indexOf(T.formatKeyword),n=e.substring(s+T.formatKeyword.length).trim(),e=e.substring(0,s)),e&&(r=e)}var u={name:w(t),attributes:[]},l=E(r,n);l&&(u.name+=l);for(let e=0;e-1!==["FK","PK"].findIndex(e=>e==t.value.toUpperCase())||-1!=t.value.toUpperCase().indexOf("PK,"));if(m&&(f.attributeKeyType=m.value,"PK"!=f.attributeKeyType)&&-1!=f.attributeKeyType.indexOf("PK")&&(f.attributeKeyType="PK"),u.attributes.push(f),d.edges&&d.edges.length)for(let e=0;e-1!=t.toLocaleLowerCase().indexOf(e)),h=r&&-1!=h.findIndex(e=>-1!=r.toLocaleLowerCase().indexOf(e));if(!h&&!y||h&&y){if(h&&y){var v,h=N(g.source.value,p),b=(h.attributeKeyType="PK",k=h.attributeName,w(g.source.parent.value)),x=N(g.target.value,p),S=(x.attributeKeyType="PK",v=x.attributeName,w(g.target.parent.value)),h={name:w(b)+"_"+w(S),attributes:[h,x]};a[h.name]||(a[h.name]=h);let t={entityA:b,entityB:h.name,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:`[${b}.${k}] to [${h.name}.${k}]`},r=(-1==o.findIndex(e=>e.entityA==t.entityA&&e.entityB==t.entityB&&e.roleA==t.roleA)&&o.push(t),{entityA:S,entityB:h.name,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:`[${S}.${v}] to [${h.name}.${v}]`});-1==o.findIndex(e=>e.entityA==r.entityA&&e.entityB==r.entityB&&e.roleA==r.roleA)&&o.push(r)}}else{x=N(g.source.value,p).attributeName;var k,b=w(g.source.parent.value),S=(k=N(g.target.value,p).attributeName,w(g.target.parent.value));let t={entityA:y?b:S,entityB:y?S:b,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:y?`[${b}.${x}] to [${S}.${k}]`:`[${S}.${k}] to [${b}.${x}]`};-1==o.findIndex(e=>e.entityA==t.entityA&&e.entityB==t.entityB&&e.roleA==t.roleA)&&o.push(t)}}}}}if(a[u.name]){let e=2;for(;a[u.name+e.toString()];)e++;a[u.name+e.toString()]=u}else a[u.name]=u}}e=P(a,o);return e},r.GenerateDatabaseModel=P,r.generateComment=E;let T=e("./constants");function C(e){var t={Start:'"',End:'"'};return e&&["mysql","ts","openapi"].includes(e)?(t.Start="`",t.End="`"):"sqlserver"==e&&(t.Start="[",t.End="]"),t}function n(e){var t=document.createElement("div"),e=(t.innerHTML=e,t.textContent||t.innerText||"");return t.remove(),e}function w(e){return e.replace(/\[|\]|\(|\"|\'|\`/g,"").trim()}function N(e,t){let r=n(e);e=(r=r.toString().replace(/\s+/g," "))[0]==t.Start&&-1!==r.indexOf(t.End+" ")?r.indexOf(t.End+" "):r.indexOf(" "),t=r.substring(e+1).trim();return{attributeName:w(r.substring(0,e+1)),attributeType:t}}function D(e){let t=!1;return{beforeStart:(t=-1!==e.indexOf(T.commentColumnQuantifiers.Start)&&-1!==e.indexOf(T.commentColumnQuantifiers.End)?!0:t)?e.indexOf(T.commentColumnQuantifiers.Start):-1,start:t?e.indexOf(T.commentColumnQuantifiers.Start)+T.commentColumnQuantifiers.Start.length:-1,end:t?e.indexOf(T.commentColumnQuantifiers.End)-1:-1}}function P(e,t){return new class{constructor(e,t){this.entities=e,this.relationships=t}getEntities(){return this.entities}getRelationships(){return this.relationships}}(e,t)}function E(e,t){let r="";return e&&(r+=""+e),t&&(r+=" @format "+t),r&&(r=r.trim(),r=`${T.commentColumnQuantifiers.Start} ${r} `+T.commentColumnQuantifiers.End),r}},{"./constants":49}]},{},[48]); \ No newline at end of file + `;r.validJSONSchemaTypes=["string","number","integer","boolean","object","array","null","any"]},{"./constants":50}],50:[function(e,t,r){Object.defineProperty(r,"__esModule",{value:!0}),r.objectKeyword=r.arrayKeyword=r.nullableKeyword=r.enumKeyword=r.formatKeyword=r.commentColumnQuantifiers=r.pluginVersion=void 0,r.pluginVersion="0.0.6",r.commentColumnQuantifiers={Start:"/**",End:"*/"},r.formatKeyword="@format",r.enumKeyword="enum",r.nullableKeyword="nullable",r.arrayKeyword="array",r.objectKeyword="object"},{}],51:[function(e,t,r){Object.defineProperty(r,"__esModule",{value:!0}),r.dbToOpenApi=function(l){var e={openapi:"3.0.0",info:{title:"drawio nosql export",version:y.pluginVersion,"x-comment":"Generated by from drawio uml using plugin nosql"},paths:{},components:{schemas:{}}},_={},n=l.getEntities();for(let c in n)if(Object.prototype.hasOwnProperty.call(n,c)){let s=c;var i=n[c],a=(0,v.getCommentIndexes)(c);let t="",r="";if(-1e.entityA==c);let t=`[${c}.${p}]`;f=g.find(e=>-1!=e.roleA.indexOf(t));f&&(h=(0,v.getCommentIndexes)(f.entityB),f=f.entityB.substring(0,h.beforeStart).trim(),e="#/components/schemas/"+f),e&&("array"==i&&(r={$ref:e}),"object"==i)&&(n={$ref:e})}var h={title:s+"."+p,type:i};n&&(h.additionalProperties=n),r&&(h.items=r),null!=(f=d.attributeType)&&f.includes("nullable")&&(h.nullable=!0),!e||null!==n&&void 0!==n&&n.$ref||null!==r&&void 0!==r&&r.$ref||(h.$ref=e),t&&delete h.type,a.trim()&&!e&&(h.description=a.trim()),o.trim()&&(h.items?h.items.format=o.trim():h.format=o.trim()),_[s].properties[d.attributeName]=h}}}0===Object.keys(_[s].properties).length&&delete _[s].properties}}return e.components.schemas=_,e},r.GeneratePropertyModel=g,r.ConvertOpenApiToDatabaseModel=function(t){var r,n,i;var a={Dialect:"nosql",TableList:[],PrimaryKeyList:[],ForeignKeyList:[]},o={};for(var e in t)if(Object.prototype.hasOwnProperty.call(t,e)){var s,c,l,_=t[e],u=(0,v.dbTypeEnds)(e),d={Name:(0,v.dbTypeEnds)(e),Properties:[]};for(l in _.enum?(s=_.enum,c=_.type+" "+y.enumKeyword,s={enum:s},_.description&&(s.description=_.description),_.format&&(s.format=_.format),e=g(e,c,s),d.Properties.push(e)):(c=(0,v.generateComment)(_.description,_.format))&&(d.Name+=" "+c),_.properties)if(Object.prototype.hasOwnProperty.call(_.properties,l)){var p=_.properties[l];let e=null;p.$ref?e=p.$ref.split("/").pop():p.items&&typeof p.items==y.objectKeyword?e=null==(r=p.items.$ref)?void 0:r.split("/").pop():p.additionalProperties&&"object"==typeof p.additionalProperties&&(e=null==(r=p.additionalProperties.$ref)?void 0:r.split("/").pop()),e&&(m=t[e],e=m&&!m.enum&&(m=(0,v.generateComment)(m.description,m.format))?(0,v.dbTypeEnds)(e)+" "+m:(0,v.dbTypeEnds)(e)),e&&!p.type&&(p.type=e);var f,m=g(d.Name,l,p);e&&(p={PrimaryKeyTableName:d.Name,ReferencesTableName:e,PrimaryKeyName:(0,v.dbTypeEnds)(l),ReferencesPropertyName:"",IsDestination:!1},f={ReferencesTableName:d.Name,PrimaryKeyTableName:e,ReferencesPropertyName:(0,v.dbTypeEnds)(l),PrimaryKeyName:"",IsDestination:!0},a.ForeignKeyList.push(f),a.ForeignKeyList.push(p),m.IsForeignKey=!0),d.Properties.push(m)}a.TableList.push(d),o[u]||(o[u]=d)}for(let r=0;re.Name==t.ReferencesTableName))?void 0:n.Properties[0];(e=e||(null==(n=o[t.ReferencesTableName])?void 0:n.Properties[0]))&&(a.ForeignKeyList[r].ReferencesPropertyName=e.Name)}if(!t.PrimaryKeyName){let e=null==(n=a.TableList.find(e=>e.Name==t.PrimaryKeyTableName))?void 0:n.Properties[0];(e=e||(null==(i=o[t.PrimaryKeyTableName])?void 0:i.Properties[0]))&&(a.ForeignKeyList[r].PrimaryKeyName=e.Name)}}return a};let y=e("./constants"),v=e("./sharedUtils"),b=e("./constants-nosql");function g(e,t,r){let n,i=(null!=(n=r.type)?n:y.objectKeyword).toString();i===y.arrayKeyword&&r.items&&typeof r.items===y.objectKeyword&&(r.items.format&&!r.format&&(r.format=r.items.format),r.items.type)&&(i=r.items.type+"[]"),r.enum?i=""+JSON.stringify(r.enum):r.nullable&&(i+=" "+y.nullableKeyword);r=(0,v.generateComment)(r.description,r.format),r&&(i+=" "+r),r={Name:(0,v.dbTypeEnds)(t),IsPrimaryKey:!1,IsForeignKey:!1,ColumnProperties:i,TableName:(0,v.dbTypeEnds)(e),ForeignKey:[]};return r}},{"./constants":50,"./constants-nosql":49,"./sharedUtils":52}],52:[function(e,t,r){Object.defineProperty(r,"__esModule",{value:!0}),r.GetColumnQuantifiers=C,r.removeHtml=n,r.dbTypeEnds=m,r.RemoveNameQuantifiers=w,r.getDbLabel=N,r.entityName=function(e,t){let r="";e&&(r+=""+e);t&&(r+=` ${T.formatKeyword} `+t);r=r&&`/** ${r=r.trim()} */`;return r},r.getCommentIndexes=D,r.getMermaidDiagramDb=function(e,i){var t=e.editor.graph.getModel(),a={},o=[];for(var s in t.cells)if(Object.hasOwnProperty.call(t.cells,s)){var c=t.cells[s];if(-1!==c.mxObjectId.indexOf("mxCell")&&c.style&&c.style.trim().startsWith("swimlane;")){let t=c.value.toString(),r="",n="";if(null!==t&&void 0!==t&&t.includes(T.commentColumnQuantifiers.Start)&&null!==t&&void 0!==t&&t.includes(T.commentColumnQuantifiers.End)){let e=t.toString();var s=D(e),l=s.start,_=s.end;t=e.substring(0,s.beforeStart),-1!==(e=e.substring(l,_)).indexOf(T.formatKeyword)&&(s=e.indexOf(T.formatKeyword),n=e.substring(s+T.formatKeyword.length).trim(),e=e.substring(0,s)),e&&(r=e)}var u={name:w(t),attributes:[]},l=E(r,n);l&&(u.name+=" "+l);for(let e=0;e-1!==["FK","PK"].findIndex(e=>e==t.value.toUpperCase())||-1!=t.value.toUpperCase().indexOf("PK,"));if(m&&(f.attributeKeyType=m.value,"PK"!=f.attributeKeyType)&&-1!=f.attributeKeyType.indexOf("PK")&&(f.attributeKeyType="PK"),u.attributes.push(f),d.edges&&d.edges.length)for(let e=0;e-1!=t.toLocaleLowerCase().indexOf(e)),h=r&&-1!=h.findIndex(e=>-1!=r.toLocaleLowerCase().indexOf(e));if(!h&&!y||h&&y){if(h&&y){var h=N(g.source.value,p),v=(h.attributeKeyType="PK",S=h.attributeName,w(g.source.parent.value)),b=N(g.target.value,p),x=(b.attributeKeyType="PK",k=b.attributeName,w(g.target.parent.value)),h={name:w(v)+"_"+w(x),attributes:[h,b]};a[h.name]||(a[h.name]=h);let t={entityA:v,entityB:h.name,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:`[${v}.${S}] to [${h.name}.${S}]`},r=(-1==o.findIndex(e=>e.entityA==t.entityA&&e.entityB==t.entityB&&e.roleA==t.roleA)&&o.push(t),{entityA:x,entityB:h.name,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:`[${x}.${k}] to [${h.name}.${k}]`});-1==o.findIndex(e=>e.entityA==r.entityA&&e.entityB==r.entityB&&e.roleA==r.roleA)&&o.push(r)}}else{b=N(g.source.value,p).attributeName;let e=g.source.parent.value;var S,k,v=D(e),x=(e=-1!=v.start&&-1!=v.end?(S=e.substring(v.start,v.end).trim(),w(e=e.substring(0,v.beforeStart).trim())+" "+E(S)):w(e),g.target.value),h=N(x,p);x=h.attributeName;let t=g.target.parent.value,r=(v=D(t),t=-1!=v.start&&-1!=v.end?(k=t.substring(v.start,v.end).trim(),w(t=t.substring(0,v.beforeStart).trim())+" "+E(k)):w(t),{entityA:y?e:t,entityB:y?t:e,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:y?`[${e}.${b}] to [${t}.${x}]`:`[${t}.${x}] to [${e}.${b}]`});-1==o.findIndex(e=>e.entityA==r.entityA&&e.entityB==r.entityB&&e.roleA==r.roleA)&&o.push(r)}}}}}if(a[u.name]){let e=2;for(;a[u.name+e.toString()];)e++;a[u.name+e.toString()]=u}else a[u.name]=u}}e=P(a,o);return e},r.GenerateDatabaseModel=P,r.generateComment=E,r.CreateTableUI=function(n,e,t,i,a,o,r,s,c){if(t.forEach(function(t){var e,r=100+t.Name.length;(o=new mxCell(t.Name,new mxGeometry(s,0,r,26),"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;")).vertex=!0,a&&null!==(e=n.editor.graph.getPreferredSizeForCell(a))&&(o.geometry.width=e.width+r),i.push(o),t.Properties.forEach(function(e){e=function(e,t,r,n){var i=t.Name+(t.ColumnProperties?" "+t.ColumnProperties:""),i=((r=new mxCell(i,new mxGeometry(0,0,90,26),"shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;")).vertex=!0,t.IsPrimaryKey&&t.IsForeignKey?"PK | FK":t.IsPrimaryKey?"PK":t.IsForeignKey?"FK":""),t=sb.cloneCell(r,i),i=(t.connectable=!1,t.style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;",t.geometry.width=54,t.geometry.height=26,r.insert(t),e.editor.graph.getPreferredSizeForCell(r));n&&(null!==i&&n.geometry.width 0) { - const graph = ui.editor.graph; - const view = graph.view; - const bds = graph.getGraphBounds(); - // Computes unscaled, untranslated graph bounds - const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize); - const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + 4 * graph.gridSize); - graph.setSelectionCells(graph.importCells(cells, x, y)); - // add foreign key edges - const model = graph.getModel(); - const columnQuantifiers = (0, sharedUtils_1.GetColumnQuantifiers)(type); - // const pt = graph.getFreeInsertPoint(); - foreignKeyList.forEach(function (fk) { - if (fk.IsDestination && fk.PrimaryKeyName && fk.ReferencesPropertyName && - fk.PrimaryKeyTableName && fk.ReferencesTableName) { - const insertEdge = mxUtils.bind(this, function (targetCell, sourceCell, edge) { - const label = ""; - const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; - const edgeCell = graph.insertEdge(null, null, label || "", (edge.invert) ? - sourceCell : targetCell, (edge.invert) ? targetCell : sourceCell, edgeStyle); - }); - const edge = { - invert: true - }; - let targetCell = null; - let sourceCell = null; - // locate edge source and target cells - for (const key in model.cells) { - if (targetCell && sourceCell) - break; - if (Object.hasOwnProperty.call(model.cells, key)) { - const mxcell = model.cells[key]; - if (mxcell.style && mxcell.style.trim().startsWith("swimlane;")) { - const entity = { - name: mxcell.value, - attributes: [] - }; - const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; - const isForeignTable = entity.name == fk.ReferencesTableName; - if (isPrimaryTable || isForeignTable) { - for (let c = 0; c < mxcell.children.length; c++) { - if (targetCell && sourceCell) - break; - const col = mxcell.children[c]; - if (col.mxObjectId.indexOf("mxCell") !== -1) { - if (col.style && col.style.trim().startsWith("shape=partialRectangle")) { - const attribute = (0, sharedUtils_1.getDbLabel)(col.value, columnQuantifiers); - if (isPrimaryTable && (0, sharedUtils_1.dbTypeEnds)(attribute.attributeName) == fk.PrimaryKeyName) { - targetCell = col; - break; - } - else if (isForeignTable && (0, sharedUtils_1.dbTypeEnds)(attribute.attributeName) == fk.ReferencesPropertyName) { - sourceCell = col; - break; - } - } - } - } - } - } - } - } - if (targetCell && sourceCell) - insertEdge(targetCell, sourceCell, edge); - } - }); - graph.scrollCellToVisible(graph.getSelectionCell()); - } - wndFromNOSQL.setVisible(false); - } - ; mxUtils.br(divFromNOSQL); const resetOpenAPIBtnFromNOSQL = mxUtils.button("Reset OpenAPI", function () { - sqlInputFromNOSQL.value = defaultResetOpenApi; + sqlInputFromNOSQL.value = constants_nosql_1.defaultResetOpenApi; }); resetOpenAPIBtnFromNOSQL.style.marginTop = "8px"; resetOpenAPIBtnFromNOSQL.style.marginRight = "4px"; @@ -4984,21 +4803,128 @@ Draw.loadPlugin(function (ui) { } }); -},{"./utils/constants":29,"./utils/nosqlUtils":30,"./utils/sharedUtils":31,"core-types-json-schema":1}],29:[function(require,module,exports){ +},{"./utils/constants":30,"./utils/constants-nosql":29,"./utils/nosqlUtils":31,"./utils/sharedUtils":32,"core-types-json-schema":1}],29:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.validJSONSchemaTypes = exports.defaultResetOpenApi = exports.defaultReset = void 0; +const constants_1 = require("./constants"); +exports.defaultReset = `/*\n\tDrawio default value\n\tPlugin: nosql\n\tVersion: ${constants_1.pluginVersion}\n*/\n\n +export interface WeatherForecast { + /** @format date-time */ + date?: string; + /** @format int32 */ + temperatureC?: number; + /** @format int32 */ + temperatureF?: number; + summary?: string | null; + nestedProp: string[]; + children?: Child[]; +} + +export interface Child { + name: string +} + `; +exports.defaultResetOpenApi = ` +{ + "openapi": "3.0.0", + "info": { + "title": "nosql plugin sample", + "version": "${constants_1.pluginVersion}", + "x-comment": "Generated by core-types-json-schema (https://github.com/grantila/core-types-json-schema)" + }, + "paths": {}, + "components": { + "schemas": { + "WeatherForecast": { + "properties": { + "date": { + "title": "WeatherForecast.date", + "description": "@format date-time", + "type": "string" + }, + "temperatureC": { + "title": "WeatherForecast.temperatureC", + "description": "@format int32", + "type": "number" + }, + "temperatureF": { + "title": "WeatherForecast.temperatureF", + "description": "@format int32", + "type": "number" + }, + "summary": { + "title": "WeatherForecast.summary", + "nullable": true, + "type": "string" + }, + "nestedProp": { + "items": { + "title": "WeatherForecast.nestedProp.[]", + "type": "string" + }, + "title": "WeatherForecast.nestedProp", + "type": "array" + }, + "child": { + "$ref": "#/components/schemas/Child", + "title": "WeatherForecast.child" + } + }, + "required": [ + "nestedProp" + ], + "additionalProperties": false, + "title": "WeatherForecast", + "type": "object" + }, + "Child": { + "properties": { + "name": { + "title": "Child.name", + "type": "string" + } + }, + "required": [ + "name" + ], + "additionalProperties": false, + "title": "Child", + "type": "object" + } + } + } +} + `; +const JSONSchemaTypes = [ + "string", + "number", + "integer", + "boolean", + "object", + "array", + "null", + "any" +]; +exports.validJSONSchemaTypes = JSONSchemaTypes; + +},{"./constants":30}],30:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.validEnumTypes = exports.enumKeyword = exports.formatKeyword = exports.commentColumnQuantifiers = exports.pluginVersion = void 0; +exports.objectKeyword = exports.arrayKeyword = exports.nullableKeyword = exports.enumKeyword = exports.formatKeyword = exports.commentColumnQuantifiers = exports.pluginVersion = void 0; // export sql methods -exports.pluginVersion = "0.0.5"; +exports.pluginVersion = "0.0.6"; exports.commentColumnQuantifiers = { Start: "/**", End: "*/", }; exports.formatKeyword = "@format"; exports.enumKeyword = "enum"; -exports.validEnumTypes = ["string", "number", "integer", "boolean"]; +exports.nullableKeyword = "nullable"; +exports.arrayKeyword = "array"; +exports.objectKeyword = "object"; -},{}],30:[function(require,module,exports){ +},{}],31:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dbToOpenApi = dbToOpenApi; @@ -5006,13 +4932,14 @@ exports.GeneratePropertyModel = GeneratePropertyModel; exports.ConvertOpenApiToDatabaseModel = ConvertOpenApiToDatabaseModel; const constants_1 = require("./constants"); const sharedUtils_1 = require("./sharedUtils"); +const constants_nosql_1 = require("./constants-nosql"); /** * convert db to openapi * @param db * @returns */ function dbToOpenApi(db) { - var _a, _b, _c, _d, _e, _f, _g; + var _a, _b, _c, _d, _e, _f; const result = { openapi: "3.0.0", info: { @@ -5033,35 +4960,37 @@ function dbToOpenApi(db) { let schemaKey = key; const entity = entities[key]; let commentIndexes = (0, sharedUtils_1.getCommentIndexes)(key); - let description = ""; + let schemaDescription = ""; let formatValue = ""; if (commentIndexes.start > -1 && commentIndexes.end > -1) { let result = schemaKey.toString().trim(); commentIndexes = (0, sharedUtils_1.getCommentIndexes)(result); const firstSpaceIndex = commentIndexes.start; const lastSpaceIndex = commentIndexes.end; - schemaKey = result.substring(0, commentIndexes.beforeStart); + schemaKey = result.substring(0, commentIndexes.beforeStart).trim(); result = result.substring(firstSpaceIndex, lastSpaceIndex).trim(); if (result.indexOf(constants_1.formatKeyword) !== -1) { const formatIndex = result.indexOf(constants_1.formatKeyword); - formatValue = result.substring(formatIndex + constants_1.formatKeyword.length).trim(); + formatValue = result + .substring(formatIndex + constants_1.formatKeyword.length) + .trim(); result = result.substring(0, formatIndex); } if (result) { - description = result; + schemaDescription = result; } } if (schema[schemaKey]) { continue; } schema[schemaKey] = { - type: "object", + type: constants_1.objectKeyword, title: schemaKey, additionalProperties: false, properties: {}, }; - if (description) { - schema[schemaKey].description = description.trim(); + if (schemaDescription) { + schema[schemaKey].description = schemaDescription.trim(); } if (formatValue) { schema[schemaKey].format = formatValue.trim(); @@ -5080,23 +5009,25 @@ function dbToOpenApi(db) { if (propName.indexOf(constants_1.enumKeyword) !== -1) { const splitPropName = propName.split(" "); if (splitPropName.length == 2 && - constants_1.validEnumTypes.indexOf(splitPropName[0]) !== -1 && + constants_nosql_1.validJSONSchemaTypes.indexOf(splitPropName[0]) !== -1 && splitPropName[1] == constants_1.enumKeyword) { isEnum = true; type = splitPropName[0]; } } // extract desciption /** asdf */ - let description = ""; + let propertyDescription = ""; let formatValue = ""; let enumValues = null; if (((_d = attribute.attributeType) === null || _d === void 0 ? void 0 : _d.includes(constants_1.commentColumnQuantifiers.Start)) && ((_e = attribute.attributeType) === null || _e === void 0 ? void 0 : _e.includes(constants_1.commentColumnQuantifiers.End))) { - let result = attribute.attributeType; - const commentIndexes = (0, sharedUtils_1.getCommentIndexes)(result); + let attributeTypeResult = attribute.attributeType; + const commentIndexes = (0, sharedUtils_1.getCommentIndexes)(attributeTypeResult); const firstSpaceIndex = commentIndexes.start; const lastSpaceIndex = commentIndexes.end; - const enumRaw = result.substring(0, commentIndexes.beforeStart).trim(); + const enumRaw = attributeTypeResult + .substring(0, commentIndexes.beforeStart) + .trim(); if (enumRaw) { try { enumValues = JSON.parse(enumRaw); @@ -5105,16 +5036,16 @@ function dbToOpenApi(db) { console.log(`Error parsing raw enum values: ${enumRaw} Message: ${JSON.stringify(error)}`); } } - result = result.substring(firstSpaceIndex, lastSpaceIndex); - if (result.indexOf(constants_1.formatKeyword) !== -1) { - const formatIndex = result.indexOf(constants_1.formatKeyword); - formatValue = result + attributeTypeResult = attributeTypeResult.substring(firstSpaceIndex, lastSpaceIndex); + if (attributeTypeResult.indexOf(constants_1.formatKeyword) !== -1) { + const formatIndex = attributeTypeResult.indexOf(constants_1.formatKeyword); + formatValue = attributeTypeResult .substring(formatIndex + constants_1.formatKeyword.length) .trim(); - result = result.substring(0, formatIndex); + attributeTypeResult = attributeTypeResult.substring(0, formatIndex); } - if (result) { - description = result; + if (attributeTypeResult.trim()) { + propertyDescription = attributeTypeResult.trim(); } // decription = attribute.attributeType?.replace("/**", "").replace("*/", ""); } @@ -5124,25 +5055,94 @@ function dbToOpenApi(db) { if (enumValues) { schema[schemaKey].enum = enumValues; } - if (description) { - schema[schemaKey].description = description.trim(); + if (propertyDescription.trim()) { + schema[schemaKey].description = propertyDescription.trim(); } - if (formatValue) { + if (formatValue.trim()) { schema[schemaKey].format = formatValue.trim(); } schema[schemaKey].type = type; } else { + // check if type is jsonschema type + let $ref = null; + let removeType = false; + let items = null; + let additionalProperties = null; + if (constants_nosql_1.validJSONSchemaTypes.indexOf(type) === -1) { + if (type.indexOf("[]") != -1) { + const itemsType = type.replace("[]", ""); + if (constants_nosql_1.validJSONSchemaTypes.indexOf(itemsType) != -1) { + items = { + type: itemsType, + }; + type = "array"; + } + } + if (constants_nosql_1.validJSONSchemaTypes.indexOf(type) != -1) { + // + } + else { + // else { + removeType = true; + $ref = `#/components/schemas/${(0, sharedUtils_1.RemoveNameQuantifiers)(type)}`; + } + } + if (["array", "object"].indexOf(type) !== -1) { + const relationships = db.getRelationships().filter(x => x.entityA == key); + const roleLookup = `[${key}.${propName}]`; + // FIND MATCH + const rel = relationships.find(x => x.roleA.indexOf(roleLookup) != -1); + if (rel) { + const commentFKIndexes = (0, sharedUtils_1.getCommentIndexes)(rel.entityB); + const entityBName = rel.entityB.substring(0, commentFKIndexes.beforeStart).trim(); + $ref = `#/components/schemas/${entityBName}`; + } + if ($ref) { + // if array additionalProperties.$ref + if (type == "array") { + items = { + $ref: $ref + }; + } + // if object items.$ref + if (type == "object") { + additionalProperties = { + $ref: $ref + }; + } + } + } const property = { - title: `${key}.${propName}`, - nullable: (_g = (_f = attribute.attributeType) === null || _f === void 0 ? void 0 : _f.includes("nullable")) !== null && _g !== void 0 ? _g : false, + title: `${schemaKey}.${propName}`, type: type, }; - if (description) { - property.description = description.trim(); + if (additionalProperties) { + property.additionalProperties = additionalProperties; + } + if (items) { + property.items = items; } - if (formatValue) { - property.format = formatValue.trim(); + if ((_f = attribute.attributeType) === null || _f === void 0 ? void 0 : _f.includes("nullable")) { + property.nullable = true; + } + if ($ref && !(additionalProperties === null || additionalProperties === void 0 ? void 0 : additionalProperties.$ref) && !(items === null || items === void 0 ? void 0 : items.$ref)) { + property["$ref"] = $ref; + } + if (removeType) { + delete property.type; + } + // $ref properties don't have descriptions + if (propertyDescription.trim() && !$ref) { + // TODO: pull from proper location + property.description = propertyDescription.trim(); + } + if (formatValue.trim()) { + if (property.items) { + property.items.format = formatValue.trim(); + } + else + property.format = formatValue.trim(); } schema[schemaKey].properties[attribute.attributeName] = property; } @@ -5155,15 +5155,32 @@ function dbToOpenApi(db) { result.components.schemas = schema; return result; } -// TODO: may need to make recursive for when schema property items is array +/** + * used in uml generation + * @param tableName + * @param propertyName + * @param property + * @returns + */ function GeneratePropertyModel(tableName, propertyName, property) { var _a; - let columnProperties = ((_a = property.type) !== null && _a !== void 0 ? _a : "object").toString(); + let columnProperties = ((_a = property.type) !== null && _a !== void 0 ? _a : constants_1.objectKeyword).toString(); + if (columnProperties === constants_1.arrayKeyword) { + if (property.items && typeof property.items === constants_1.objectKeyword) { + if (property.items.format && !property.format) { + property.format = property.items.format; + // columnProperties = `${(property.items as JSONSchema4).format}[]`; + } + // else + if (property.items.type) + columnProperties = `${property.items.type}[]`; + } + } if (property.enum) { columnProperties = `${JSON.stringify(property.enum)}`; } else if (property.nullable) { - columnProperties += " nullable"; + columnProperties += ` ${constants_1.nullableKeyword}`; } const description = (0, sharedUtils_1.generateComment)(property.description, property.format); if (description) { @@ -5179,17 +5196,24 @@ function GeneratePropertyModel(tableName, propertyName, property) { }; return result; } +/** + * convert openapi schema to database model + * @param schemas + * @returns + */ function ConvertOpenApiToDatabaseModel(schemas) { - var _a, _b, _c; + var _a, _b, _c, _d, _e, _f; const models = { Dialect: "nosql", TableList: [], PrimaryKeyList: [], ForeignKeyList: [], }; + const tableDict = {}; for (const key in schemas) { if (Object.prototype.hasOwnProperty.call(schemas, key)) { const schema = schemas[key]; + const originalKey = (0, sharedUtils_1.dbTypeEnds)(key); const tableModel = { Name: (0, sharedUtils_1.dbTypeEnds)(key), Properties: [], @@ -5197,7 +5221,7 @@ function ConvertOpenApiToDatabaseModel(schemas) { if (schema.enum) { const enumList = schema.enum; // serialize to string enum [values] - const propertyKey = `${schema.type} enum`; + const propertyKey = `${schema.type} ${constants_1.enumKeyword}`; const property = { enum: enumList, }; @@ -5220,56 +5244,93 @@ function ConvertOpenApiToDatabaseModel(schemas) { for (const propertyKey in schema.properties) { if (Object.prototype.hasOwnProperty.call(schema.properties, propertyKey)) { const property = schema.properties[propertyKey]; - const propertyModel = GeneratePropertyModel(key, propertyKey, property); - if (propertyModel.ColumnProperties.includes("object") || - propertyModel.ColumnProperties.includes("array")) { - let refName = null; - if (property.$ref) { - refName = property.$ref.split("/").pop(); - } - else if (property.items && typeof property.items == "object") { - refName = (_a = property.items.$ref) === null || _a === void 0 ? void 0 : _a.split("/").pop(); + // if note object or array use ref + let refName = null; + if (property.$ref) { + refName = property.$ref.split("/").pop(); + } + else if (property.items && typeof property.items == constants_1.objectKeyword) { + refName = (_a = property.items.$ref) === null || _a === void 0 ? void 0 : _a.split("/").pop(); + } + else if (property.additionalProperties && + typeof property.additionalProperties == "object") { + refName = (_b = property.additionalProperties.$ref) === null || _b === void 0 ? void 0 : _b.split("/").pop(); + } + if (refName) { + const refSchema = schemas[refName]; + if (refSchema && !refSchema.enum) { + const comment = (0, sharedUtils_1.generateComment)(refSchema.description, refSchema.format); + if (comment) { + refName = `${(0, sharedUtils_1.dbTypeEnds)(refName)} ${comment}`; + } + else { + refName = (0, sharedUtils_1.dbTypeEnds)(refName); + } } - if (refName) { - const primaryKeyModel = { - PrimaryKeyTableName: (0, sharedUtils_1.dbTypeEnds)(key), - ReferencesTableName: (0, sharedUtils_1.dbTypeEnds)(refName), - PrimaryKeyName: (0, sharedUtils_1.dbTypeEnds)(propertyKey), - // should just point to first property in uml table - ReferencesPropertyName: "", - IsDestination: false, - }; - const foreignKeyModel = { - ReferencesTableName: (0, sharedUtils_1.dbTypeEnds)(key), - PrimaryKeyTableName: (0, sharedUtils_1.dbTypeEnds)(refName), - ReferencesPropertyName: (0, sharedUtils_1.dbTypeEnds)(propertyKey), - // should just point to first property in uml table - PrimaryKeyName: "", - IsDestination: true, - }; - models.ForeignKeyList.push(foreignKeyModel); - models.ForeignKeyList.push(primaryKeyModel); - propertyModel.IsForeignKey = true; + else { + refName = (0, sharedUtils_1.dbTypeEnds)(refName); } } + if (refName && !property.type) { + property.type = refName; + } + const propertyModel = GeneratePropertyModel(tableModel.Name, propertyKey, property); + // if ( + // propertyModel.ColumnProperties.includes(objectKeyword) || + // propertyModel.ColumnProperties.includes(arrayKeyword) + // ) { + if (refName) { + const primaryKeyModel = { + PrimaryKeyTableName: tableModel.Name, + ReferencesTableName: refName, + PrimaryKeyName: (0, sharedUtils_1.dbTypeEnds)(propertyKey), + // should just point to first property in uml table + ReferencesPropertyName: "", + IsDestination: false, + }; + const foreignKeyModel = { + ReferencesTableName: tableModel.Name, + PrimaryKeyTableName: refName, + ReferencesPropertyName: (0, sharedUtils_1.dbTypeEnds)(propertyKey), + // should just point to first property in uml table + PrimaryKeyName: "", + IsDestination: true, + }; + models.ForeignKeyList.push(foreignKeyModel); + models.ForeignKeyList.push(primaryKeyModel); + propertyModel.IsForeignKey = true; + } + // } tableModel.Properties.push(propertyModel); } } models.TableList.push(tableModel); + // may no longer be needed + if (!tableDict[originalKey]) { + tableDict[originalKey] = tableModel; + } } } for (let i = 0; i < models.ForeignKeyList.length; i++) { const fk = models.ForeignKeyList[i]; if (!fk.ReferencesPropertyName) { // match to first entry - const property = (_b = models.TableList.find((t) => t.Name == fk.ReferencesTableName)) === null || _b === void 0 ? void 0 : _b.Properties[0]; + let property = (_c = models.TableList.find((t) => t.Name == fk.ReferencesTableName)) === null || _c === void 0 ? void 0 : _c.Properties[0]; + if (!property) { + // attempt a comment lookup + property = (_d = tableDict[fk.ReferencesTableName]) === null || _d === void 0 ? void 0 : _d.Properties[0]; + } if (property) { models.ForeignKeyList[i].ReferencesPropertyName = property.Name; } } if (!fk.PrimaryKeyName) { // match to first entry - const property = (_c = models.TableList.find((t) => t.Name == fk.PrimaryKeyTableName)) === null || _c === void 0 ? void 0 : _c.Properties[0]; + let property = (_e = models.TableList.find((t) => t.Name == fk.PrimaryKeyTableName)) === null || _e === void 0 ? void 0 : _e.Properties[0]; + if (!property) { + // attempt a comment lookup + property = (_f = tableDict[fk.PrimaryKeyTableName]) === null || _f === void 0 ? void 0 : _f.Properties[0]; + } if (property) { models.ForeignKeyList[i].PrimaryKeyName = property.Name; } @@ -5278,7 +5339,7 @@ function ConvertOpenApiToDatabaseModel(schemas) { return models; } -},{"./constants":29,"./sharedUtils":31}],31:[function(require,module,exports){ +},{"./constants":30,"./constants-nosql":29,"./sharedUtils":32}],32:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GetColumnQuantifiers = GetColumnQuantifiers; @@ -5291,6 +5352,7 @@ exports.getCommentIndexes = getCommentIndexes; exports.getMermaidDiagramDb = getMermaidDiagramDb; exports.GenerateDatabaseModel = GenerateDatabaseModel; exports.generateComment = generateComment; +exports.CreateTableUI = CreateTableUI; const constants_1 = require("./constants"); /** * return text quantifiers for dialect @@ -5298,8 +5360,8 @@ const constants_1 = require("./constants"); */ function GetColumnQuantifiers(type) { const chars = { - Start: "\"", - End: "\"", + Start: '"', + End: '"', }; if (type && ["mysql", "ts", "openapi"].includes(type)) { chars.Start = "`"; @@ -5323,6 +5385,11 @@ function removeHtml(label) { tempDiv.remove(); return text; } +/** + * add db ends + * @param label + * @returns + */ function dbTypeEnds(label) { const char1 = "`"; const char2 = "`"; @@ -5332,6 +5399,11 @@ function dbTypeEnds(label) { // } return `${char1}${label}${char2}`; } +/** + * remove name quantifiers + * @param name + * @returns + */ function RemoveNameQuantifiers(name) { return name.replace(/\[|\]|\(|\"|\'|\`/g, "").trim(); } @@ -5363,7 +5435,7 @@ function entityName(description, format) { result += `${description}`; } if (format) { - result += ` @format ${format}`; + result += ` ${constants_1.formatKeyword} ${format}`; } if (result) { result = result.trim(); @@ -5373,16 +5445,24 @@ function entityName(description, format) { } function getCommentIndexes(result) { let hasComment = false; - if (result.indexOf(constants_1.commentColumnQuantifiers.Start) !== -1 && result.indexOf(constants_1.commentColumnQuantifiers.End) !== -1) { + if (result.indexOf(constants_1.commentColumnQuantifiers.Start) !== -1 && + result.indexOf(constants_1.commentColumnQuantifiers.End) !== -1) { hasComment = true; } - const beforeIndex = hasComment ? result.indexOf(constants_1.commentColumnQuantifiers.Start) : -1; - const firstSpaceIndex = hasComment ? result.indexOf(constants_1.commentColumnQuantifiers.Start) + constants_1.commentColumnQuantifiers.Start.length : -1; - const lastSpaceIndex = hasComment ? result.indexOf(constants_1.commentColumnQuantifiers.End) - 1 : -1; + const beforeIndex = hasComment + ? result.indexOf(constants_1.commentColumnQuantifiers.Start) + : -1; + const firstSpaceIndex = hasComment + ? result.indexOf(constants_1.commentColumnQuantifiers.Start) + + constants_1.commentColumnQuantifiers.Start.length + : -1; + const lastSpaceIndex = hasComment + ? result.indexOf(constants_1.commentColumnQuantifiers.End) - 1 + : -1; return { beforeStart: beforeIndex, start: firstSpaceIndex, - end: lastSpaceIndex + end: lastSpaceIndex, }; } /** @@ -5399,6 +5479,7 @@ function getMermaidDiagramDb(ui, type) { const relationships = []; // TODO: support for ts and openapi enum // build models + // fix fk for comments for (const key in model.cells) { if (Object.hasOwnProperty.call(model.cells, key)) { const mxcell = model.cells[key]; @@ -5417,7 +5498,9 @@ function getMermaidDiagramDb(ui, type) { result = result.substring(firstSpaceIndex, lastSpaceIndex); if (result.indexOf(constants_1.formatKeyword) !== -1) { const formatIndex = result.indexOf(constants_1.formatKeyword); - formatValue = result.substring(formatIndex + constants_1.formatKeyword.length).trim(); + formatValue = result + .substring(formatIndex + constants_1.formatKeyword.length) + .trim(); result = result.substring(0, formatIndex); } if (result) { @@ -5431,22 +5514,23 @@ function getMermaidDiagramDb(ui, type) { }; const comment = generateComment(description, formatValue); if (comment) { - entity.name += comment; + entity.name += ` ${comment}`; } - // const comment = + // const comment = for (let c = 0; c < mxcell.children.length; c++) { const col = mxcell.children[c]; if (col.mxObjectId.indexOf("mxCell") !== -1) { - if (col.style && col.style.trim().startsWith("shape=partialRectangle")) { + if (col.style && + col.style.trim().startsWith("shape=partialRectangle")) { const columnQuantifiers = GetColumnQuantifiers(type); //Get delimiter of column name //Get full name const attribute = getDbLabel(col.value, columnQuantifiers); - const attributeKeyType = col.children.find(x => ["FK", "PK"].findIndex(k => k == x.value.toUpperCase()) !== -1 || - x.value.toUpperCase().indexOf("PK,") != -1); + const attributeKeyType = col.children.find((x) => ["FK", "PK"].findIndex((k) => k == x.value.toUpperCase()) !== -1 || x.value.toUpperCase().indexOf("PK,") != -1); if (attributeKeyType) { attribute.attributeKeyType = attributeKeyType.value; - if (attribute.attributeKeyType != "PK" && attribute.attributeKeyType.indexOf("PK") != -1) { + if (attribute.attributeKeyType != "PK" && + attribute.attributeKeyType.indexOf("PK") != -1) { attribute.attributeKeyType = "PK"; } } @@ -5456,53 +5540,106 @@ function getMermaidDiagramDb(ui, type) { for (let e = 0; e < col.edges.length; e++) { const edge = col.edges[e]; if (edge.mxObjectId.indexOf("mxCell") !== -1) { - if (edge.style && edge.style.indexOf("endArrow=") != -1 && edge.source && - edge.source.value && edge.target && edge.target.value) { + if (edge.style && + edge.style.indexOf("endArrow=") != -1 && + edge.source && + edge.source.value && + edge.target && + edge.target.value) { // need to check if end is open or certain value to determin relationship type // extract endArrow txt // check if both match and contain many or open // if both match and are many then create a new table const endCheck = "endArrow="; - const endArr = edge.style.indexOf(endCheck) != -1 ? - edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length, edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length).indexOf(";") + edge.style.indexOf(endCheck) + endCheck.length) + const endArr = edge.style.indexOf(endCheck) != -1 + ? edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length, edge.style + .substring(edge.style.indexOf(endCheck) + + endCheck.length) + .indexOf(";") + + edge.style.indexOf(endCheck) + + endCheck.length) : ""; const startCheck = "startArrow="; - const startArr = edge.style.indexOf(startCheck) != -1 ? - edge.style.substring(edge.style.indexOf(startCheck) + startCheck.length, edge.style.substring(edge.style.indexOf(startCheck) + startCheck.length).indexOf(";") + edge.style.indexOf(startCheck) + startCheck.length) + const startArr = edge.style.indexOf(startCheck) != -1 + ? edge.style.substring(edge.style.indexOf(startCheck) + + startCheck.length, edge.style + .substring(edge.style.indexOf(startCheck) + + startCheck.length) + .indexOf(";") + + edge.style.indexOf(startCheck) + + startCheck.length) : ""; const manyCheck = ["open", "many"]; - const sourceIsPrimary = endArr && manyCheck - .findIndex(x => endArr.toLocaleLowerCase().indexOf(x) != -1) != -1; - const targetIsPrimary = startArr && manyCheck - .findIndex(x => startArr.toLocaleLowerCase().indexOf(x) != -1) != -1; + const sourceIsPrimary = endArr && + manyCheck.findIndex((x) => endArr.toLocaleLowerCase().indexOf(x) != -1) != -1; + const targetIsPrimary = startArr && + manyCheck.findIndex((x) => startArr.toLocaleLowerCase().indexOf(x) != -1) != -1; // has to be one to many and not one to one if ((targetIsPrimary || sourceIsPrimary) && !(targetIsPrimary && sourceIsPrimary)) { let sourceId = edge.source.value; const sourceAttr = getDbLabel(sourceId, columnQuantifiers); sourceId = sourceAttr.attributeName; - const sourceEntity = RemoveNameQuantifiers(edge.source.parent.value); + let sourceEntity = edge.source.parent.value; + // extract comments + let commentsIndexes = getCommentIndexes(sourceEntity); + if (commentsIndexes.start != -1 && + commentsIndexes.end != -1) { + const sourceComment = sourceEntity + .substring(commentsIndexes.start, commentsIndexes.end) + .trim(); + sourceEntity = sourceEntity + .substring(0, commentsIndexes.beforeStart) + .trim(); + sourceEntity = `${RemoveNameQuantifiers(sourceEntity)} ${generateComment(sourceComment)}`; + } + else { + sourceEntity = RemoveNameQuantifiers(sourceEntity); + } let targetId = edge.target.value; const targetAttr = getDbLabel(targetId, columnQuantifiers); targetId = targetAttr.attributeName; - const targetEntity = RemoveNameQuantifiers(edge.target.parent.value); + let targetEntity = edge.target.parent.value; + commentsIndexes = getCommentIndexes(targetEntity); + if (commentsIndexes.start != -1 && + commentsIndexes.end != -1) { + const targetComment = targetEntity + .substring(commentsIndexes.start, commentsIndexes.end) + .trim(); + targetEntity = targetEntity + .substring(0, commentsIndexes.beforeStart) + .trim(); + targetEntity = `${RemoveNameQuantifiers(targetEntity)} ${generateComment(targetComment)}`; + } + else { + targetEntity = RemoveNameQuantifiers(targetEntity); + } + // const targetEntity = RemoveNameQuantifiers( + // edge.target.parent.value + // ); // entityA primary // entityB foreign const relationship = { - entityA: sourceIsPrimary ? sourceEntity : targetEntity, - entityB: sourceIsPrimary ? targetEntity : sourceEntity, + entityA: sourceIsPrimary + ? sourceEntity + : targetEntity, + entityB: sourceIsPrimary + ? targetEntity + : sourceEntity, // based off of styles? relSpec: { cardA: "ZERO_OR_MORE", cardB: "ONLY_ONE", - relType: "IDENTIFYING" + relType: "IDENTIFYING", }, - roleA: sourceIsPrimary ? - `[${sourceEntity}.${sourceId}] to [${targetEntity}.${targetId}]` : - `[${targetEntity}.${targetId}] to [${sourceEntity}.${sourceId}]` + roleA: sourceIsPrimary + ? `[${sourceEntity}.${sourceId}] to [${targetEntity}.${targetId}]` + : `[${targetEntity}.${targetId}] to [${sourceEntity}.${sourceId}]`, }; // check that is doesn't already exist - const exists = relationships.findIndex(r => r.entityA == relationship.entityA && r.entityB == relationship.entityB && r.roleA == relationship.roleA); + const exists = relationships.findIndex((r) => r.entityA == relationship.entityA && + r.entityB == relationship.entityB && + r.roleA == relationship.roleA); if (exists == -1) { relationships.push(relationship); } @@ -5520,8 +5657,10 @@ function getMermaidDiagramDb(ui, type) { targetId = targetAttr.attributeName; const targetEntity = RemoveNameQuantifiers(edge.target.parent.value); const compositeEntity = { - name: RemoveNameQuantifiers(sourceEntity) + "_" + RemoveNameQuantifiers(targetEntity), - attributes: [sourceAttr, targetAttr] + name: RemoveNameQuantifiers(sourceEntity) + + "_" + + RemoveNameQuantifiers(targetEntity), + attributes: [sourceAttr, targetAttr], }; // add composite entity if (entities[compositeEntity.name]) { @@ -5539,12 +5678,14 @@ function getMermaidDiagramDb(ui, type) { relSpec: { cardA: "ZERO_OR_MORE", cardB: "ONLY_ONE", - relType: "IDENTIFYING" + relType: "IDENTIFYING", }, - roleA: `[${sourceEntity}.${sourceId}] to [${compositeEntity.name}.${sourceId}]` + roleA: `[${sourceEntity}.${sourceId}] to [${compositeEntity.name}.${sourceId}]`, }; // check that is doesn't already exist - let exists = relationships.findIndex(r => r.entityA == relationship.entityA && r.entityB == relationship.entityB && r.roleA == relationship.roleA); + let exists = relationships.findIndex((r) => r.entityA == relationship.entityA && + r.entityB == relationship.entityB && + r.roleA == relationship.roleA); if (exists == -1) { relationships.push(relationship); } @@ -5555,12 +5696,14 @@ function getMermaidDiagramDb(ui, type) { relSpec: { cardA: "ZERO_OR_MORE", cardB: "ONLY_ONE", - relType: "IDENTIFYING" + relType: "IDENTIFYING", }, - roleA: `[${targetEntity}.${targetId}] to [${compositeEntity.name}.${targetId}]` + roleA: `[${targetEntity}.${targetId}] to [${compositeEntity.name}.${targetId}]`, }; // check that is doesn't already exist - exists = relationships.findIndex(r => r.entityA == relationship2.entityA && r.entityB == relationship2.entityB && r.roleA == relationship2.roleA); + exists = relationships.findIndex((r) => r.entityA == relationship2.entityA && + r.entityB == relationship2.entityB && + r.roleA == relationship2.roleA); if (exists == -1) { relationships.push(relationship2); } @@ -5590,6 +5733,12 @@ function getMermaidDiagramDb(ui, type) { const db = GenerateDatabaseModel(entities, relationships); return db; } +/** + * genearte a database model + * @param entities + * @param relationships + * @returns + */ function GenerateDatabaseModel(entities, relationships) { class DatabaseModel { constructor(entities, relationships) { @@ -5606,13 +5755,19 @@ function GenerateDatabaseModel(entities, relationships) { const db = new DatabaseModel(entities, relationships); return db; } +/** + * generate a comment using description and format + * @param description + * @param formatValue + * @returns + */ function generateComment(description, formatValue) { let result = ""; if (description) { result += `${description}`; } if (formatValue) { - result += ` @format ${formatValue}`; + result += ` ${constants_1.formatKeyword} ${formatValue}`; } if (result) { result = result.trim(); @@ -5620,5 +5775,174 @@ function generateComment(description, formatValue) { } return result; } +/** + * create uml tables from db models + * @param ui + * @param wndFromInput + * @param tableList + * @param cells + * @param rowCell + * @param tableCell + * @param foreignKeyList + * @param dx + * @param type + * @returns + */ +function CreateTableUI(ui, wndFromInput, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type) { + tableList.forEach(function (tableModel) { + //Define table size width + const maxNameLenght = 100 + tableModel.Name.length; + //Create Table + tableCell = new mxCell(tableModel.Name, new mxGeometry(dx, 0, maxNameLenght, 26), "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;"); + tableCell.vertex = true; + //Resize row + if (rowCell) { + const size = ui.editor.graph.getPreferredSizeForCell(rowCell); + if (size !== null) { + tableCell.geometry.width = size.width + maxNameLenght; + } + } + //Add Table to cells + cells.push(tableCell); + //Add properties + tableModel.Properties.forEach(function (propertyModel) { + //Add row + const addRowResult = AddRow(ui, propertyModel, tableModel.Name, rowCell, tableCell); + if (addRowResult) { + rowCell = addRowResult.rowCell; + tableCell = addRowResult.tableCell; + } + }); + //Close table + dx += tableCell.geometry.width + 40; + tableCell = null; + }); + if (cells.length > 0) { + const graph = ui.editor.graph; + const view = graph.view; + const bds = graph.getGraphBounds(); + // Computes unscaled, untranslated graph bounds + const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize); + const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + + 4 * graph.gridSize); + graph.setSelectionCells(graph.importCells(cells, x, y)); + // add foreign key edges + const model = graph.getModel(); + const columnQuantifiers = GetColumnQuantifiers(type); + // const pt = graph.getFreeInsertPoint(); + foreignKeyList.forEach(function (fk) { + if (fk.IsDestination && + fk.PrimaryKeyName && + fk.ReferencesPropertyName && + fk.PrimaryKeyTableName && + fk.ReferencesTableName) { + const insertEdge = mxUtils.bind(this, function (targetCell, sourceCell, edge) { + const label = ""; + const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; + const edgeCell = graph.insertEdge(null, null, label || "", edge.invert ? sourceCell : targetCell, edge.invert ? targetCell : sourceCell, edgeStyle); + }); + const edge = { + invert: true, + }; + let targetCell = null; + let sourceCell = null; + // locate edge source and target cells + for (const key in model.cells) { + if (targetCell && sourceCell) + break; + if (Object.hasOwnProperty.call(model.cells, key)) { + const mxcell = model.cells[key]; + if (mxcell.style && mxcell.style.trim().startsWith("swimlane;")) { + const entity = { + name: mxcell.value, + attributes: [], + }; + const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; + const isForeignTable = entity.name == fk.ReferencesTableName; + if (isPrimaryTable || isForeignTable) { + for (let c = 0; c < mxcell.children.length; c++) { + if (targetCell && sourceCell) + break; + const col = mxcell.children[c]; + if (col.mxObjectId.indexOf("mxCell") !== -1) { + if (col.style && + col.style.trim().startsWith("shape=partialRectangle")) { + const attribute = getDbLabel(col.value, columnQuantifiers); + if (isPrimaryTable && + dbTypeEnds(attribute.attributeName) == fk.PrimaryKeyName) { + targetCell = col; + // allow recursion + } + if (isForeignTable && + dbTypeEnds(attribute.attributeName) == + fk.ReferencesPropertyName) { + sourceCell = col; + } + if (targetCell && sourceCell) + break; + } + } + } + } + } + } + } + if (targetCell && sourceCell) + insertEdge(targetCell, sourceCell, edge); + } + }); + graph.scrollCellToVisible(graph.getSelectionCell()); + } + wndFromInput.setVisible(false); + return { + cells, + rowCell, + tableCell, + dx, + }; +} +/** + * add row to uml table + * @param ui + * @param propertyModel + * @param tableName + * @param rowCell + * @param tableCell + * @returns + */ +function AddRow(ui, propertyModel, tableName, rowCell, tableCell) { + const cellName = propertyModel.Name + + (propertyModel.ColumnProperties + ? " " + propertyModel.ColumnProperties + : ""); + rowCell = new mxCell(cellName, new mxGeometry(0, 0, 90, 26), "shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;"); + rowCell.vertex = true; + const columnType = propertyModel.IsPrimaryKey && propertyModel.IsForeignKey + ? "PK | FK" + : propertyModel.IsPrimaryKey + ? "PK" + : propertyModel.IsForeignKey + ? "FK" + : ""; + const left = sb.cloneCell(rowCell, columnType); + left.connectable = false; + left.style = + "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;"; + left.geometry.width = 54; + left.geometry.height = 26; + rowCell.insert(left); + const size = ui.editor.graph.getPreferredSizeForCell(rowCell); + if (tableCell) { + if (size !== null && tableCell.geometry.width < size.width + 10) { + tableCell.geometry.width = size.width + 10; + } + tableCell.insert(rowCell); + tableCell.geometry.height += 26; + } + return { + rowCell, + tableCell, + }; +} -},{"./constants":29}]},{},[28]); +},{"./constants":30}]},{},[28]); diff --git a/dist/nosql.min.js b/dist/nosql.min.js index 4a6dcc7..a4fbce5 100644 --- a/dist/nosql.min.js +++ b/dist/nosql.min.js @@ -1,9 +1,31 @@ -!function r(o,i,a){function l(t,e){if(!i[t]){if(!o[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(s)return s(t,!0);throw(e=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",e}n=i[t]={exports:{}},o[t][0].call(n.exports,function(e){return l(o[t][1][e]||e)},n,n.exports,r,o,i,a)}return i[t].exports}for(var s="function"==typeof require&&require,e=0;e(0,o.ensureArray)(t).map(e=>"@see "+e).join("\n");if(e&&null!=t&&t.length)return e+"\n\n"+n();return e||n()}(e.description,e.see):void 0;return{...t,...e.title?{title:e.title}:{},...n?{description:n}:{},...e.default?{default:e.default}:{},...e.examples?{examples:e.examples}:{},...e.comment?{$comment:e.comment}:{}}},n.annotateCoreTypes=function(e,t){var{description:n,see:r}=function(e){var t=(null!=e?e:"").split("\n"),n=[];for(;0s(e)),e=(0,a.annotateJsonSchema)(e,{anyOf:t});return 1{return e=e,!(1===(e=Object.keys(e).sort()).length&&"type"===e[0]||2===e.length&&"title"===e[0]&&"type"===e[1])})&&(delete e.anyOf,e.type=t.map(({type:e})=>e)),e}function s(t){if("any"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{}));if("null"===t.type)return(0,a.annotateJsonSchema)(t,{type:"null"});if("boolean"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{type:"boolean"}));if("string"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{type:"string"}));if("number"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{type:"number"}));if("integer"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{type:"integer"}));if("and"===t.type)return(0,a.annotateJsonSchema)(t,{allOf:t.and.map(e=>s(e))});if("or"===t.type)return l(t);var e,n,r;if("object"===t.type)return n=(e=Object.keys(t.properties)).filter(e=>t.properties[e].required),r=Object.fromEntries(e.map(e=>[e,s(t.properties[e].node)])),(0,a.annotateJsonSchema)(t,u(t,{type:"object",...0s(e)),...!0===t.additionalItems?{}:t.additionalItems?{additionalItems:s(t.additionalItems)}:{additionalItems:!1},minItems:t.minItems}));if("ref"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{$ref:(0,o.encodeRefNameJsonSchema)(t.ref)}));throw new i.UnsupportedError(`core-types node of type ${t.type} not supported`,t)}function u(e,t){return void 0!==e.const?{...t,const:e.const}:e.enum?{...t,enum:e.enum}:t}n.decorateSchema=r,n.convertCoreTypesToJsonSchema=function(e,t){var{version:e,types:n}=e;if(1!==e)throw new i.UnsupportedError(`core-types version ${e} not supported`);return r(e={definitions:Object.fromEntries(n.map(e=>[e.name,s(e)]))},null!=t?t:{}),{data:e,convertedTypes:n.map(({name:e})=>e),notConvertedTypes:[]}}},{"./annotations":2,"core-types":6,"openapi-json-schema":18}],4:[function(e,t,c){Object.defineProperty(c,"__esModule",{value:!0}),c.complexProps=c.convertJsonSchemaToCoreTypes=void 0;let i=e("jsonpos"),p=e("openapi-json-schema"),O=e("core-types"),f=e("./annotations"),d=(e,t)=>({...e,path:[...e.path,t]});function m(n,l){if("boolean"==typeof n)l.throwUnsupportedError("Boolean JSON Schema definition not supported",{blob:{schema:n}});else if("object"==typeof(e=n)&&Object.keys(e).some(e=>c.complexProps.has(e))){e=function(t,n){let{$ref:r,type:a,enum:l,const:s,items:u,additionalItems:c,required:p,properties:f,additionalProperties:d,then:e,else:o,allOf:i,anyOf:m,oneOf:y}=t;var h=i&&"object"==typeof i?i.filter(e=>e&&"object"==typeof e):null,b=m&&"object"==typeof m?m.filter(e=>e&&"object"==typeof e):null,g=y&&"object"==typeof y?y.filter(e=>e&&"object"==typeof e):null;let v=(e,o)=>{var i=(e,t)=>!(e&&t&&!(0,O.isEqual)(e,t));if(i(r,o.$ref)||n.throwUnsupportedError(`Cannot have $ref in a node *and* in its '${e}'`,{blob:t}),i(a,o.type)||n.throwUnsupportedError(`Cannot have 'type' in a node *and* in its '${e}'`,{blob:t}),l)if(o.enum){var i=(0,O.intersection)(l,o.enum);if(0===i.length)throw new O.MalformedTypeError("Cannot merge types with non-intersecting enums",{path:n.path,blob:{child:[...n.path,e]}});o.enum=i}else o.enum=l;if(void 0!==s)if(void 0!==o.const){if((0,O.isEqual)(s,o.const))throw new O.MalformedTypeError("Cannot merge types with mismatching const",{path:n.path,blob:{child:[...n.path,e]}})}else o.const=s;if(o.items=null!=(i=o.items)?i:u,o.additionalItems=null!=(e=o.additionalItems)?e:c,void 0===p&&void 0===o.required||(o.required=(0,O.union)(null!=(i=o.required)?i:[],null!==p&&void 0!==p?p:[])),void 0===f!=(void 0===o.properties))null!=o.properties||(o.properties=f);else if(void 0!==f){let t=f,n=o.properties;e=Object.keys(t),i=Object.keys(n),e=(0,O.union)(e,i);let r={};e.forEach(e=>{void 0!==t[e]?r[e]=n[e]:void 0!==n[e]?r[e]=t[e]:r[e]={allOf:[t[e],n[e]]}})}void 0===d!=(void 0===o.additionalProperties)?null==o.additionalProperties&&(o.additionalProperties=d):void 0!==d&&(o.additionalProperties={allOf:[o.additionalProperties,d]})};return e&&"object"==typeof e&&v("then",e),o&&"object"==typeof o&&v("else",o),h&&"object"==typeof h&&h.forEach(e=>v("allOf",e)),b&&"object"==typeof b&&b.forEach(e=>v("anyOf",e)),g&&"object"==typeof g&&g.forEach(e=>v("oneOf",e)),{...e&&"object"==typeof e?{then:e}:{},...o&&"object"==typeof o?{else:o}:{},...h&&"object"==typeof h?{allOf:h}:{},...b&&"object"==typeof b?{anyOf:b}:{},...g&&"object"==typeof g?{oneOf:g}:{}}}(n,l);var r=l;var{then:e,else:t,allOf:o,anyOf:i,oneOf:a}=e,e=[...e?[[d(r,"then"),e]]:[],...t?[[d(r,"else"),t]]:[]],t=[...i?i.map((e,t)=>[d(d(r,"anyOf"),t),e]):[],...a?a.map((e,t)=>[d(d(r,"oneOf"),t),e]):[]],i=[...o?o.map((e,t)=>[d(d(r,"allOf"),t),e]):[]];return{type:"and",and:[{type:"or",or:e.map(([e,t])=>m(t,e))},{type:"or",or:t.map(([e,t])=>m(t,e))},{type:"and",and:i.map(([e,t])=>m(t,e))}]};return}void 0===n&&l.throwUnsupportedError("Internal error",{blob:{schema:n}});let s=e=>({type:"ref",ref:(0,p.decodeRefNameJsonSchema)(e)});var a=e=>void 0===n.$ref?e:{type:"and",and:[e,s(n.$ref)]},{const:o,enum:e}=n;let u={...void 0!==o?{const:o}:{},...void 0!==e?{enum:e}:{}};return void 0===n.type?n.$ref?{...s(n.$ref),...u}:{type:"any",...u}:1===(t=(0,O.ensureArray)(n.type).map(e=>{var t,r=n,o=u,i=l;if(y(e))return"null"===e?(0,f.annotateCoreTypes)({type:"null"},r):(0,f.annotateCoreTypes)({type:e,...o},r);if("array"===e)return Array.isArray(r.items)?(0,f.annotateCoreTypes)({type:"tuple",elementTypes:r.items.map(e=>m(e,d(i,"items"))),additionalItems:void 0===r.additionalItems||("boolean"==typeof r.additionalItems?r.additionalItems:m(r.additionalItems,d(i,"additionalItems"))),minItems:null!=(a=r.minItems)?a:0,...o},r):!1===r.items?(0,f.annotateCoreTypes)({type:"tuple",elementTypes:[],additionalItems:!1,minItems:0,...o},r):(0,f.annotateCoreTypes)({type:"array",elementType:void 0===r.items||!0===r.items?{type:"any"}:m(r.items,d(i,"items")),...o},r);if("object"===e){let n=new Set(null!=(a=r.required)?a:[]);var a=null!=(a=r.additionalProperties)?a:i.defaultAdditionalProperties;return(0,f.annotateCoreTypes)({type:"object",properties:Object.fromEntries(Object.entries(null!=(t=r.properties)?t:{}).map(([e,t])=>[e,{node:m(t,d(d(i,"properties"),e)),required:n.has(e)}])),additionalProperties:"boolean"==typeof a?a:m(a,d(i,"additionalProperties")),...o},r)}i.throwUnsupportedError(`Unsupported JSON Schema type "${e}"`,{blob:{schema:r}})})).length?a(t[0]):a({type:"or",or:t})}c.convertJsonSchemaToCoreTypes=function(e,n={}){let r=("string"==typeof e?(0,i.getAstByString):(0,i.getAstByObject))(e),o=(e=r.json)["definitions"];return{data:e={version:1,types:Object.keys(null!==o&&void 0!==o?o:{}).map(e=>{var t;return{...m((null!==o&&void 0!==o?o:{})[e],{locByPath(){return{path:this.path,loc:(0,i.getLocation)(r,{dataPath:this.path,markIdentifier:!0})}},path:["definitions",e],throwUnsupportedError(e,t){throw(t={...t}).path||(t.path=this.path),t.loc||(t.loc=(0,i.getLocation)(r,{dataPath:this.path,markIdentifier:!0})),new O.UnsupportedError(e,t)},defaultAdditionalProperties:null==(t=n.defaultAdditionalProperties)||t}),name:e}})},convertedTypes:e.types.map(({name:e})=>e),notConvertedTypes:[]}},c.complexProps=new Set(["anyOf","allOf","oneOf","then","else"]);let y=e=>["string","number","integer","boolean","null"].includes(e)},{"./annotations":2,"core-types":6,jsonpos:25,"openapi-json-schema":18}],5:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.convertOpenApiToCoreTypes=n.convertCoreTypesToOpenApi=void 0;let o=e("openapi-json-schema"),i=e("./core-types-to-json-schema"),r=e("./json-schema-to-core-types");n.convertCoreTypesToOpenApi=function(e,t){let{data:n,...r}=(0,i.convertCoreTypesToJsonSchema)(e,t);return{...r,data:(0,o.jsonSchemaDocumentToOpenApi)(n,t)}},n.convertOpenApiToCoreTypes=function(e){return e="string"==typeof e?JSON.parse(e):e,e=(0,o.openApiToJsonSchema)(e),(0,r.convertJsonSchemaToCoreTypes)(e)}},{"./core-types-to-json-schema":3,"./json-schema-to-core-types":4,"openapi-json-schema":18}],6:[function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){e[r=void 0===r?n:r]=t[n]}),o=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)},i=(Object.defineProperty(n,"__esModule",{value:!0}),n.traverse=n.some=n.mergeLocations=n.getPositionOffset=n.locationToLineColumn=n.positionToLineColumn=n.decorateError=n.decorateErrorMeta=n.isCoreTypesError=n.throwRelatedError=n.throwUnsupportedError=n.RelatedError=n.UnsupportedError=n.MissingReferenceError=n.MalformedTypeError=n.formatSee=n.formatDefault=n.formatExamples=n.stringify=n.stripAnnotations=n.stringifyAnnotations=n.extractAnnotations=n.mergeAnnotations=n.isNonNullable=n.union=n.intersection=n.isEqual=n.hasConstEnum=n.isPrimitiveType=n.ensureArray=n.validate=n.simplify=void 0,o(e("./lib/types"),n),e("./lib/simplify")),a=(Object.defineProperty(n,"simplify",{enumerable:!0,get:function(){return i.simplify}}),e("./lib/validate")),l=(Object.defineProperty(n,"validate",{enumerable:!0,get:function(){return a.validate}}),e("./lib/util")),s=(Object.defineProperty(n,"ensureArray",{enumerable:!0,get:function(){return l.ensureArray}}),Object.defineProperty(n,"isPrimitiveType",{enumerable:!0,get:function(){return l.isPrimitiveType}}),Object.defineProperty(n,"hasConstEnum",{enumerable:!0,get:function(){return l.hasConstEnum}}),Object.defineProperty(n,"isEqual",{enumerable:!0,get:function(){return l.isEqual}}),Object.defineProperty(n,"intersection",{enumerable:!0,get:function(){return l.intersection}}),Object.defineProperty(n,"union",{enumerable:!0,get:function(){return l.union}}),Object.defineProperty(n,"isNonNullable",{enumerable:!0,get:function(){return l.isNonNullable}}),e("./lib/annotation")),u=(Object.defineProperty(n,"mergeAnnotations",{enumerable:!0,get:function(){return s.mergeAnnotations}}),Object.defineProperty(n,"extractAnnotations",{enumerable:!0,get:function(){return s.extractAnnotations}}),Object.defineProperty(n,"stringifyAnnotations",{enumerable:!0,get:function(){return s.stringifyAnnotations}}),Object.defineProperty(n,"stripAnnotations",{enumerable:!0,get:function(){return s.stripAnnotations}}),Object.defineProperty(n,"stringify",{enumerable:!0,get:function(){return s.stringify}}),Object.defineProperty(n,"formatExamples",{enumerable:!0,get:function(){return s.formatExamples}}),Object.defineProperty(n,"formatDefault",{enumerable:!0,get:function(){return s.formatDefault}}),Object.defineProperty(n,"formatSee",{enumerable:!0,get:function(){return s.formatSee}}),e("./lib/error")),c=(Object.defineProperty(n,"MalformedTypeError",{enumerable:!0,get:function(){return u.MalformedTypeError}}),Object.defineProperty(n,"MissingReferenceError",{enumerable:!0,get:function(){return u.MissingReferenceError}}),Object.defineProperty(n,"UnsupportedError",{enumerable:!0,get:function(){return u.UnsupportedError}}),Object.defineProperty(n,"RelatedError",{enumerable:!0,get:function(){return u.RelatedError}}),Object.defineProperty(n,"throwUnsupportedError",{enumerable:!0,get:function(){return u.throwUnsupportedError}}),Object.defineProperty(n,"throwRelatedError",{enumerable:!0,get:function(){return u.throwRelatedError}}),Object.defineProperty(n,"isCoreTypesError",{enumerable:!0,get:function(){return u.isCoreTypesError}}),Object.defineProperty(n,"decorateErrorMeta",{enumerable:!0,get:function(){return u.decorateErrorMeta}}),Object.defineProperty(n,"decorateError",{enumerable:!0,get:function(){return u.decorateError}}),e("./lib/location")),p=(Object.defineProperty(n,"positionToLineColumn",{enumerable:!0,get:function(){return c.positionToLineColumn}}),Object.defineProperty(n,"locationToLineColumn",{enumerable:!0,get:function(){return c.locationToLineColumn}}),Object.defineProperty(n,"getPositionOffset",{enumerable:!0,get:function(){return c.getPositionOffset}}),Object.defineProperty(n,"mergeLocations",{enumerable:!0,get:function(){return c.mergeLocations}}),e("./lib/traverse"));Object.defineProperty(n,"some",{enumerable:!0,get:function(){return p.some}}),Object.defineProperty(n,"traverse",{enumerable:!0,get:function(){return p.traverse}})},{"./lib/annotation":7,"./lib/error":8,"./lib/location":9,"./lib/simplify":13,"./lib/traverse":14,"./lib/types":15,"./lib/util":16,"./lib/validate":17}],7:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.stringify=n.formatSee=n.formatDefault=n.formatExamples=n.arrayOrSingle=n.stripAnnotations=n.stringifyAnnotations=n.wrapWhitespace=n.extractAnnotations=n.mergeAnnotations=void 0;let c=e("./location"),p=e("./util");function l(e){return e.includes("\n")?["*",e.split("\n").map(e=>" * "+e).join("\n")," "].join("\n"):e.startsWith(" ")?e:" "+e}function f(e){return 1===e.length?e[0]:e}function s(e){return e.map(e=>"@example\n"+o(r(e).split("\n"),4)).join("\n").trim()}function u(e){return["@default",o(r(e).split("\n"),4)].join("\n").trim()}function d(e){return e.map(e=>"@see "+r(e)).join("\n").trim()}function r(e){return"string"==typeof e?e:JSON.stringify(e,null,2)}function o(e,n,r=!1){return e.map((e,t)=>{return(0===t&&r?" ".repeat(n-2)+"* ":" ".repeat(n))+e}).join("\n")}n.mergeAnnotations=function(e){let t,n=e=>!!e;var r=(e,t="\n")=>(0,p.uniq)(e.filter(n)).join(t).trim(),o=null==(t=e.find(e=>e.name))?void 0:t.name,i=r(e.map(e=>e.title),", "),a=r(e.map(e=>e.description)),l=(0,p.uniq)([].concat(...e.map(e=>(0,p.ensureArray)(e.examples))).filter(n)),s=r(e.map(e=>e.default)),u=(0,p.uniq)([].concat(...e.map(e=>(0,p.ensureArray)(e.see))).filter(n)),r=r(e.map(e=>e.comment)),e=(0,c.mergeLocations)(e.map(e=>e.loc));return{...o?{name:o}:{},...i?{title:i}:{},...a?{description:a}:{},...0e).join("\n\n").trim().replace(/\*\//g,"*\\/");return n&&e?l(e):e},n.stripAnnotations=function t(e,n=!0){let{comment:r,description:o,default:i,examples:a,see:l,title:s,...u}=e,c=u;if(n){if("and"===c.type)return{...c,and:c.and.map(e=>t(e,!0))};if("or"===c.type)return{...c,or:c.or.map(e=>t(e,!0))};if("array"===c.type)return{...c,elementType:t(c.elementType,!0)};if("tuple"===c.type)return{...c,elementTypes:c.elementTypes.map(e=>t(e,!0)),additionalItems:"object"==typeof c.additionalItems?t(c.additionalItems,!0):c.additionalItems};if("object"===c.type)return{...c,properties:Object.fromEntries(Object.keys(c.properties).map(e=>[e,{...c.properties[e],node:t(c.properties[e].node,!0)}])),additionalProperties:"object"==typeof c.additionalProperties?t(c.additionalProperties,!0):c.additionalProperties}}return c},n.arrayOrSingle=f,n.formatExamples=s,n.formatDefault=u,n.formatSee=d,n.stringify=r},{"./location":9,"./util":16}],8:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.decorateError=n.decorateErrorMeta=n.isCoreTypesError=n.throwRelatedError=n.throwUnsupportedError=n.RelatedError=n.UnsupportedError=n.MissingReferenceError=n.MalformedTypeError=n.CoreTypesError=void 0;class r extends Error{constructor(e,t={}){super(e),Object.setPrototypeOf(this,r.prototype),this.blob=t.blob,this.path=t.path,this.loc=t.loc,this.source=t.source,this.filename=t.filename,this.relatedError=t.relatedError}}n.CoreTypesError=r;class o extends r{constructor(e,t={}){super(e,t),Object.setPrototypeOf(this,o.prototype)}}n.MalformedTypeError=o;class i extends r{constructor(e,t={}){super(`Reference to missing type "${e}"`,t),Object.setPrototypeOf(this,i.prototype)}}n.MissingReferenceError=i;class a extends r{constructor(e,t={}){super(e,t),Object.setPrototypeOf(this,a.prototype)}}n.UnsupportedError=a;class l extends r{constructor(e,t={}){super(e.message,{...t,relatedError:e}),Object.setPrototypeOf(this,l.prototype)}}function s(e){return e instanceof r}function u(e,t){return t.blob&&null==e.blob&&(e.blob=t.blob),t.path&&null==e.path&&(e.path=t.path),t.loc&&null==e.loc&&(e.loc=t.loc),t.source&&null==e.source&&(e.source=t.source),t.filename&&null==e.filename&&(e.filename=t.filename),e}n.RelatedError=l,n.throwUnsupportedError=function(e,t,n){throw new a(e,{blob:t,...t.loc?{loc:t.loc}:{},...n?{path:n}:{}})},n.throwRelatedError=function(e,t){throw new l(e,t)},n.isCoreTypesError=s,n.decorateErrorMeta=u,n.decorateError=function(e,t){return s(e)&&u(e,t),e}},{}],9:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.mergeLocations=n.getPositionOffset=n.locationToLineColumn=n.positionToLineColumn=void 0;let s=e("./util");function r(e,t){var n=e.slice(0,t).split("\n").length,e=e.lastIndexOf("\n",t);return-1===e?{offset:t,line:n,column:t}:{offset:t,line:n,column:t-e}}n.positionToLineColumn=r,n.locationToLineColumn=function(e,t){return"object"==typeof t.start?t:{start:void 0===t.start?void 0:r(e,t.start),...null==t.end?{}:{end:r(e,t.end)}}},n.getPositionOffset=function(e){return void 0===e||"number"==typeof e?e:e.offset},n.mergeLocations=function(e){let t,n,r,o,i,a=e=>"number"==typeof e?e:null==e?void 0:e.offset;e.filter(s.isNonNullable).forEach(({start:e,end:t})=>{var n=a(e),r=a(t);void 0!==n&&(!o||"number"==typeof o.location&&o.location===n||o.offset>n)&&(o={location:e,offset:n}),void 0!==r&&(!i||"number"==typeof i.location&&i.location===n||i.offseti(e))).some(e=>0===e.length)?[]:(0,r.uniq)([].concat(...e))},n.combineConstAndEnum=i},{"../util":16}],11:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.intersectConstEnum=void 0;let r=e("../annotation"),o=e("../util");n.intersectConstEnum=function(e){if(0===e.length)throw new Error("Cannot intersect const and enum from an empty array of nodes");var t;return 1===e.length?e[0]:(t=(t=e.map(e=>void 0!==e.const?[e.const]:void 0!==e.enum?e.enum:void 0).filter(e=>!!e)).slice(1).reduce((e,t)=>(0,o.intersection)(e,t),t[0]),{type:e[0].type,...1===t.length?{const:t[0]}:{},...1!==t.length?{enum:t}:{},...(0,r.mergeAnnotations)(e)})}},{"../annotation":7,"../util":16}],12:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.simplifySingle=void 0;let r=e("./const-enum");n.simplifySingle=function(e){return"boolean"===e.type||"integer"===e.type||"number"===e.type||"string"===e.type?(0,r.simplifyEnumAndConst)(e):e}},{"./const-enum":10}],13:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.simplify=void 0;let a=e("./simplifications/single"),l=e("./simplifications/const-enum"),o=e("./simplifications/intersect-const-enum"),i=e("./error"),s=e("./annotation"),u=e("./util"),c=["any","string","number","integer","boolean"];n.simplify=function r(t){if(Array.isArray(t))return t.map(e=>r(e));if((0,u.isNodeDocument)(t))return{...t,types:r(t.types)};var e,n=e=>(0,u.copyName)(t,e);if("tuple"===t.type)return{...t,elementTypes:t.elementTypes.map(e=>r(e)),...t.additionalItems&&"object"==typeof t.additionalItems?{additionalItems:r(t.additionalItems)}:{}};if("array"===t.type)return{...t,elementType:r(t.elementType)};if("object"===t.type)return{...t,properties:Object.fromEntries(Object.entries(t.properties).map(([e,{node:t,required:n}])=>[e,{node:r(t),required:n}])),...t.additionalProperties&&"object"==typeof t.additionalProperties?{additionalProperties:r(t.additionalProperties)}:{}};if("and"!==t.type&&"or"!==t.type)return n((0,a.simplifySingle)(t));if("and"===t.type)return 1===(e=function(e){if(0<(e=(0,u.splitTypes)(e)).any.length){if(0===e.and.length&&0===e.or.length&&0===e.ref.length&&0===e.null.length&&0===e.string.length&&0===e.number.length&&0===e.integer.length&&0===e.boolean.length&&0===e.object.length&&0===e.array.length&&0===e.tuple.length)return[{type:"any",...(0,s.mergeAnnotations)(e.any.map(({node:e})=>e))}];e.any=[]}var t=e=>e.map(({node:e})=>e);return 1e),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.boolean)}]),1e),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.string)}]),0e),...t(e.integer),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.number)}],e.integer=[]):1e),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.number)}]:1e),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.integer)}]),000(e=r(e)).and||[e])))).length?n({...e[0],...(0,s.mergeAnnotations)([(0,s.extractAnnotations)(t),e[0]])}):n({type:"and",and:e,...(0,s.extractAnnotations)(t)});if("or"===t.type)return 1===(e=function(e){var t,n,r,o,i=(0,u.splitTypes)(e);if(0e)).length)return[{type:"any",...(0,s.mergeAnnotations)(i.any.map(({node:e})=>e))}];for([t,n]of Object.entries(i))c.includes(t)&&n.length&&(r=n.map(({node:e})=>e),0===(o=(0,l.mergeConstEnumUnion)(r)).length?i[t]=[{node:{type:t,...(0,s.mergeAnnotations)(r)},order:(0,u.firstSplitTypeIndex)(n)}]:i[t]=[{node:(0,a.simplifySingle)({type:t,enum:o,...(0,s.mergeAnnotations)(r)}),order:(0,u.firstSplitTypeIndex)(n)}]);return 000(e=r(e)).or||[e])))).length?n({...e[0],...(0,s.mergeAnnotations)([(0,s.extractAnnotations)(t),e[0]])}):n({type:"or",or:e,...(0,s.extractAnnotations)(t)});throw new i.MalformedTypeError("Invalid node",t)}},{"./annotation":7,"./error":8,"./simplifications/const-enum":10,"./simplifications/intersect-const-enum":11,"./simplifications/single":12,"./util":16}],14:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.some=n.traverse=void 0;class r extends Error{}function o(e,t){function a(e,t,n,r,o,i){var i=void 0!==i?i:void 0===r?t[n]:t[n][r],a=[...e.path,n,...void 0===r?[]:[r]];return Object.assign({},e,{node:i,path:a,parentNode:t,parentProperty:n,index:r,required:o})}!function n(r,o){o(r);let i=r.node;if("array"===i.type)n(a(r,i,"elementType"),o);else if("tuple"===i.type)i.elementTypes.forEach((e,t)=>n(a(r,i,"elementTypes",t),o)),"object"==typeof i.additionalItems&&n(a(r,i,"additionalItems"),o);else if("object"===i.type){for(var e of Object.keys(i.properties))n(a(r,i,"properties",e,i.properties[e].required,i.properties[e].node),o);"object"==typeof i.additionalProperties&&n(a(r,i,"additionalProperties"),o)}else"and"===i.type?i.and.forEach((e,t)=>n(a(r,i,"and",t),o)):"or"===i.type&&i.or.forEach((e,t)=>n(a(r,i,"or",t),o))}({node:e,rootNode:e,path:[]},t)}n.traverse=o,n.some=function(e,t){try{o(e,e=>{if(t(e))throw new r})}catch(e){if(e instanceof r)return!0;throw e}return!1}},{}],15:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0})},{}],16:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.isNodeDocument=n.isNonNullable=n.copyName=n.firstSplitTypeIndex=n.flattenSplitTypeValues=n.splitTypes=n.union=n.intersection=n.isEqual=n.hasConstEnum=n.constEnumTypes=n.isPrimitiveType=n.ensureArray=n.uniq=void 0,n.uniq=function(r){return r.filter((t,n)=>{for(let e=0;e["null","string","number","integer","boolean"].includes(e.type),n.constEnumTypes=new Set(["any","string","number","integer","boolean","object","array","tuple","ref"]);function o(t,n){var e;return typeof t==typeof n&&!(null===t!=(null===n)||null!==t&&(Array.isArray(t)&&Array.isArray(n)?t.length!==n.length||t.some((e,t)=>!o(e,n[t])):Array.isArray(t)!==Array.isArray(n)||("object"==typeof t?!o(e=Object.keys(t).sort(),Object.keys(n).sort())||e.some(e=>!o(t[e],n[e])):t!==n)))}n.hasConstEnum=e=>n.constEnumTypes.has(e.type),n.isEqual=o,n.intersection=function(e,n){let r=[];return e.forEach(t=>{n.forEach(e=>{o(t,e)&&r.push(t)})}),r},n.union=function(e,t){let n=[...e];return t.forEach(t=>{e.some(e=>o(t,e))||n.push(t)}),n},n.splitTypes=function(e){let n={and:[],or:[],ref:[],any:[],null:[],string:[],number:[],integer:[],boolean:[],object:[],array:[],tuple:[]};return e.forEach((e,t)=>{("and"!==e.type&&"or"!==e.type||"and"===e.type&&0e.order-t.order).map(({node:e})=>e))},n.firstSplitTypeIndex=function(e){return Math.min(...e.map(({order:e})=>e))},n.copyName=function(e,t){return void 0===e.name?t:{...t,name:e.name}},n.isNonNullable=function(e){return null!=e},n.isNodeDocument=function(e){return Array.isArray(e.types)}},{}],17:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.validate=void 0;let r=e("./error"),o=e("./util");n.validate=function t(e){if((0,o.hasConstEnum)(e)){var n=e;if(n.enum&&0===n.enum.length)throw new r.MalformedTypeError("Empty enum is not allowed",n);if(n.enum&&void 0!==n.const&&!n.enum.some(e=>(0,o.isEqual)(e,n.const)))throw new r.MalformedTypeError("Enum and const are both set, but enum doesn't contain const",n)}"and"===e.type&&e.and.forEach(e=>t(e)),"or"===e.type&&e.or.forEach(e=>t(e))}},{"./error":8,"./util":16}],18:[function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){e[r=void 0===r?n:r]=t[n]}),o=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(n,"__esModule",{value:!0}),o(e("./lib"),n),o(e("./lib/types"),n),o(e("./lib/utils"),n)},{"./lib":19,"./lib/types":22,"./lib/utils":23}],19:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.openApiToJsonSchema=n.jsonSchemaDocumentToOpenApi=n.decorateOpenApi=void 0;let o=e("./json-schema-to-openapi"),r=e("./openapi-to-json-schema");function i(e,{title:t,version:n,schemaVersion:r="3.0.0"}){t={title:t,version:n};return e.$id&&(t["x-id"]=e.$id,delete e.$id),e.$comment&&(t["x-comment"]=e.$comment,delete e.$comment),delete e.$schema,{openapi:r,info:t,paths:{},...e}}n.decorateOpenApi=i,n.jsonSchemaDocumentToOpenApi=function(e,t){let{definitions:n={},...r}=e;return i({...r,components:{schemas:Object.fromEntries(Object.entries(n).map(([e,t])=>[e,(0,o.jsonSchemaTypeToOpenApi)(t)]))}},t)},n.openApiToJsonSchema=function(e){let t=e.components.schemas;return{definitions:Object.fromEntries(Object.keys(t).map(e=>[e,(0,r.openApiToJsonSchemaType)(t[e])]))}}},{"./json-schema-to-openapi":20,"./openapi-to-json-schema":21}],20:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.jsonSchemaTypeToOpenApi=void 0;let r=e("./utils");n.jsonSchemaTypeToOpenApi=function e(t){var n;return"boolean"==typeof t?t:(t=function(e){if(void 0===e.type)return e;let{type:t,...n}=e,r=Array.isArray(t)?t.includes("null"):"null"===t;var o=Array.isArray(t)?t.filter(e=>"null"!==e):"null"===t?void 0:t;let i=(e,t)=>"any"!==t&&t?{...e,type:t}:e;return void 0!==e.const&&(n.enum=[e.const],delete n.const),e=e=>r?{...e,nullable:r}:e,Array.isArray(o)?0===o.length?e(n):1===o.length?i(e(n),o[0]):{...e(n),anyOf:o.map(e=>i({},e))}:i(e(n),o)}(t),t=(n=t).$ref?{...n,$ref:(0,r.encodeRefNameOpenApi)((0,r.decodeRefNameJsonSchema)(n.$ref))}:n,(0,r.recurseSchema)(t,e))}},{"./utils":23}],21:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.openApiToJsonSchemaType=void 0;let a=e("./utils");n.openApiToJsonSchemaType=function e(t){if("boolean"==typeof t)return t;let{type:n,nullable:r,...o}=t;var i,t=function(e,t){if(void 0!==e&&"any"!==e)return Array.isArray(e)?e.includes("any")?void 0:(!e.includes("null")&&t&&e.push("null"),1===e.length?e[0]:e):"null"!==e&&t?[e,"null"]:e}(n,r),t={...o,...t?{type:t}:{}},t=(i=t).$ref?{...i,$ref:(0,a.encodeRefNameJsonSchema)((0,a.decodeRefNameOpenApi)(i.$ref))}:i;return(0,a.recurseSchema)(t,e)}},{"./utils":23}],22:[function(e,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],23:[function(e,t,n){function r(e){return encodeURIComponent(e)}function o(e){return decodeURIComponent(e)}function i(e){return e&&0n(e))}:{items:n(r.items)},..."object"!=typeof r.additionalItems?{}:{additionalItems:n(r.additionalItems)},..."object"!=typeof r.contains?{}:{contains:n(r.contains)},...i(r.properties)?{properties:Object.fromEntries(Object.keys(r.properties).map(e=>{var t;return[e,n(null==(t=r.properties)?void 0:t[e])]}))}:{},...i(r.patternProperties)?{patternProperties:Object.fromEntries(Object.keys(r.patternProperties).map(e=>{var t;return[e,n(null==(t=r.patternProperties)?void 0:t[e])]}))}:{},..."object"!=typeof r.additionalProperties?{}:{additionalProperties:n(r.additionalProperties)},...i(r.dependencies)?{dependencies:Object.fromEntries(Object.keys(r.dependencies).map(e=>{var t;return[e,n(null==(t=r.dependencies)?void 0:t[e])]}))}:{},..."object"!=typeof r.propertyNames?{}:{propertyNames:n(r.propertyNames)},..."object"!=typeof r.if?{}:{if:n(r.if)},..."object"!=typeof r.then?{}:{then:n(r.then)},..."object"!=typeof r.else?{}:{else:n(r.else)},..."object"==typeof r.allOf&&r.allOf.length?{allOf:r.allOf.map(e=>n(e))}:{},..."object"==typeof r.anyOf&&r.anyOf.length?{anyOf:r.anyOf.map(e=>n(e))}:{},..."object"==typeof r.oneOf&&r.oneOf.length?{oneOf:r.oneOf.map(e=>n(e))}:{},..."object"!=typeof r.not?{}:{not:n(r.not)},...i(r.definitions)?{definitions:Object.fromEntries(Object.keys(r.definitions).map(e=>{var t;return[e,n(null==(t=r.definitions)?void 0:t[e])]}))}:{}}}},{}],24:[function(e,n,r){!function(e){!function(){var e,t;e=this,t=function(){function e(e,t){return e(t={exports:{}},t.exports),t.exports}var l=new(e(function(e){function t(){function l(e,t){var n,r,o=e.charCodeAt(t=void 0===t?0:t);return 55296<=o&&o<=56319&&t=e.length-1))for(var n,r=s(l(e,t)),o=[],i=t+1;i=n)return r.substr(0,n);while(n>r.length&&t>1){if(t&1)r+=e;t>>=1;e+=e}r+=e;r=r.substr(0,n);return r}"use strict";var l=function e(t,n,r){if(t==null||n==null)return t;var o=String(t);var i=typeof n==="number"?n:parseInt(n,10);if(isNaN(i)||!isFinite(i))return o;var a=o.length;if(a>=i)return o;var l=r==null?"":String(r);if(l==="")l=" ";var s=i-a;while(l.lengths?l.substr(0,s):l;return u+o},m=Object.assign||function(e){for(var t=1;t at "+n.filter(Boolean).join(":")}},s={unexpectedSymbol:function(e){for(var t=arguments.length,n=Array(1 at "+n.filter(Boolean).join(":")}},d={LEFT_BRACE:0,RIGHT_BRACE:1,LEFT_BRACKET:2,RIGHT_BRACKET:3,COLON:4,COMMA:5,STRING:6,NUMBER:7,TRUE:8,FALSE:9,NULL:10},o={"{":d.LEFT_BRACE,"}":d.RIGHT_BRACE,"[":d.LEFT_BRACKET,"]":d.RIGHT_BRACKET,":":d.COLON,",":d.COMMA},m={true:d.TRUE,false:d.FALSE,null:d.NULL},y={_START_:0,START_QUOTE_OR_CHAR:1,ESCAPE:2},h={'"':0,"\\":1,"/":2,b:3,f:4,n:5,r:6,t:7,u:8},b={_START_:0,MINUS:1,ZERO:2,DIGIT:3,POINT:4,DIGIT_FRACTION:5,EXP:6,EXP_DIGIT_OR_SIGN:7};function g(e){return"1"<=e&&e<="9"}function v(e){return"0"<=e&&e<="9"}function O(e){return"e"===e||"E"===e}function T(e,t,n,r){var o=e.charAt(t);if("\r"===o)n++,r=1,"\n"===e.charAt(++t)&&t++;else if("\n"===o)t++,n++,r=1;else{if("\t"!==o&&" "!==o)return null;t++,r++}return{index:t,line:n,column:r}}function E(e,t,n,r){e=e.charAt(t);return e in o?{type:o[e],line:n,column:r+1,index:t+1,value:null}:null}function A(e,t,n,r){for(var o in m)if(m.hasOwnProperty(o)&&e.substr(t,o.length)===o)return{type:m[o],line:n,column:r+o.length,index:t+o.length,value:o};return null}function j(e,t,n,r){for(var o=t,i=y._START_;te),l=e=>{return e=e,"."+a.slice(0,e).join(".")+` [query: ${a.join(".")}]`};return{start:null==(t=a.reduce((e,t,n)=>{if("Object"===e.type){var r,o=e.children.find(e=>e.key.value===t);if(o)return{key:o,value:r}=o,i&&n===a.length-1?o:r;throw new Error(`No such property ${t} in `+l(n))}if("Array"!==e.type)return e;o=Number(t);if(isNaN(o))throw new Error(`Invalid non-numeric array index "${t}" `+"in array at "+l(n));if(o<0||o>=e.children.length)throw new RangeError(`Index ${o} out-of-bounds in array of `+`size ${e.children.length} at `+l(n));return e.children,e.children[Number(t)]},e).loc)?void 0:t.start,end:null==t?void 0:t.end}}},{}],27:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.getAstByObject=n.getAstByString=void 0;let r=e("json-to-ast");function o(e,t){var n=r(e,{loc:!0});return{json:t||JSON.parse(e),jsonString:e,jsonAST:n}}n.getAstByString=o,n.getAstByObject=function(e,t=4){return o(JSON.stringify(e,null,t))}},{"json-to-ast":24}],28:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});let j=e("core-types-json-schema"),P=e("./utils/sharedUtils"),x=e("./utils/constants"),S=e("./utils/nosqlUtils");Draw.loadPlugin(function(b){var e=document.createElement("div");e.style.userSelect="none",e.style.overflow="hidden",e.style.padding="10px",e.style.height="100%";let r=document.createElement("textarea"),t=(r.style.height="200px",r.style.width="100%","-- click a nosql type button");r.value=t,mxUtils.br(e),e.appendChild(r);var n=b.menus.get("exportAs");let o="tonosql=To NoSQL",i=(n&&!window.VsCodeApi||(o="tonosql=Export As NoSQL"),mxResources.parse(o),new mxWindow(mxResources.get("tonosql"),e,document.body.offsetWidth-480,140,320,320,!0,!0));i.destroyOnClose=!1,i.setMaximizable(!1),i.setResizable(!1),i.setClosable(!0),mxUtils.br(e);var a=mxUtils.button(mxResources.get("reset"),function(){r.value=t}),a=(a.style.marginTop="8px",a.style.marginRight="4px",a.style.padding="4px",e.appendChild(a),mxUtils.button("OpenAPI",function(){{var t="openapi",n=(0,P.getMermaidDiagramDb)(b,t),n=(0,S.dbToOpenApi)(n);let e="";if("openapi"!=t)throw new Error(`type:${t} is not supported`);e=JSON.stringify(n,null,2),r.value=e}}));a.style.marginTop="8px",a.style.padding="4px",e.appendChild(a),b.actions.addAction("tonosql",function(){i.setVisible(!i.isVisible()),i.isVisible()&&r.focus()});let g=[],f,d=[],v=[],m=null,O=null,T=0,E;e=document.createElement("div");e.style.userSelect="none",e.style.overflow="hidden",e.style.padding="10px",e.style.height="100%";let l=document.createElement("textarea"),s=(l.style.height="200px",l.style.width="100%",` +!function r(o,i,a){function l(t,e){if(!i[t]){if(!o[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(s)return s(t,!0);throw(e=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",e}n=i[t]={exports:{}},o[t][0].call(n.exports,function(e){return l(o[t][1][e]||e)},n,n.exports,r,o,i,a)}return i[t].exports}for(var s="function"==typeof require&&require,e=0;e(0,o.ensureArray)(t).map(e=>"@see "+e).join("\n");if(e&&null!=t&&t.length)return e+"\n\n"+n();return e||n()}(e.description,e.see):void 0;return{...t,...e.title?{title:e.title}:{},...n?{description:n}:{},...e.default?{default:e.default}:{},...e.examples?{examples:e.examples}:{},...e.comment?{$comment:e.comment}:{}}},n.annotateCoreTypes=function(e,t){var{description:n,see:r}=function(e){var t=(null!=e?e:"").split("\n"),n=[];for(;0s(e)),e=(0,a.annotateJsonSchema)(e,{anyOf:t});return 1{return e=e,!(1===(e=Object.keys(e).sort()).length&&"type"===e[0]||2===e.length&&"title"===e[0]&&"type"===e[1])})&&(delete e.anyOf,e.type=t.map(({type:e})=>e)),e}function s(t){if("any"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{}));if("null"===t.type)return(0,a.annotateJsonSchema)(t,{type:"null"});if("boolean"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{type:"boolean"}));if("string"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{type:"string"}));if("number"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{type:"number"}));if("integer"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{type:"integer"}));if("and"===t.type)return(0,a.annotateJsonSchema)(t,{allOf:t.and.map(e=>s(e))});if("or"===t.type)return l(t);var e,n,r;if("object"===t.type)return n=(e=Object.keys(t.properties)).filter(e=>t.properties[e].required),r=Object.fromEntries(e.map(e=>[e,s(t.properties[e].node)])),(0,a.annotateJsonSchema)(t,u(t,{type:"object",...0s(e)),...!0===t.additionalItems?{}:t.additionalItems?{additionalItems:s(t.additionalItems)}:{additionalItems:!1},minItems:t.minItems}));if("ref"===t.type)return(0,a.annotateJsonSchema)(t,u(t,{$ref:(0,o.encodeRefNameJsonSchema)(t.ref)}));throw new i.UnsupportedError(`core-types node of type ${t.type} not supported`,t)}function u(e,t){return void 0!==e.const?{...t,const:e.const}:e.enum?{...t,enum:e.enum}:t}n.decorateSchema=r,n.convertCoreTypesToJsonSchema=function(e,t){var{version:e,types:n}=e;if(1!==e)throw new i.UnsupportedError(`core-types version ${e} not supported`);return r(e={definitions:Object.fromEntries(n.map(e=>[e.name,s(e)]))},null!=t?t:{}),{data:e,convertedTypes:n.map(({name:e})=>e),notConvertedTypes:[]}}},{"./annotations":2,"core-types":6,"openapi-json-schema":18}],4:[function(e,t,c){Object.defineProperty(c,"__esModule",{value:!0}),c.complexProps=c.convertJsonSchemaToCoreTypes=void 0;let i=e("jsonpos"),p=e("openapi-json-schema"),O=e("core-types"),f=e("./annotations"),d=(e,t)=>({...e,path:[...e.path,t]});function m(n,l){if("boolean"==typeof n)l.throwUnsupportedError("Boolean JSON Schema definition not supported",{blob:{schema:n}});else if("object"==typeof(e=n)&&Object.keys(e).some(e=>c.complexProps.has(e))){e=function(t,n){let{$ref:r,type:a,enum:l,const:s,items:u,additionalItems:c,required:p,properties:f,additionalProperties:d,then:e,else:o,allOf:i,anyOf:m,oneOf:y}=t;var h=i&&"object"==typeof i?i.filter(e=>e&&"object"==typeof e):null,b=m&&"object"==typeof m?m.filter(e=>e&&"object"==typeof e):null,g=y&&"object"==typeof y?y.filter(e=>e&&"object"==typeof e):null;let v=(e,o)=>{var i=(e,t)=>!(e&&t&&!(0,O.isEqual)(e,t));if(i(r,o.$ref)||n.throwUnsupportedError(`Cannot have $ref in a node *and* in its '${e}'`,{blob:t}),i(a,o.type)||n.throwUnsupportedError(`Cannot have 'type' in a node *and* in its '${e}'`,{blob:t}),l)if(o.enum){var i=(0,O.intersection)(l,o.enum);if(0===i.length)throw new O.MalformedTypeError("Cannot merge types with non-intersecting enums",{path:n.path,blob:{child:[...n.path,e]}});o.enum=i}else o.enum=l;if(void 0!==s)if(void 0!==o.const){if((0,O.isEqual)(s,o.const))throw new O.MalformedTypeError("Cannot merge types with mismatching const",{path:n.path,blob:{child:[...n.path,e]}})}else o.const=s;if(o.items=null!=(i=o.items)?i:u,o.additionalItems=null!=(e=o.additionalItems)?e:c,void 0===p&&void 0===o.required||(o.required=(0,O.union)(null!=(i=o.required)?i:[],null!==p&&void 0!==p?p:[])),void 0===f!=(void 0===o.properties))null!=o.properties||(o.properties=f);else if(void 0!==f){let t=f,n=o.properties;e=Object.keys(t),i=Object.keys(n),e=(0,O.union)(e,i);let r={};e.forEach(e=>{void 0!==t[e]?r[e]=n[e]:void 0!==n[e]?r[e]=t[e]:r[e]={allOf:[t[e],n[e]]}})}void 0===d!=(void 0===o.additionalProperties)?null==o.additionalProperties&&(o.additionalProperties=d):void 0!==d&&(o.additionalProperties={allOf:[o.additionalProperties,d]})};return e&&"object"==typeof e&&v("then",e),o&&"object"==typeof o&&v("else",o),h&&"object"==typeof h&&h.forEach(e=>v("allOf",e)),b&&"object"==typeof b&&b.forEach(e=>v("anyOf",e)),g&&"object"==typeof g&&g.forEach(e=>v("oneOf",e)),{...e&&"object"==typeof e?{then:e}:{},...o&&"object"==typeof o?{else:o}:{},...h&&"object"==typeof h?{allOf:h}:{},...b&&"object"==typeof b?{anyOf:b}:{},...g&&"object"==typeof g?{oneOf:g}:{}}}(n,l);var r=l;var{then:e,else:t,allOf:o,anyOf:i,oneOf:a}=e,e=[...e?[[d(r,"then"),e]]:[],...t?[[d(r,"else"),t]]:[]],t=[...i?i.map((e,t)=>[d(d(r,"anyOf"),t),e]):[],...a?a.map((e,t)=>[d(d(r,"oneOf"),t),e]):[]],i=[...o?o.map((e,t)=>[d(d(r,"allOf"),t),e]):[]];return{type:"and",and:[{type:"or",or:e.map(([e,t])=>m(t,e))},{type:"or",or:t.map(([e,t])=>m(t,e))},{type:"and",and:i.map(([e,t])=>m(t,e))}]};return}void 0===n&&l.throwUnsupportedError("Internal error",{blob:{schema:n}});let s=e=>({type:"ref",ref:(0,p.decodeRefNameJsonSchema)(e)});var a=e=>void 0===n.$ref?e:{type:"and",and:[e,s(n.$ref)]},{const:o,enum:e}=n;let u={...void 0!==o?{const:o}:{},...void 0!==e?{enum:e}:{}};return void 0===n.type?n.$ref?{...s(n.$ref),...u}:{type:"any",...u}:1===(t=(0,O.ensureArray)(n.type).map(e=>{var t,r=n,o=u,i=l;if(y(e))return"null"===e?(0,f.annotateCoreTypes)({type:"null"},r):(0,f.annotateCoreTypes)({type:e,...o},r);if("array"===e)return Array.isArray(r.items)?(0,f.annotateCoreTypes)({type:"tuple",elementTypes:r.items.map(e=>m(e,d(i,"items"))),additionalItems:void 0===r.additionalItems||("boolean"==typeof r.additionalItems?r.additionalItems:m(r.additionalItems,d(i,"additionalItems"))),minItems:null!=(a=r.minItems)?a:0,...o},r):!1===r.items?(0,f.annotateCoreTypes)({type:"tuple",elementTypes:[],additionalItems:!1,minItems:0,...o},r):(0,f.annotateCoreTypes)({type:"array",elementType:void 0===r.items||!0===r.items?{type:"any"}:m(r.items,d(i,"items")),...o},r);if("object"===e){let n=new Set(null!=(a=r.required)?a:[]);var a=null!=(a=r.additionalProperties)?a:i.defaultAdditionalProperties;return(0,f.annotateCoreTypes)({type:"object",properties:Object.fromEntries(Object.entries(null!=(t=r.properties)?t:{}).map(([e,t])=>[e,{node:m(t,d(d(i,"properties"),e)),required:n.has(e)}])),additionalProperties:"boolean"==typeof a?a:m(a,d(i,"additionalProperties")),...o},r)}i.throwUnsupportedError(`Unsupported JSON Schema type "${e}"`,{blob:{schema:r}})})).length?a(t[0]):a({type:"or",or:t})}c.convertJsonSchemaToCoreTypes=function(e,n={}){let r=("string"==typeof e?(0,i.getAstByString):(0,i.getAstByObject))(e),o=(e=r.json)["definitions"];return{data:e={version:1,types:Object.keys(null!==o&&void 0!==o?o:{}).map(e=>{var t;return{...m((null!==o&&void 0!==o?o:{})[e],{locByPath(){return{path:this.path,loc:(0,i.getLocation)(r,{dataPath:this.path,markIdentifier:!0})}},path:["definitions",e],throwUnsupportedError(e,t){throw(t={...t}).path||(t.path=this.path),t.loc||(t.loc=(0,i.getLocation)(r,{dataPath:this.path,markIdentifier:!0})),new O.UnsupportedError(e,t)},defaultAdditionalProperties:null==(t=n.defaultAdditionalProperties)||t}),name:e}})},convertedTypes:e.types.map(({name:e})=>e),notConvertedTypes:[]}},c.complexProps=new Set(["anyOf","allOf","oneOf","then","else"]);let y=e=>["string","number","integer","boolean","null"].includes(e)},{"./annotations":2,"core-types":6,jsonpos:25,"openapi-json-schema":18}],5:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.convertOpenApiToCoreTypes=n.convertCoreTypesToOpenApi=void 0;let o=e("openapi-json-schema"),i=e("./core-types-to-json-schema"),r=e("./json-schema-to-core-types");n.convertCoreTypesToOpenApi=function(e,t){let{data:n,...r}=(0,i.convertCoreTypesToJsonSchema)(e,t);return{...r,data:(0,o.jsonSchemaDocumentToOpenApi)(n,t)}},n.convertOpenApiToCoreTypes=function(e){return e="string"==typeof e?JSON.parse(e):e,e=(0,o.openApiToJsonSchema)(e),(0,r.convertJsonSchemaToCoreTypes)(e)}},{"./core-types-to-json-schema":3,"./json-schema-to-core-types":4,"openapi-json-schema":18}],6:[function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){e[r=void 0===r?n:r]=t[n]}),o=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)},i=(Object.defineProperty(n,"__esModule",{value:!0}),n.traverse=n.some=n.mergeLocations=n.getPositionOffset=n.locationToLineColumn=n.positionToLineColumn=n.decorateError=n.decorateErrorMeta=n.isCoreTypesError=n.throwRelatedError=n.throwUnsupportedError=n.RelatedError=n.UnsupportedError=n.MissingReferenceError=n.MalformedTypeError=n.formatSee=n.formatDefault=n.formatExamples=n.stringify=n.stripAnnotations=n.stringifyAnnotations=n.extractAnnotations=n.mergeAnnotations=n.isNonNullable=n.union=n.intersection=n.isEqual=n.hasConstEnum=n.isPrimitiveType=n.ensureArray=n.validate=n.simplify=void 0,o(e("./lib/types"),n),e("./lib/simplify")),a=(Object.defineProperty(n,"simplify",{enumerable:!0,get:function(){return i.simplify}}),e("./lib/validate")),l=(Object.defineProperty(n,"validate",{enumerable:!0,get:function(){return a.validate}}),e("./lib/util")),s=(Object.defineProperty(n,"ensureArray",{enumerable:!0,get:function(){return l.ensureArray}}),Object.defineProperty(n,"isPrimitiveType",{enumerable:!0,get:function(){return l.isPrimitiveType}}),Object.defineProperty(n,"hasConstEnum",{enumerable:!0,get:function(){return l.hasConstEnum}}),Object.defineProperty(n,"isEqual",{enumerable:!0,get:function(){return l.isEqual}}),Object.defineProperty(n,"intersection",{enumerable:!0,get:function(){return l.intersection}}),Object.defineProperty(n,"union",{enumerable:!0,get:function(){return l.union}}),Object.defineProperty(n,"isNonNullable",{enumerable:!0,get:function(){return l.isNonNullable}}),e("./lib/annotation")),u=(Object.defineProperty(n,"mergeAnnotations",{enumerable:!0,get:function(){return s.mergeAnnotations}}),Object.defineProperty(n,"extractAnnotations",{enumerable:!0,get:function(){return s.extractAnnotations}}),Object.defineProperty(n,"stringifyAnnotations",{enumerable:!0,get:function(){return s.stringifyAnnotations}}),Object.defineProperty(n,"stripAnnotations",{enumerable:!0,get:function(){return s.stripAnnotations}}),Object.defineProperty(n,"stringify",{enumerable:!0,get:function(){return s.stringify}}),Object.defineProperty(n,"formatExamples",{enumerable:!0,get:function(){return s.formatExamples}}),Object.defineProperty(n,"formatDefault",{enumerable:!0,get:function(){return s.formatDefault}}),Object.defineProperty(n,"formatSee",{enumerable:!0,get:function(){return s.formatSee}}),e("./lib/error")),c=(Object.defineProperty(n,"MalformedTypeError",{enumerable:!0,get:function(){return u.MalformedTypeError}}),Object.defineProperty(n,"MissingReferenceError",{enumerable:!0,get:function(){return u.MissingReferenceError}}),Object.defineProperty(n,"UnsupportedError",{enumerable:!0,get:function(){return u.UnsupportedError}}),Object.defineProperty(n,"RelatedError",{enumerable:!0,get:function(){return u.RelatedError}}),Object.defineProperty(n,"throwUnsupportedError",{enumerable:!0,get:function(){return u.throwUnsupportedError}}),Object.defineProperty(n,"throwRelatedError",{enumerable:!0,get:function(){return u.throwRelatedError}}),Object.defineProperty(n,"isCoreTypesError",{enumerable:!0,get:function(){return u.isCoreTypesError}}),Object.defineProperty(n,"decorateErrorMeta",{enumerable:!0,get:function(){return u.decorateErrorMeta}}),Object.defineProperty(n,"decorateError",{enumerable:!0,get:function(){return u.decorateError}}),e("./lib/location")),p=(Object.defineProperty(n,"positionToLineColumn",{enumerable:!0,get:function(){return c.positionToLineColumn}}),Object.defineProperty(n,"locationToLineColumn",{enumerable:!0,get:function(){return c.locationToLineColumn}}),Object.defineProperty(n,"getPositionOffset",{enumerable:!0,get:function(){return c.getPositionOffset}}),Object.defineProperty(n,"mergeLocations",{enumerable:!0,get:function(){return c.mergeLocations}}),e("./lib/traverse"));Object.defineProperty(n,"some",{enumerable:!0,get:function(){return p.some}}),Object.defineProperty(n,"traverse",{enumerable:!0,get:function(){return p.traverse}})},{"./lib/annotation":7,"./lib/error":8,"./lib/location":9,"./lib/simplify":13,"./lib/traverse":14,"./lib/types":15,"./lib/util":16,"./lib/validate":17}],7:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.stringify=n.formatSee=n.formatDefault=n.formatExamples=n.arrayOrSingle=n.stripAnnotations=n.stringifyAnnotations=n.wrapWhitespace=n.extractAnnotations=n.mergeAnnotations=void 0;let c=e("./location"),p=e("./util");function l(e){return e.includes("\n")?["*",e.split("\n").map(e=>" * "+e).join("\n")," "].join("\n"):e.startsWith(" ")?e:" "+e}function f(e){return 1===e.length?e[0]:e}function s(e){return e.map(e=>"@example\n"+o(r(e).split("\n"),4)).join("\n").trim()}function u(e){return["@default",o(r(e).split("\n"),4)].join("\n").trim()}function d(e){return e.map(e=>"@see "+r(e)).join("\n").trim()}function r(e){return"string"==typeof e?e:JSON.stringify(e,null,2)}function o(e,n,r=!1){return e.map((e,t)=>{return(0===t&&r?" ".repeat(n-2)+"* ":" ".repeat(n))+e}).join("\n")}n.mergeAnnotations=function(e){let t,n=e=>!!e;var r=(e,t="\n")=>(0,p.uniq)(e.filter(n)).join(t).trim(),o=null==(t=e.find(e=>e.name))?void 0:t.name,i=r(e.map(e=>e.title),", "),a=r(e.map(e=>e.description)),l=(0,p.uniq)([].concat(...e.map(e=>(0,p.ensureArray)(e.examples))).filter(n)),s=r(e.map(e=>e.default)),u=(0,p.uniq)([].concat(...e.map(e=>(0,p.ensureArray)(e.see))).filter(n)),r=r(e.map(e=>e.comment)),e=(0,c.mergeLocations)(e.map(e=>e.loc));return{...o?{name:o}:{},...i?{title:i}:{},...a?{description:a}:{},...0e).join("\n\n").trim().replace(/\*\//g,"*\\/");return n&&e?l(e):e},n.stripAnnotations=function t(e,n=!0){let{comment:r,description:o,default:i,examples:a,see:l,title:s,...u}=e,c=u;if(n){if("and"===c.type)return{...c,and:c.and.map(e=>t(e,!0))};if("or"===c.type)return{...c,or:c.or.map(e=>t(e,!0))};if("array"===c.type)return{...c,elementType:t(c.elementType,!0)};if("tuple"===c.type)return{...c,elementTypes:c.elementTypes.map(e=>t(e,!0)),additionalItems:"object"==typeof c.additionalItems?t(c.additionalItems,!0):c.additionalItems};if("object"===c.type)return{...c,properties:Object.fromEntries(Object.keys(c.properties).map(e=>[e,{...c.properties[e],node:t(c.properties[e].node,!0)}])),additionalProperties:"object"==typeof c.additionalProperties?t(c.additionalProperties,!0):c.additionalProperties}}return c},n.arrayOrSingle=f,n.formatExamples=s,n.formatDefault=u,n.formatSee=d,n.stringify=r},{"./location":9,"./util":16}],8:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.decorateError=n.decorateErrorMeta=n.isCoreTypesError=n.throwRelatedError=n.throwUnsupportedError=n.RelatedError=n.UnsupportedError=n.MissingReferenceError=n.MalformedTypeError=n.CoreTypesError=void 0;class r extends Error{constructor(e,t={}){super(e),Object.setPrototypeOf(this,r.prototype),this.blob=t.blob,this.path=t.path,this.loc=t.loc,this.source=t.source,this.filename=t.filename,this.relatedError=t.relatedError}}n.CoreTypesError=r;class o extends r{constructor(e,t={}){super(e,t),Object.setPrototypeOf(this,o.prototype)}}n.MalformedTypeError=o;class i extends r{constructor(e,t={}){super(`Reference to missing type "${e}"`,t),Object.setPrototypeOf(this,i.prototype)}}n.MissingReferenceError=i;class a extends r{constructor(e,t={}){super(e,t),Object.setPrototypeOf(this,a.prototype)}}n.UnsupportedError=a;class l extends r{constructor(e,t={}){super(e.message,{...t,relatedError:e}),Object.setPrototypeOf(this,l.prototype)}}function s(e){return e instanceof r}function u(e,t){return t.blob&&null==e.blob&&(e.blob=t.blob),t.path&&null==e.path&&(e.path=t.path),t.loc&&null==e.loc&&(e.loc=t.loc),t.source&&null==e.source&&(e.source=t.source),t.filename&&null==e.filename&&(e.filename=t.filename),e}n.RelatedError=l,n.throwUnsupportedError=function(e,t,n){throw new a(e,{blob:t,...t.loc?{loc:t.loc}:{},...n?{path:n}:{}})},n.throwRelatedError=function(e,t){throw new l(e,t)},n.isCoreTypesError=s,n.decorateErrorMeta=u,n.decorateError=function(e,t){return s(e)&&u(e,t),e}},{}],9:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.mergeLocations=n.getPositionOffset=n.locationToLineColumn=n.positionToLineColumn=void 0;let s=e("./util");function r(e,t){var n=e.slice(0,t).split("\n").length,e=e.lastIndexOf("\n",t);return-1===e?{offset:t,line:n,column:t}:{offset:t,line:n,column:t-e}}n.positionToLineColumn=r,n.locationToLineColumn=function(e,t){return"object"==typeof t.start?t:{start:void 0===t.start?void 0:r(e,t.start),...null==t.end?{}:{end:r(e,t.end)}}},n.getPositionOffset=function(e){return void 0===e||"number"==typeof e?e:e.offset},n.mergeLocations=function(e){let t,n,r,o,i,a=e=>"number"==typeof e?e:null==e?void 0:e.offset;e.filter(s.isNonNullable).forEach(({start:e,end:t})=>{var n=a(e),r=a(t);void 0!==n&&(!o||"number"==typeof o.location&&o.location===n||o.offset>n)&&(o={location:e,offset:n}),void 0!==r&&(!i||"number"==typeof i.location&&i.location===n||i.offseti(e))).some(e=>0===e.length)?[]:(0,r.uniq)([].concat(...e))},n.combineConstAndEnum=i},{"../util":16}],11:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.intersectConstEnum=void 0;let r=e("../annotation"),o=e("../util");n.intersectConstEnum=function(e){if(0===e.length)throw new Error("Cannot intersect const and enum from an empty array of nodes");var t;return 1===e.length?e[0]:(t=(t=e.map(e=>void 0!==e.const?[e.const]:void 0!==e.enum?e.enum:void 0).filter(e=>!!e)).slice(1).reduce((e,t)=>(0,o.intersection)(e,t),t[0]),{type:e[0].type,...1===t.length?{const:t[0]}:{},...1!==t.length?{enum:t}:{},...(0,r.mergeAnnotations)(e)})}},{"../annotation":7,"../util":16}],12:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.simplifySingle=void 0;let r=e("./const-enum");n.simplifySingle=function(e){return"boolean"===e.type||"integer"===e.type||"number"===e.type||"string"===e.type?(0,r.simplifyEnumAndConst)(e):e}},{"./const-enum":10}],13:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.simplify=void 0;let a=e("./simplifications/single"),l=e("./simplifications/const-enum"),o=e("./simplifications/intersect-const-enum"),i=e("./error"),s=e("./annotation"),u=e("./util"),c=["any","string","number","integer","boolean"];n.simplify=function r(t){if(Array.isArray(t))return t.map(e=>r(e));if((0,u.isNodeDocument)(t))return{...t,types:r(t.types)};var e,n=e=>(0,u.copyName)(t,e);if("tuple"===t.type)return{...t,elementTypes:t.elementTypes.map(e=>r(e)),...t.additionalItems&&"object"==typeof t.additionalItems?{additionalItems:r(t.additionalItems)}:{}};if("array"===t.type)return{...t,elementType:r(t.elementType)};if("object"===t.type)return{...t,properties:Object.fromEntries(Object.entries(t.properties).map(([e,{node:t,required:n}])=>[e,{node:r(t),required:n}])),...t.additionalProperties&&"object"==typeof t.additionalProperties?{additionalProperties:r(t.additionalProperties)}:{}};if("and"!==t.type&&"or"!==t.type)return n((0,a.simplifySingle)(t));if("and"===t.type)return 1===(e=function(e){if(0<(e=(0,u.splitTypes)(e)).any.length){if(0===e.and.length&&0===e.or.length&&0===e.ref.length&&0===e.null.length&&0===e.string.length&&0===e.number.length&&0===e.integer.length&&0===e.boolean.length&&0===e.object.length&&0===e.array.length&&0===e.tuple.length)return[{type:"any",...(0,s.mergeAnnotations)(e.any.map(({node:e})=>e))}];e.any=[]}var t=e=>e.map(({node:e})=>e);return 1e),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.boolean)}]),1e),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.string)}]),0e),...t(e.integer),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.number)}],e.integer=[]):1e),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.number)}]:1e),...t(e.any)]),order:(0,u.firstSplitTypeIndex)(e.integer)}]),000(e=r(e)).and||[e])))).length?n({...e[0],...(0,s.mergeAnnotations)([(0,s.extractAnnotations)(t),e[0]])}):n({type:"and",and:e,...(0,s.extractAnnotations)(t)});if("or"===t.type)return 1===(e=function(e){var t,n,r,o,i=(0,u.splitTypes)(e);if(0e)).length)return[{type:"any",...(0,s.mergeAnnotations)(i.any.map(({node:e})=>e))}];for([t,n]of Object.entries(i))c.includes(t)&&n.length&&(r=n.map(({node:e})=>e),0===(o=(0,l.mergeConstEnumUnion)(r)).length?i[t]=[{node:{type:t,...(0,s.mergeAnnotations)(r)},order:(0,u.firstSplitTypeIndex)(n)}]:i[t]=[{node:(0,a.simplifySingle)({type:t,enum:o,...(0,s.mergeAnnotations)(r)}),order:(0,u.firstSplitTypeIndex)(n)}]);return 000(e=r(e)).or||[e])))).length?n({...e[0],...(0,s.mergeAnnotations)([(0,s.extractAnnotations)(t),e[0]])}):n({type:"or",or:e,...(0,s.extractAnnotations)(t)});throw new i.MalformedTypeError("Invalid node",t)}},{"./annotation":7,"./error":8,"./simplifications/const-enum":10,"./simplifications/intersect-const-enum":11,"./simplifications/single":12,"./util":16}],14:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.some=n.traverse=void 0;class r extends Error{}function o(e,t){function a(e,t,n,r,o,i){var i=void 0!==i?i:void 0===r?t[n]:t[n][r],a=[...e.path,n,...void 0===r?[]:[r]];return Object.assign({},e,{node:i,path:a,parentNode:t,parentProperty:n,index:r,required:o})}!function n(r,o){o(r);let i=r.node;if("array"===i.type)n(a(r,i,"elementType"),o);else if("tuple"===i.type)i.elementTypes.forEach((e,t)=>n(a(r,i,"elementTypes",t),o)),"object"==typeof i.additionalItems&&n(a(r,i,"additionalItems"),o);else if("object"===i.type){for(var e of Object.keys(i.properties))n(a(r,i,"properties",e,i.properties[e].required,i.properties[e].node),o);"object"==typeof i.additionalProperties&&n(a(r,i,"additionalProperties"),o)}else"and"===i.type?i.and.forEach((e,t)=>n(a(r,i,"and",t),o)):"or"===i.type&&i.or.forEach((e,t)=>n(a(r,i,"or",t),o))}({node:e,rootNode:e,path:[]},t)}n.traverse=o,n.some=function(e,t){try{o(e,e=>{if(t(e))throw new r})}catch(e){if(e instanceof r)return!0;throw e}return!1}},{}],15:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0})},{}],16:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.isNodeDocument=n.isNonNullable=n.copyName=n.firstSplitTypeIndex=n.flattenSplitTypeValues=n.splitTypes=n.union=n.intersection=n.isEqual=n.hasConstEnum=n.constEnumTypes=n.isPrimitiveType=n.ensureArray=n.uniq=void 0,n.uniq=function(r){return r.filter((t,n)=>{for(let e=0;e["null","string","number","integer","boolean"].includes(e.type),n.constEnumTypes=new Set(["any","string","number","integer","boolean","object","array","tuple","ref"]);function o(t,n){var e;return typeof t==typeof n&&!(null===t!=(null===n)||null!==t&&(Array.isArray(t)&&Array.isArray(n)?t.length!==n.length||t.some((e,t)=>!o(e,n[t])):Array.isArray(t)!==Array.isArray(n)||("object"==typeof t?!o(e=Object.keys(t).sort(),Object.keys(n).sort())||e.some(e=>!o(t[e],n[e])):t!==n)))}n.hasConstEnum=e=>n.constEnumTypes.has(e.type),n.isEqual=o,n.intersection=function(e,n){let r=[];return e.forEach(t=>{n.forEach(e=>{o(t,e)&&r.push(t)})}),r},n.union=function(e,t){let n=[...e];return t.forEach(t=>{e.some(e=>o(t,e))||n.push(t)}),n},n.splitTypes=function(e){let n={and:[],or:[],ref:[],any:[],null:[],string:[],number:[],integer:[],boolean:[],object:[],array:[],tuple:[]};return e.forEach((e,t)=>{("and"!==e.type&&"or"!==e.type||"and"===e.type&&0e.order-t.order).map(({node:e})=>e))},n.firstSplitTypeIndex=function(e){return Math.min(...e.map(({order:e})=>e))},n.copyName=function(e,t){return void 0===e.name?t:{...t,name:e.name}},n.isNonNullable=function(e){return null!=e},n.isNodeDocument=function(e){return Array.isArray(e.types)}},{}],17:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.validate=void 0;let r=e("./error"),o=e("./util");n.validate=function t(e){if((0,o.hasConstEnum)(e)){var n=e;if(n.enum&&0===n.enum.length)throw new r.MalformedTypeError("Empty enum is not allowed",n);if(n.enum&&void 0!==n.const&&!n.enum.some(e=>(0,o.isEqual)(e,n.const)))throw new r.MalformedTypeError("Enum and const are both set, but enum doesn't contain const",n)}"and"===e.type&&e.and.forEach(e=>t(e)),"or"===e.type&&e.or.forEach(e=>t(e))}},{"./error":8,"./util":16}],18:[function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n),Object.defineProperty(e,r,{enumerable:!0,get:function(){return t[n]}})}:function(e,t,n,r){e[r=void 0===r?n:r]=t[n]}),o=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(n,"__esModule",{value:!0}),o(e("./lib"),n),o(e("./lib/types"),n),o(e("./lib/utils"),n)},{"./lib":19,"./lib/types":22,"./lib/utils":23}],19:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.openApiToJsonSchema=n.jsonSchemaDocumentToOpenApi=n.decorateOpenApi=void 0;let o=e("./json-schema-to-openapi"),r=e("./openapi-to-json-schema");function i(e,{title:t,version:n,schemaVersion:r="3.0.0"}){t={title:t,version:n};return e.$id&&(t["x-id"]=e.$id,delete e.$id),e.$comment&&(t["x-comment"]=e.$comment,delete e.$comment),delete e.$schema,{openapi:r,info:t,paths:{},...e}}n.decorateOpenApi=i,n.jsonSchemaDocumentToOpenApi=function(e,t){let{definitions:n={},...r}=e;return i({...r,components:{schemas:Object.fromEntries(Object.entries(n).map(([e,t])=>[e,(0,o.jsonSchemaTypeToOpenApi)(t)]))}},t)},n.openApiToJsonSchema=function(e){let t=e.components.schemas;return{definitions:Object.fromEntries(Object.keys(t).map(e=>[e,(0,r.openApiToJsonSchemaType)(t[e])]))}}},{"./json-schema-to-openapi":20,"./openapi-to-json-schema":21}],20:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.jsonSchemaTypeToOpenApi=void 0;let r=e("./utils");n.jsonSchemaTypeToOpenApi=function e(t){var n;return"boolean"==typeof t?t:(t=function(e){if(void 0===e.type)return e;let{type:t,...n}=e,r=Array.isArray(t)?t.includes("null"):"null"===t;var o=Array.isArray(t)?t.filter(e=>"null"!==e):"null"===t?void 0:t;let i=(e,t)=>"any"!==t&&t?{...e,type:t}:e;return void 0!==e.const&&(n.enum=[e.const],delete n.const),e=e=>r?{...e,nullable:r}:e,Array.isArray(o)?0===o.length?e(n):1===o.length?i(e(n),o[0]):{...e(n),anyOf:o.map(e=>i({},e))}:i(e(n),o)}(t),t=(n=t).$ref?{...n,$ref:(0,r.encodeRefNameOpenApi)((0,r.decodeRefNameJsonSchema)(n.$ref))}:n,(0,r.recurseSchema)(t,e))}},{"./utils":23}],21:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.openApiToJsonSchemaType=void 0;let a=e("./utils");n.openApiToJsonSchemaType=function e(t){if("boolean"==typeof t)return t;let{type:n,nullable:r,...o}=t;var i,t=function(e,t){if(void 0!==e&&"any"!==e)return Array.isArray(e)?e.includes("any")?void 0:(!e.includes("null")&&t&&e.push("null"),1===e.length?e[0]:e):"null"!==e&&t?[e,"null"]:e}(n,r),t={...o,...t?{type:t}:{}},t=(i=t).$ref?{...i,$ref:(0,a.encodeRefNameJsonSchema)((0,a.decodeRefNameOpenApi)(i.$ref))}:i;return(0,a.recurseSchema)(t,e)}},{"./utils":23}],22:[function(e,t,n){arguments[4][15][0].apply(n,arguments)},{dup:15}],23:[function(e,t,n){function r(e){return encodeURIComponent(e)}function o(e){return decodeURIComponent(e)}function i(e){return e&&0n(e))}:{items:n(r.items)},..."object"!=typeof r.additionalItems?{}:{additionalItems:n(r.additionalItems)},..."object"!=typeof r.contains?{}:{contains:n(r.contains)},...i(r.properties)?{properties:Object.fromEntries(Object.keys(r.properties).map(e=>{var t;return[e,n(null==(t=r.properties)?void 0:t[e])]}))}:{},...i(r.patternProperties)?{patternProperties:Object.fromEntries(Object.keys(r.patternProperties).map(e=>{var t;return[e,n(null==(t=r.patternProperties)?void 0:t[e])]}))}:{},..."object"!=typeof r.additionalProperties?{}:{additionalProperties:n(r.additionalProperties)},...i(r.dependencies)?{dependencies:Object.fromEntries(Object.keys(r.dependencies).map(e=>{var t;return[e,n(null==(t=r.dependencies)?void 0:t[e])]}))}:{},..."object"!=typeof r.propertyNames?{}:{propertyNames:n(r.propertyNames)},..."object"!=typeof r.if?{}:{if:n(r.if)},..."object"!=typeof r.then?{}:{then:n(r.then)},..."object"!=typeof r.else?{}:{else:n(r.else)},..."object"==typeof r.allOf&&r.allOf.length?{allOf:r.allOf.map(e=>n(e))}:{},..."object"==typeof r.anyOf&&r.anyOf.length?{anyOf:r.anyOf.map(e=>n(e))}:{},..."object"==typeof r.oneOf&&r.oneOf.length?{oneOf:r.oneOf.map(e=>n(e))}:{},..."object"!=typeof r.not?{}:{not:n(r.not)},...i(r.definitions)?{definitions:Object.fromEntries(Object.keys(r.definitions).map(e=>{var t;return[e,n(null==(t=r.definitions)?void 0:t[e])]}))}:{}}}},{}],24:[function(e,n,r){!function(e){!function(){var e,t;e=this,t=function(){function e(e,t){return e(t={exports:{}},t.exports),t.exports}var l=new(e(function(e){function t(){function l(e,t){var n,r,o=e.charCodeAt(t=void 0===t?0:t);return 55296<=o&&o<=56319&&t=e.length-1))for(var n,r=s(l(e,t)),o=[],i=t+1;i=n)return r.substr(0,n);while(n>r.length&&t>1){if(t&1)r+=e;t>>=1;e+=e}r+=e;r=r.substr(0,n);return r}"use strict";var l=function e(t,n,r){if(t==null||n==null)return t;var o=String(t);var i=typeof n==="number"?n:parseInt(n,10);if(isNaN(i)||!isFinite(i))return o;var a=o.length;if(a>=i)return o;var l=r==null?"":String(r);if(l==="")l=" ";var s=i-a;while(l.lengths?l.substr(0,s):l;return u+o},m=Object.assign||function(e){for(var t=1;t at "+n.filter(Boolean).join(":")}},s={unexpectedSymbol:function(e){for(var t=arguments.length,n=Array(1 at "+n.filter(Boolean).join(":")}},d={LEFT_BRACE:0,RIGHT_BRACE:1,LEFT_BRACKET:2,RIGHT_BRACKET:3,COLON:4,COMMA:5,STRING:6,NUMBER:7,TRUE:8,FALSE:9,NULL:10},o={"{":d.LEFT_BRACE,"}":d.RIGHT_BRACE,"[":d.LEFT_BRACKET,"]":d.RIGHT_BRACKET,":":d.COLON,",":d.COMMA},m={true:d.TRUE,false:d.FALSE,null:d.NULL},y={_START_:0,START_QUOTE_OR_CHAR:1,ESCAPE:2},h={'"':0,"\\":1,"/":2,b:3,f:4,n:5,r:6,t:7,u:8},b={_START_:0,MINUS:1,ZERO:2,DIGIT:3,POINT:4,DIGIT_FRACTION:5,EXP:6,EXP_DIGIT_OR_SIGN:7};function g(e){return"1"<=e&&e<="9"}function v(e){return"0"<=e&&e<="9"}function O(e){return"e"===e||"E"===e}function T(e,t,n,r){var o=e.charAt(t);if("\r"===o)n++,r=1,"\n"===e.charAt(++t)&&t++;else if("\n"===o)t++,n++,r=1;else{if("\t"!==o&&" "!==o)return null;t++,r++}return{index:t,line:n,column:r}}function j(e,t,n,r){e=e.charAt(t);return e in o?{type:o[e],line:n,column:r+1,index:t+1,value:null}:null}function A(e,t,n,r){for(var o in m)if(m.hasOwnProperty(o)&&e.substr(t,o.length)===o)return{type:m[o],line:n,column:r+o.length,index:t+o.length,value:o};return null}function E(e,t,n,r){for(var o=t,i=y._START_;te),l=e=>{return e=e,"."+a.slice(0,e).join(".")+` [query: ${a.join(".")}]`};return{start:null==(t=a.reduce((e,t,n)=>{if("Object"===e.type){var r,o=e.children.find(e=>e.key.value===t);if(o)return{key:o,value:r}=o,i&&n===a.length-1?o:r;throw new Error(`No such property ${t} in `+l(n))}if("Array"!==e.type)return e;o=Number(t);if(isNaN(o))throw new Error(`Invalid non-numeric array index "${t}" `+"in array at "+l(n));if(o<0||o>=e.children.length)throw new RangeError(`Index ${o} out-of-bounds in array of `+`size ${e.children.length} at `+l(n));return e.children,e.children[Number(t)]},e).loc)?void 0:t.start,end:null==t?void 0:t.end}}},{}],27:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.getAstByObject=n.getAstByString=void 0;let r=e("json-to-ast");function o(e,t){var n=r(e,{loc:!0});return{json:t||JSON.parse(e),jsonString:e,jsonAST:n}}n.getAstByString=o,n.getAstByObject=function(e,t=4){return o(JSON.stringify(e,null,t))}},{"json-to-ast":24}],28:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0});let j=e("core-types-json-schema"),A=e("./utils/sharedUtils"),E=e("./utils/constants"),P=e("./utils/nosqlUtils"),l=e("./utils/constants-nosql");Draw.loadPlugin(function(p){var e=document.createElement("div");e.style.userSelect="none",e.style.overflow="hidden",e.style.padding="10px",e.style.height="100%";let r=document.createElement("textarea"),t=(r.style.height="200px",r.style.width="100%","-- click a nosql type button");r.value=t,mxUtils.br(e),e.appendChild(r);var n=p.menus.get("exportAs");let o="tonosql=To NoSQL",i=(n&&!window.VsCodeApi||(o="tonosql=Export As NoSQL"),mxResources.parse(o),new mxWindow(mxResources.get("tonosql"),e,document.body.offsetWidth-480,140,320,320,!0,!0));i.destroyOnClose=!1,i.setMaximizable(!1),i.setResizable(!1),i.setClosable(!0),mxUtils.br(e);var a=mxUtils.button(mxResources.get("reset"),function(){r.value=t}),a=(a.style.marginTop="8px",a.style.marginRight="4px",a.style.padding="4px",e.appendChild(a),mxUtils.button("OpenAPI",function(){{var t="openapi",n=(0,A.getMermaidDiagramDb)(p,t),n=(0,P.dbToOpenApi)(n);let e="";if("openapi"!=t)throw new Error(`type:${t} is not supported`);e=JSON.stringify(n,null,2),r.value=e}}));a.style.marginTop="8px",a.style.padding="4px",e.appendChild(a),p.actions.addAction("tonosql",function(){i.setVisible(!i.isVisible()),i.isVisible()&&r.focus()});let f,d,m,y=[],h=null,b=null,g=0,v;e=document.createElement("div");e.style.userSelect="none",e.style.overflow="hidden",e.style.padding="10px",e.style.height="100%";let O=document.createElement("textarea"),T=(O.style.height="200px",O.style.width="100%",O.value=l.defaultResetOpenApi,mxUtils.br(e),e.appendChild(O),mxResources.parse("fromNoSql=From NoSQL"),new mxWindow(mxResources.get("fromNoSql"),e,document.body.offsetWidth-480,140,320,320,!0,!0));T.destroyOnClose=!1,T.setMaximizable(!1),T.setResizable(!1),T.setClosable(!0),mxUtils.br(e);a=mxUtils.button("Reset OpenAPI",function(){O.value=l.defaultResetOpenApi}),a.style.marginTop="8px",a.style.marginRight="4px",a.style.padding="4px",e.appendChild(a),a=mxUtils.button("Insert OpenAPI",function(){var t,n=O.value,r="openapi";y=[],h=null,b=null;try{let e=null;var o={title:"nosql default options",version:E.pluginVersion};if("openapi"!=r)throw new Error(`type:${r} is not supported`);var i,a,l=JSON.parse(n),s=(0,j.convertOpenApiToCoreTypes)(l)["data"],u=(0,j.convertCoreTypesToJsonSchema)(s)["data"],c=((0,j.jsonSchemaDocumentToOpenApi)(u,o),null==(t=null===(e=l)||void 0===e?void 0:e.components)?void 0:t.schemas);c&&(i=(0,P.ConvertOpenApiToDatabaseModel)(c),f=i.ForeignKeyList,d=i.PrimaryKeyList,m=i.TableList,v=m.length,a=(0,A.CreateTableUI)(p,T,m,y,b,h,f,g,r))&&(y=a.cells,g=a.dx,h=a.tableCell,b=a.rowCell)}catch(e){console.log("unable to serialize the response:"+r),console.log(e)}}),a.style.marginTop="8px",a.style.padding="4px",e.appendChild(a),p.actions.addAction("fromNoSql",function(){T.setVisible(!T.isVisible()),T.isVisible()&&O.focus()}),e=p.menus.get("insert");if(e){let r=e.funct;e.funct=function(...e){var[t,n]=e;r.apply(this,e),p.menus.addMenuItems(t,["fromNoSql"],n)}}if(n&&!window.VsCodeApi){let r=n.funct;n.funct=function(...e){var[t,n]=e;r.apply(this,e),p.menus.addMenuItems(t,["tonosql"],n)}}else{a=p.menus.get("file");if(a&&a.enabled){let r=a.funct;a.funct=function(...e){var[t,n]=e;r.apply(this,e),p.menus.addMenuItems(t,["tonosql"],n)}}}})},{"./utils/constants":30,"./utils/constants-nosql":29,"./utils/nosqlUtils":31,"./utils/sharedUtils":32,"core-types-json-schema":1}],29:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.validJSONSchemaTypes=n.defaultResetOpenApi=n.defaultReset=void 0;e=e("./constants");n.defaultReset=`/* + Drawio default value + Plugin: nosql + Version: ${e.pluginVersion} +*/ + + +export interface WeatherForecast { + /** @format date-time */ + date?: string; + /** @format int32 */ + temperatureC?: number; + /** @format int32 */ + temperatureF?: number; + summary?: string | null; + nestedProp: string[]; + children?: Child[]; +} + +export interface Child { + name: string +} + `,n.defaultResetOpenApi=` { "openapi": "3.0.0", "info": { "title": "nosql plugin sample", - "version": "${x.pluginVersion}", + "version": "${e.pluginVersion}", "x-comment": "Generated by core-types-json-schema (https://github.com/grantila/core-types-json-schema)" }, "paths": {}, @@ -68,4 +90,4 @@ } } } - `),A=(l.value=s,mxUtils.br(e),e.appendChild(l),mxResources.parse("fromNoSql=From NoSQL"),new mxWindow(mxResources.get("fromNoSql"),e,document.body.offsetWidth-480,140,320,320,!0,!0));function u(t,n){var r;v=[],m=null,O=null;try{let e=null;var o={title:"nosql default options",version:x.pluginVersion};if("openapi"!=n)throw new Error(`type:${n} is not supported`);var i=JSON.parse(t),a=(0,j.convertOpenApiToCoreTypes)(i)["data"],l=(0,j.convertCoreTypesToJsonSchema)(a)["data"],s=((0,j.jsonSchemaDocumentToOpenApi)(l,o),null==(r=null===(e=i)||void 0===e?void 0:e.components)?void 0:r.schemas);if(s){var u=(0,S.ConvertOpenApiToDatabaseModel)(s),c=(g=u.ForeignKeyList,f=u.PrimaryKeyList,d=u.TableList,E=d.length,n);if(d.forEach(function(n){var e,t=100+n.Name.length;(m=new mxCell(n.Name,new mxGeometry(T,0,t,26),"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;")).vertex=!0,O&&null!==(e=b.editor.graph.getPreferredSizeForCell(O))&&(m.geometry.width=e.width+t),v.push(m),n.Properties.forEach(function(e){var t;e=e,n.Name,t=e.Name+(e.ColumnProperties?" "+e.ColumnProperties:""),(O=new mxCell(t,new mxGeometry(0,0,90,26),"shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;")).vertex=!0,t=e.IsPrimaryKey&&e.IsForeignKey?"PK | FK":e.IsPrimaryKey?"PK":e.IsForeignKey?"FK":"",(e=sb.cloneCell(O,t)).connectable=!1,e.style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;",e.geometry.width=54,e.geometry.height=26,O.insert(e),t=b.editor.graph.getPreferredSizeForCell(O),m&&(null!==t&&m.geometry.widthe.Name==t.ReferencesTableName))?void 0:p.Properties[0])&&(n.ForeignKeyList[e].ReferencesPropertyName=p.Name),t.PrimaryKeyName||(f=null==(p=n.TableList.find(e=>e.Name==t.PrimaryKeyTableName))?void 0:p.Properties[0])&&(n.ForeignKeyList[e].PrimaryKeyName=f.Name)}return n};let h=e("./constants"),b=e("./sharedUtils");function d(e,t,n){let r,o=(null!=(r=n.type)?r:"object").toString();n.enum?o=""+JSON.stringify(n.enum):n.nullable&&(o+=" nullable");n=(0,b.generateComment)(n.description,n.format),n&&(o+=" "+n),n={Name:(0,b.dbTypeEnds)(t),IsPrimaryKey:!1,IsForeignKey:!1,ColumnProperties:o,TableName:(0,b.dbTypeEnds)(e),ForeignKey:[]};return n}},{"./constants":29,"./sharedUtils":31}],31:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.GetColumnQuantifiers=P,n.removeHtml=r,n.dbTypeEnds=function(e){return`\`${e}\``},n.RemoveNameQuantifiers=x,n.getDbLabel=S,n.entityName=function(e,t){let n="";e&&(n+=""+e);t&&(n+=" @format "+t);n=n&&`/** ${n=n.trim()} */`;return n},n.getCommentIndexes=C,n.getMermaidDiagramDb=function(e,o){var t=e.editor.graph.getModel(),i={},a=[];for(var l in t.cells)if(Object.hasOwnProperty.call(t.cells,l)){var s=t.cells[l];if(-1!==s.mxObjectId.indexOf("mxCell")&&s.style&&s.style.trim().startsWith("swimlane;")){let t=s.value.toString(),n="",r="";if(null!==t&&void 0!==t&&t.includes(j.commentColumnQuantifiers.Start)&&null!==t&&void 0!==t&&t.includes(j.commentColumnQuantifiers.End)){let e=t.toString();var l=C(e),u=l.start,c=l.end;t=e.substring(0,l.beforeStart),-1!==(e=e.substring(u,c)).indexOf(j.formatKeyword)&&(l=e.indexOf(j.formatKeyword),r=e.substring(l+j.formatKeyword.length).trim(),e=e.substring(0,l)),e&&(n=e)}var p={name:x(t),attributes:[]},u=R(n,r);u&&(p.name+=u);for(let e=0;e-1!==["FK","PK"].findIndex(e=>e==t.value.toUpperCase())||-1!=t.value.toUpperCase().indexOf("PK,"));if(y&&(m.attributeKeyType=y.value,"PK"!=m.attributeKeyType)&&-1!=m.attributeKeyType.indexOf("PK")&&(m.attributeKeyType="PK"),p.attributes.push(m),f.edges&&f.edges.length)for(let e=0;e-1!=t.toLocaleLowerCase().indexOf(e)),b=n&&-1!=b.findIndex(e=>-1!=n.toLocaleLowerCase().indexOf(e));if(!b&&!g||b&&g){if(b&&g){var v,b=S(h.source.value,d),O=(b.attributeKeyType="PK",A=b.attributeName,x(h.source.parent.value)),T=S(h.target.value,d),E=(T.attributeKeyType="PK",v=T.attributeName,x(h.target.parent.value)),b={name:x(O)+"_"+x(E),attributes:[b,T]};i[b.name]||(i[b.name]=b);let t={entityA:O,entityB:b.name,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:`[${O}.${A}] to [${b.name}.${A}]`},n=(-1==a.findIndex(e=>e.entityA==t.entityA&&e.entityB==t.entityB&&e.roleA==t.roleA)&&a.push(t),{entityA:E,entityB:b.name,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:`[${E}.${v}] to [${b.name}.${v}]`});-1==a.findIndex(e=>e.entityA==n.entityA&&e.entityB==n.entityB&&e.roleA==n.roleA)&&a.push(n)}}else{T=S(h.source.value,d).attributeName;var A,O=x(h.source.parent.value),E=(A=S(h.target.value,d).attributeName,x(h.target.parent.value));let t={entityA:g?O:E,entityB:g?E:O,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:g?`[${O}.${T}] to [${E}.${A}]`:`[${E}.${A}] to [${O}.${T}]`};-1==a.findIndex(e=>e.entityA==t.entityA&&e.entityB==t.entityB&&e.roleA==t.roleA)&&a.push(t)}}}}}if(i[p.name]){let e=2;for(;i[p.name+e.toString()];)e++;i[p.name+e.toString()]=p}else i[p.name]=p}}e=N(i,a);return e},n.GenerateDatabaseModel=N,n.generateComment=R;let j=e("./constants");function P(e){var t={Start:'"',End:'"'};return e&&["mysql","ts","openapi"].includes(e)?(t.Start="`",t.End="`"):"sqlserver"==e&&(t.Start="[",t.End="]"),t}function r(e){var t=document.createElement("div"),e=(t.innerHTML=e,t.textContent||t.innerText||"");return t.remove(),e}function x(e){return e.replace(/\[|\]|\(|\"|\'|\`/g,"").trim()}function S(e,t){let n=r(e);e=(n=n.toString().replace(/\s+/g," "))[0]==t.Start&&-1!==n.indexOf(t.End+" ")?n.indexOf(t.End+" "):n.indexOf(" "),t=n.substring(e+1).trim();return{attributeName:x(n.substring(0,e+1)),attributeType:t}}function C(e){let t=!1;return{beforeStart:(t=-1!==e.indexOf(j.commentColumnQuantifiers.Start)&&-1!==e.indexOf(j.commentColumnQuantifiers.End)?!0:t)?e.indexOf(j.commentColumnQuantifiers.Start):-1,start:t?e.indexOf(j.commentColumnQuantifiers.Start)+j.commentColumnQuantifiers.Start.length:-1,end:t?e.indexOf(j.commentColumnQuantifiers.End)-1:-1}}function N(e,t){return new class{constructor(e,t){this.entities=e,this.relationships=t}getEntities(){return this.entities}getRelationships(){return this.relationships}}(e,t)}function R(e,t){let n="";return e&&(n+=""+e),t&&(n+=" @format "+t),n&&(n=n.trim(),n=`${j.commentColumnQuantifiers.Start} ${n} `+j.commentColumnQuantifiers.End),n}},{"./constants":29}]},{},[28]); \ No newline at end of file + `;n.validJSONSchemaTypes=["string","number","integer","boolean","object","array","null","any"]},{"./constants":30}],30:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.objectKeyword=n.arrayKeyword=n.nullableKeyword=n.enumKeyword=n.formatKeyword=n.commentColumnQuantifiers=n.pluginVersion=void 0,n.pluginVersion="0.0.6",n.commentColumnQuantifiers={Start:"/**",End:"*/"},n.formatKeyword="@format",n.enumKeyword="enum",n.nullableKeyword="nullable",n.arrayKeyword="array",n.objectKeyword="object"},{}],31:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.dbToOpenApi=function(u){var e={openapi:"3.0.0",info:{title:"drawio nosql export",version:g.pluginVersion,"x-comment":"Generated by from drawio uml using plugin nosql"},paths:{},components:{schemas:{}}},c={},r=u.getEntities();for(let s in r)if(Object.prototype.hasOwnProperty.call(r,s)){let l=s;var o=r[s],i=(0,v.getCommentIndexes)(s);let t="",n="";if(-1e.entityA==s);let t=`[${s}.${d}]`;m=h.find(e=>-1!=e.roleA.indexOf(t));m&&(b=(0,v.getCommentIndexes)(m.entityB),m=m.entityB.substring(0,b.beforeStart).trim(),e="#/components/schemas/"+m),e&&("array"==o&&(n={$ref:e}),"object"==o)&&(r={$ref:e})}var b={title:l+"."+d,type:o};r&&(b.additionalProperties=r),n&&(b.items=n),null!=(m=f.attributeType)&&m.includes("nullable")&&(b.nullable=!0),!e||null!==r&&void 0!==r&&r.$ref||null!==n&&void 0!==n&&n.$ref||(b.$ref=e),t&&delete b.type,i.trim()&&!e&&(b.description=i.trim()),a.trim()&&(b.items?b.items.format=a.trim():b.format=a.trim()),c[l].properties[f.attributeName]=b}}}0===Object.keys(c[l].properties).length&&delete c[l].properties}}return e.components.schemas=c,e},n.GeneratePropertyModel=h,n.ConvertOpenApiToDatabaseModel=function(t){var n,r,o;var i={Dialect:"nosql",TableList:[],PrimaryKeyList:[],ForeignKeyList:[]},a={};for(var e in t)if(Object.prototype.hasOwnProperty.call(t,e)){var l,s,u,c=t[e],p=(0,v.dbTypeEnds)(e),f={Name:(0,v.dbTypeEnds)(e),Properties:[]};for(u in c.enum?(l=c.enum,s=c.type+" "+g.enumKeyword,l={enum:l},c.description&&(l.description=c.description),c.format&&(l.format=c.format),e=h(e,s,l),f.Properties.push(e)):(s=(0,v.generateComment)(c.description,c.format))&&(f.Name+=" "+s),c.properties)if(Object.prototype.hasOwnProperty.call(c.properties,u)){var d=c.properties[u];let e=null;d.$ref?e=d.$ref.split("/").pop():d.items&&typeof d.items==g.objectKeyword?e=null==(n=d.items.$ref)?void 0:n.split("/").pop():d.additionalProperties&&"object"==typeof d.additionalProperties&&(e=null==(n=d.additionalProperties.$ref)?void 0:n.split("/").pop()),e&&(y=t[e],e=y&&!y.enum&&(y=(0,v.generateComment)(y.description,y.format))?(0,v.dbTypeEnds)(e)+" "+y:(0,v.dbTypeEnds)(e)),e&&!d.type&&(d.type=e);var m,y=h(f.Name,u,d);e&&(d={PrimaryKeyTableName:f.Name,ReferencesTableName:e,PrimaryKeyName:(0,v.dbTypeEnds)(u),ReferencesPropertyName:"",IsDestination:!1},m={ReferencesTableName:f.Name,PrimaryKeyTableName:e,ReferencesPropertyName:(0,v.dbTypeEnds)(u),PrimaryKeyName:"",IsDestination:!0},i.ForeignKeyList.push(m),i.ForeignKeyList.push(d),y.IsForeignKey=!0),f.Properties.push(y)}i.TableList.push(f),a[p]||(a[p]=f)}for(let n=0;ne.Name==t.ReferencesTableName))?void 0:r.Properties[0];(e=e||(null==(r=a[t.ReferencesTableName])?void 0:r.Properties[0]))&&(i.ForeignKeyList[n].ReferencesPropertyName=e.Name)}if(!t.PrimaryKeyName){let e=null==(r=i.TableList.find(e=>e.Name==t.PrimaryKeyTableName))?void 0:r.Properties[0];(e=e||(null==(o=a[t.PrimaryKeyTableName])?void 0:o.Properties[0]))&&(i.ForeignKeyList[n].PrimaryKeyName=e.Name)}}return i};let g=e("./constants"),v=e("./sharedUtils"),O=e("./constants-nosql");function h(e,t,n){let r,o=(null!=(r=n.type)?r:g.objectKeyword).toString();o===g.arrayKeyword&&n.items&&typeof n.items===g.objectKeyword&&(n.items.format&&!n.format&&(n.format=n.items.format),n.items.type)&&(o=n.items.type+"[]"),n.enum?o=""+JSON.stringify(n.enum):n.nullable&&(o+=" "+g.nullableKeyword);n=(0,v.generateComment)(n.description,n.format),n&&(o+=" "+n),n={Name:(0,v.dbTypeEnds)(t),IsPrimaryKey:!1,IsForeignKey:!1,ColumnProperties:o,TableName:(0,v.dbTypeEnds)(e),ForeignKey:[]};return n}},{"./constants":30,"./constants-nosql":29,"./sharedUtils":32}],32:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.GetColumnQuantifiers=P,n.removeHtml=r,n.dbTypeEnds=y,n.RemoveNameQuantifiers=x,n.getDbLabel=S,n.entityName=function(e,t){let n="";e&&(n+=""+e);t&&(n+=` ${E.formatKeyword} `+t);n=n&&`/** ${n=n.trim()} */`;return n},n.getCommentIndexes=C,n.getMermaidDiagramDb=function(e,o){var t=e.editor.graph.getModel(),i={},a=[];for(var l in t.cells)if(Object.hasOwnProperty.call(t.cells,l)){var s=t.cells[l];if(-1!==s.mxObjectId.indexOf("mxCell")&&s.style&&s.style.trim().startsWith("swimlane;")){let t=s.value.toString(),n="",r="";if(null!==t&&void 0!==t&&t.includes(E.commentColumnQuantifiers.Start)&&null!==t&&void 0!==t&&t.includes(E.commentColumnQuantifiers.End)){let e=t.toString();var l=C(e),u=l.start,c=l.end;t=e.substring(0,l.beforeStart),-1!==(e=e.substring(u,c)).indexOf(E.formatKeyword)&&(l=e.indexOf(E.formatKeyword),r=e.substring(l+E.formatKeyword.length).trim(),e=e.substring(0,l)),e&&(n=e)}var p={name:x(t),attributes:[]},u=N(n,r);u&&(p.name+=" "+u);for(let e=0;e-1!==["FK","PK"].findIndex(e=>e==t.value.toUpperCase())||-1!=t.value.toUpperCase().indexOf("PK,"));if(y&&(m.attributeKeyType=y.value,"PK"!=m.attributeKeyType)&&-1!=m.attributeKeyType.indexOf("PK")&&(m.attributeKeyType="PK"),p.attributes.push(m),f.edges&&f.edges.length)for(let e=0;e-1!=t.toLocaleLowerCase().indexOf(e)),b=n&&-1!=b.findIndex(e=>-1!=n.toLocaleLowerCase().indexOf(e));if(!b&&!g||b&&g){if(b&&g){var b=S(h.source.value,d),v=(b.attributeKeyType="PK",j=b.attributeName,x(h.source.parent.value)),O=S(h.target.value,d),T=(O.attributeKeyType="PK",A=O.attributeName,x(h.target.parent.value)),b={name:x(v)+"_"+x(T),attributes:[b,O]};i[b.name]||(i[b.name]=b);let t={entityA:v,entityB:b.name,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:`[${v}.${j}] to [${b.name}.${j}]`},n=(-1==a.findIndex(e=>e.entityA==t.entityA&&e.entityB==t.entityB&&e.roleA==t.roleA)&&a.push(t),{entityA:T,entityB:b.name,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:`[${T}.${A}] to [${b.name}.${A}]`});-1==a.findIndex(e=>e.entityA==n.entityA&&e.entityB==n.entityB&&e.roleA==n.roleA)&&a.push(n)}}else{O=S(h.source.value,d).attributeName;let e=h.source.parent.value;var j,A,v=C(e),T=(e=-1!=v.start&&-1!=v.end?(j=e.substring(v.start,v.end).trim(),x(e=e.substring(0,v.beforeStart).trim())+" "+N(j)):x(e),h.target.value),b=S(T,d);T=b.attributeName;let t=h.target.parent.value,n=(v=C(t),t=-1!=v.start&&-1!=v.end?(A=t.substring(v.start,v.end).trim(),x(t=t.substring(0,v.beforeStart).trim())+" "+N(A)):x(t),{entityA:g?e:t,entityB:g?t:e,relSpec:{cardA:"ZERO_OR_MORE",cardB:"ONLY_ONE",relType:"IDENTIFYING"},roleA:g?`[${e}.${O}] to [${t}.${T}]`:`[${t}.${T}] to [${e}.${O}]`});-1==a.findIndex(e=>e.entityA==n.entityA&&e.entityB==n.entityB&&e.roleA==n.roleA)&&a.push(n)}}}}}if(i[p.name]){let e=2;for(;i[p.name+e.toString()];)e++;i[p.name+e.toString()]=p}else i[p.name]=p}}e=w(i,a);return e},n.GenerateDatabaseModel=w,n.generateComment=N,n.CreateTableUI=function(r,e,t,o,i,a,n,l,s){if(t.forEach(function(t){var e,n=100+t.Name.length;(a=new mxCell(t.Name,new mxGeometry(l,0,n,26),"swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;")).vertex=!0,i&&null!==(e=r.editor.graph.getPreferredSizeForCell(i))&&(a.geometry.width=e.width+n),o.push(a),t.Properties.forEach(function(e){e=function(e,t,n,r){var o=t.Name+(t.ColumnProperties?" "+t.ColumnProperties:""),o=((n=new mxCell(o,new mxGeometry(0,0,90,26),"shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;")).vertex=!0,t.IsPrimaryKey&&t.IsForeignKey?"PK | FK":t.IsPrimaryKey?"PK":t.IsForeignKey?"FK":""),t=sb.cloneCell(n,o),o=(t.connectable=!1,t.style="shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;",t.geometry.width=54,t.geometry.height=26,n.insert(t),e.editor.graph.getPreferredSizeForCell(n));r&&(null!==o&&r.geometry.width 0) { - const graph = ui.editor.graph; - const view = graph.view; - const bds = graph.getGraphBounds(); - // Computes unscaled, untranslated graph bounds - const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize); - const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + 4 * graph.gridSize); - graph.setSelectionCells(graph.importCells(cells, x, y)); - // add foreign key edges - const model = graph.getModel(); - const columnQuantifiers = (0, sharedUtils_1.GetColumnQuantifiers)(type); - // const pt = graph.getFreeInsertPoint(); - foreignKeyList.forEach(function (fk) { - if (fk.IsDestination && fk.PrimaryKeyName && fk.ReferencesPropertyName && - fk.PrimaryKeyTableName && fk.ReferencesTableName) { - const insertEdge = mxUtils.bind(this, function (targetCell, sourceCell, edge) { - const label = ""; - const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; - const edgeCell = graph.insertEdge(null, null, label || "", (edge.invert) ? - sourceCell : targetCell, (edge.invert) ? targetCell : sourceCell, edgeStyle); - }); - const edge = { - invert: true - }; - let targetCell = null; - let sourceCell = null; - // locate edge source and target cells - for (const key in model.cells) { - if (targetCell && sourceCell) - break; - if (Object.hasOwnProperty.call(model.cells, key)) { - const mxcell = model.cells[key]; - if (mxcell.style && mxcell.style.trim().startsWith("swimlane;")) { - const entity = { - name: mxcell.value, - attributes: [] - }; - const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; - const isForeignTable = entity.name == fk.ReferencesTableName; - if (isPrimaryTable || isForeignTable) { - for (let c = 0; c < mxcell.children.length; c++) { - if (targetCell && sourceCell) - break; - const col = mxcell.children[c]; - if (col.mxObjectId.indexOf("mxCell") !== -1) { - if (col.style && col.style.trim().startsWith("shape=partialRectangle")) { - const attribute = (0, sharedUtils_1.getDbLabel)(col.value, columnQuantifiers); - if (isPrimaryTable && attribute.attributeName == fk.PrimaryKeyName) { - targetCell = col; - break; - } - else if (isForeignTable && attribute.attributeName == fk.ReferencesPropertyName) { - sourceCell = col; - break; - } - } - } - } - } - } - } - } - if (targetCell && sourceCell) - insertEdge(targetCell, sourceCell, edge); - } - }); - graph.scrollCellToVisible(graph.getSelectionCell()); + const createTableResult = (0, sharedUtils_1.CreateTableUI)(ui, wndFromSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type); + if (createTableResult) { + cells = createTableResult.cells; + dx = createTableResult.dx; + tableCell = createTableResult.tableCell; + rowCell = createTableResult.rowCell; } - wndFromSQL.setVisible(false); } ; mxUtils.br(divFromSQL); @@ -1228,16 +1117,18 @@ Draw.loadPlugin(function (ui) { },{"./utils/constants":5,"./utils/sharedUtils":6,"@funktechno/little-mermaid-2-the-sql/lib/src/generate-sql-ddl":1,"@funktechno/sqlsimpleparser":3}],5:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.validEnumTypes = exports.enumKeyword = exports.formatKeyword = exports.commentColumnQuantifiers = exports.pluginVersion = void 0; +exports.objectKeyword = exports.arrayKeyword = exports.nullableKeyword = exports.enumKeyword = exports.formatKeyword = exports.commentColumnQuantifiers = exports.pluginVersion = void 0; // export sql methods -exports.pluginVersion = "0.0.5"; +exports.pluginVersion = "0.0.6"; exports.commentColumnQuantifiers = { Start: "/**", End: "*/", }; exports.formatKeyword = "@format"; exports.enumKeyword = "enum"; -exports.validEnumTypes = ["string", "number", "integer", "boolean"]; +exports.nullableKeyword = "nullable"; +exports.arrayKeyword = "array"; +exports.objectKeyword = "object"; },{}],6:[function(require,module,exports){ "use strict"; @@ -1252,6 +1143,7 @@ exports.getCommentIndexes = getCommentIndexes; exports.getMermaidDiagramDb = getMermaidDiagramDb; exports.GenerateDatabaseModel = GenerateDatabaseModel; exports.generateComment = generateComment; +exports.CreateTableUI = CreateTableUI; const constants_1 = require("./constants"); /** * return text quantifiers for dialect @@ -1259,8 +1151,8 @@ const constants_1 = require("./constants"); */ function GetColumnQuantifiers(type) { const chars = { - Start: "\"", - End: "\"", + Start: '"', + End: '"', }; if (type && ["mysql", "ts", "openapi"].includes(type)) { chars.Start = "`"; @@ -1284,6 +1176,11 @@ function removeHtml(label) { tempDiv.remove(); return text; } +/** + * add db ends + * @param label + * @returns + */ function dbTypeEnds(label) { const char1 = "`"; const char2 = "`"; @@ -1293,6 +1190,11 @@ function dbTypeEnds(label) { // } return `${char1}${label}${char2}`; } +/** + * remove name quantifiers + * @param name + * @returns + */ function RemoveNameQuantifiers(name) { return name.replace(/\[|\]|\(|\"|\'|\`/g, "").trim(); } @@ -1324,7 +1226,7 @@ function entityName(description, format) { result += `${description}`; } if (format) { - result += ` @format ${format}`; + result += ` ${constants_1.formatKeyword} ${format}`; } if (result) { result = result.trim(); @@ -1334,16 +1236,24 @@ function entityName(description, format) { } function getCommentIndexes(result) { let hasComment = false; - if (result.indexOf(constants_1.commentColumnQuantifiers.Start) !== -1 && result.indexOf(constants_1.commentColumnQuantifiers.End) !== -1) { + if (result.indexOf(constants_1.commentColumnQuantifiers.Start) !== -1 && + result.indexOf(constants_1.commentColumnQuantifiers.End) !== -1) { hasComment = true; } - const beforeIndex = hasComment ? result.indexOf(constants_1.commentColumnQuantifiers.Start) : -1; - const firstSpaceIndex = hasComment ? result.indexOf(constants_1.commentColumnQuantifiers.Start) + constants_1.commentColumnQuantifiers.Start.length : -1; - const lastSpaceIndex = hasComment ? result.indexOf(constants_1.commentColumnQuantifiers.End) - 1 : -1; + const beforeIndex = hasComment + ? result.indexOf(constants_1.commentColumnQuantifiers.Start) + : -1; + const firstSpaceIndex = hasComment + ? result.indexOf(constants_1.commentColumnQuantifiers.Start) + + constants_1.commentColumnQuantifiers.Start.length + : -1; + const lastSpaceIndex = hasComment + ? result.indexOf(constants_1.commentColumnQuantifiers.End) - 1 + : -1; return { beforeStart: beforeIndex, start: firstSpaceIndex, - end: lastSpaceIndex + end: lastSpaceIndex, }; } /** @@ -1360,6 +1270,7 @@ function getMermaidDiagramDb(ui, type) { const relationships = []; // TODO: support for ts and openapi enum // build models + // fix fk for comments for (const key in model.cells) { if (Object.hasOwnProperty.call(model.cells, key)) { const mxcell = model.cells[key]; @@ -1378,7 +1289,9 @@ function getMermaidDiagramDb(ui, type) { result = result.substring(firstSpaceIndex, lastSpaceIndex); if (result.indexOf(constants_1.formatKeyword) !== -1) { const formatIndex = result.indexOf(constants_1.formatKeyword); - formatValue = result.substring(formatIndex + constants_1.formatKeyword.length).trim(); + formatValue = result + .substring(formatIndex + constants_1.formatKeyword.length) + .trim(); result = result.substring(0, formatIndex); } if (result) { @@ -1392,22 +1305,23 @@ function getMermaidDiagramDb(ui, type) { }; const comment = generateComment(description, formatValue); if (comment) { - entity.name += comment; + entity.name += ` ${comment}`; } - // const comment = + // const comment = for (let c = 0; c < mxcell.children.length; c++) { const col = mxcell.children[c]; if (col.mxObjectId.indexOf("mxCell") !== -1) { - if (col.style && col.style.trim().startsWith("shape=partialRectangle")) { + if (col.style && + col.style.trim().startsWith("shape=partialRectangle")) { const columnQuantifiers = GetColumnQuantifiers(type); //Get delimiter of column name //Get full name const attribute = getDbLabel(col.value, columnQuantifiers); - const attributeKeyType = col.children.find(x => ["FK", "PK"].findIndex(k => k == x.value.toUpperCase()) !== -1 || - x.value.toUpperCase().indexOf("PK,") != -1); + const attributeKeyType = col.children.find((x) => ["FK", "PK"].findIndex((k) => k == x.value.toUpperCase()) !== -1 || x.value.toUpperCase().indexOf("PK,") != -1); if (attributeKeyType) { attribute.attributeKeyType = attributeKeyType.value; - if (attribute.attributeKeyType != "PK" && attribute.attributeKeyType.indexOf("PK") != -1) { + if (attribute.attributeKeyType != "PK" && + attribute.attributeKeyType.indexOf("PK") != -1) { attribute.attributeKeyType = "PK"; } } @@ -1417,53 +1331,106 @@ function getMermaidDiagramDb(ui, type) { for (let e = 0; e < col.edges.length; e++) { const edge = col.edges[e]; if (edge.mxObjectId.indexOf("mxCell") !== -1) { - if (edge.style && edge.style.indexOf("endArrow=") != -1 && edge.source && - edge.source.value && edge.target && edge.target.value) { + if (edge.style && + edge.style.indexOf("endArrow=") != -1 && + edge.source && + edge.source.value && + edge.target && + edge.target.value) { // need to check if end is open or certain value to determin relationship type // extract endArrow txt // check if both match and contain many or open // if both match and are many then create a new table const endCheck = "endArrow="; - const endArr = edge.style.indexOf(endCheck) != -1 ? - edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length, edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length).indexOf(";") + edge.style.indexOf(endCheck) + endCheck.length) + const endArr = edge.style.indexOf(endCheck) != -1 + ? edge.style.substring(edge.style.indexOf(endCheck) + endCheck.length, edge.style + .substring(edge.style.indexOf(endCheck) + + endCheck.length) + .indexOf(";") + + edge.style.indexOf(endCheck) + + endCheck.length) : ""; const startCheck = "startArrow="; - const startArr = edge.style.indexOf(startCheck) != -1 ? - edge.style.substring(edge.style.indexOf(startCheck) + startCheck.length, edge.style.substring(edge.style.indexOf(startCheck) + startCheck.length).indexOf(";") + edge.style.indexOf(startCheck) + startCheck.length) + const startArr = edge.style.indexOf(startCheck) != -1 + ? edge.style.substring(edge.style.indexOf(startCheck) + + startCheck.length, edge.style + .substring(edge.style.indexOf(startCheck) + + startCheck.length) + .indexOf(";") + + edge.style.indexOf(startCheck) + + startCheck.length) : ""; const manyCheck = ["open", "many"]; - const sourceIsPrimary = endArr && manyCheck - .findIndex(x => endArr.toLocaleLowerCase().indexOf(x) != -1) != -1; - const targetIsPrimary = startArr && manyCheck - .findIndex(x => startArr.toLocaleLowerCase().indexOf(x) != -1) != -1; + const sourceIsPrimary = endArr && + manyCheck.findIndex((x) => endArr.toLocaleLowerCase().indexOf(x) != -1) != -1; + const targetIsPrimary = startArr && + manyCheck.findIndex((x) => startArr.toLocaleLowerCase().indexOf(x) != -1) != -1; // has to be one to many and not one to one if ((targetIsPrimary || sourceIsPrimary) && !(targetIsPrimary && sourceIsPrimary)) { let sourceId = edge.source.value; const sourceAttr = getDbLabel(sourceId, columnQuantifiers); sourceId = sourceAttr.attributeName; - const sourceEntity = RemoveNameQuantifiers(edge.source.parent.value); + let sourceEntity = edge.source.parent.value; + // extract comments + let commentsIndexes = getCommentIndexes(sourceEntity); + if (commentsIndexes.start != -1 && + commentsIndexes.end != -1) { + const sourceComment = sourceEntity + .substring(commentsIndexes.start, commentsIndexes.end) + .trim(); + sourceEntity = sourceEntity + .substring(0, commentsIndexes.beforeStart) + .trim(); + sourceEntity = `${RemoveNameQuantifiers(sourceEntity)} ${generateComment(sourceComment)}`; + } + else { + sourceEntity = RemoveNameQuantifiers(sourceEntity); + } let targetId = edge.target.value; const targetAttr = getDbLabel(targetId, columnQuantifiers); targetId = targetAttr.attributeName; - const targetEntity = RemoveNameQuantifiers(edge.target.parent.value); + let targetEntity = edge.target.parent.value; + commentsIndexes = getCommentIndexes(targetEntity); + if (commentsIndexes.start != -1 && + commentsIndexes.end != -1) { + const targetComment = targetEntity + .substring(commentsIndexes.start, commentsIndexes.end) + .trim(); + targetEntity = targetEntity + .substring(0, commentsIndexes.beforeStart) + .trim(); + targetEntity = `${RemoveNameQuantifiers(targetEntity)} ${generateComment(targetComment)}`; + } + else { + targetEntity = RemoveNameQuantifiers(targetEntity); + } + // const targetEntity = RemoveNameQuantifiers( + // edge.target.parent.value + // ); // entityA primary // entityB foreign const relationship = { - entityA: sourceIsPrimary ? sourceEntity : targetEntity, - entityB: sourceIsPrimary ? targetEntity : sourceEntity, + entityA: sourceIsPrimary + ? sourceEntity + : targetEntity, + entityB: sourceIsPrimary + ? targetEntity + : sourceEntity, // based off of styles? relSpec: { cardA: "ZERO_OR_MORE", cardB: "ONLY_ONE", - relType: "IDENTIFYING" + relType: "IDENTIFYING", }, - roleA: sourceIsPrimary ? - `[${sourceEntity}.${sourceId}] to [${targetEntity}.${targetId}]` : - `[${targetEntity}.${targetId}] to [${sourceEntity}.${sourceId}]` + roleA: sourceIsPrimary + ? `[${sourceEntity}.${sourceId}] to [${targetEntity}.${targetId}]` + : `[${targetEntity}.${targetId}] to [${sourceEntity}.${sourceId}]`, }; // check that is doesn't already exist - const exists = relationships.findIndex(r => r.entityA == relationship.entityA && r.entityB == relationship.entityB && r.roleA == relationship.roleA); + const exists = relationships.findIndex((r) => r.entityA == relationship.entityA && + r.entityB == relationship.entityB && + r.roleA == relationship.roleA); if (exists == -1) { relationships.push(relationship); } @@ -1481,8 +1448,10 @@ function getMermaidDiagramDb(ui, type) { targetId = targetAttr.attributeName; const targetEntity = RemoveNameQuantifiers(edge.target.parent.value); const compositeEntity = { - name: RemoveNameQuantifiers(sourceEntity) + "_" + RemoveNameQuantifiers(targetEntity), - attributes: [sourceAttr, targetAttr] + name: RemoveNameQuantifiers(sourceEntity) + + "_" + + RemoveNameQuantifiers(targetEntity), + attributes: [sourceAttr, targetAttr], }; // add composite entity if (entities[compositeEntity.name]) { @@ -1500,12 +1469,14 @@ function getMermaidDiagramDb(ui, type) { relSpec: { cardA: "ZERO_OR_MORE", cardB: "ONLY_ONE", - relType: "IDENTIFYING" + relType: "IDENTIFYING", }, - roleA: `[${sourceEntity}.${sourceId}] to [${compositeEntity.name}.${sourceId}]` + roleA: `[${sourceEntity}.${sourceId}] to [${compositeEntity.name}.${sourceId}]`, }; // check that is doesn't already exist - let exists = relationships.findIndex(r => r.entityA == relationship.entityA && r.entityB == relationship.entityB && r.roleA == relationship.roleA); + let exists = relationships.findIndex((r) => r.entityA == relationship.entityA && + r.entityB == relationship.entityB && + r.roleA == relationship.roleA); if (exists == -1) { relationships.push(relationship); } @@ -1516,12 +1487,14 @@ function getMermaidDiagramDb(ui, type) { relSpec: { cardA: "ZERO_OR_MORE", cardB: "ONLY_ONE", - relType: "IDENTIFYING" + relType: "IDENTIFYING", }, - roleA: `[${targetEntity}.${targetId}] to [${compositeEntity.name}.${targetId}]` + roleA: `[${targetEntity}.${targetId}] to [${compositeEntity.name}.${targetId}]`, }; // check that is doesn't already exist - exists = relationships.findIndex(r => r.entityA == relationship2.entityA && r.entityB == relationship2.entityB && r.roleA == relationship2.roleA); + exists = relationships.findIndex((r) => r.entityA == relationship2.entityA && + r.entityB == relationship2.entityB && + r.roleA == relationship2.roleA); if (exists == -1) { relationships.push(relationship2); } @@ -1551,6 +1524,12 @@ function getMermaidDiagramDb(ui, type) { const db = GenerateDatabaseModel(entities, relationships); return db; } +/** + * genearte a database model + * @param entities + * @param relationships + * @returns + */ function GenerateDatabaseModel(entities, relationships) { class DatabaseModel { constructor(entities, relationships) { @@ -1567,13 +1546,19 @@ function GenerateDatabaseModel(entities, relationships) { const db = new DatabaseModel(entities, relationships); return db; } +/** + * generate a comment using description and format + * @param description + * @param formatValue + * @returns + */ function generateComment(description, formatValue) { let result = ""; if (description) { result += `${description}`; } if (formatValue) { - result += ` @format ${formatValue}`; + result += ` ${constants_1.formatKeyword} ${formatValue}`; } if (result) { result = result.trim(); @@ -1581,5 +1566,174 @@ function generateComment(description, formatValue) { } return result; } +/** + * create uml tables from db models + * @param ui + * @param wndFromInput + * @param tableList + * @param cells + * @param rowCell + * @param tableCell + * @param foreignKeyList + * @param dx + * @param type + * @returns + */ +function CreateTableUI(ui, wndFromInput, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type) { + tableList.forEach(function (tableModel) { + //Define table size width + const maxNameLenght = 100 + tableModel.Name.length; + //Create Table + tableCell = new mxCell(tableModel.Name, new mxGeometry(dx, 0, maxNameLenght, 26), "swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize=26;fillColor=default;horizontalStack=0;resizeParent=1;resizeLast=0;collapsible=1;marginBottom=0;swimlaneFillColor=default;align=center;"); + tableCell.vertex = true; + //Resize row + if (rowCell) { + const size = ui.editor.graph.getPreferredSizeForCell(rowCell); + if (size !== null) { + tableCell.geometry.width = size.width + maxNameLenght; + } + } + //Add Table to cells + cells.push(tableCell); + //Add properties + tableModel.Properties.forEach(function (propertyModel) { + //Add row + const addRowResult = AddRow(ui, propertyModel, tableModel.Name, rowCell, tableCell); + if (addRowResult) { + rowCell = addRowResult.rowCell; + tableCell = addRowResult.tableCell; + } + }); + //Close table + dx += tableCell.geometry.width + 40; + tableCell = null; + }); + if (cells.length > 0) { + const graph = ui.editor.graph; + const view = graph.view; + const bds = graph.getGraphBounds(); + // Computes unscaled, untranslated graph bounds + const x = Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize); + const y = Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + + 4 * graph.gridSize); + graph.setSelectionCells(graph.importCells(cells, x, y)); + // add foreign key edges + const model = graph.getModel(); + const columnQuantifiers = GetColumnQuantifiers(type); + // const pt = graph.getFreeInsertPoint(); + foreignKeyList.forEach(function (fk) { + if (fk.IsDestination && + fk.PrimaryKeyName && + fk.ReferencesPropertyName && + fk.PrimaryKeyTableName && + fk.ReferencesTableName) { + const insertEdge = mxUtils.bind(this, function (targetCell, sourceCell, edge) { + const label = ""; + const edgeStyle = "edgeStyle=entityRelationEdgeStyle;html=1;endArrow=ERzeroToMany;startArrow=ERzeroToOne;labelBackgroundColor=none;fontFamily=Verdana;fontSize=14;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.608;entryDx=0;entryDy=0;entryPerimeter=0;"; + const edgeCell = graph.insertEdge(null, null, label || "", edge.invert ? sourceCell : targetCell, edge.invert ? targetCell : sourceCell, edgeStyle); + }); + const edge = { + invert: true, + }; + let targetCell = null; + let sourceCell = null; + // locate edge source and target cells + for (const key in model.cells) { + if (targetCell && sourceCell) + break; + if (Object.hasOwnProperty.call(model.cells, key)) { + const mxcell = model.cells[key]; + if (mxcell.style && mxcell.style.trim().startsWith("swimlane;")) { + const entity = { + name: mxcell.value, + attributes: [], + }; + const isPrimaryTable = entity.name == fk.PrimaryKeyTableName; + const isForeignTable = entity.name == fk.ReferencesTableName; + if (isPrimaryTable || isForeignTable) { + for (let c = 0; c < mxcell.children.length; c++) { + if (targetCell && sourceCell) + break; + const col = mxcell.children[c]; + if (col.mxObjectId.indexOf("mxCell") !== -1) { + if (col.style && + col.style.trim().startsWith("shape=partialRectangle")) { + const attribute = getDbLabel(col.value, columnQuantifiers); + if (isPrimaryTable && + dbTypeEnds(attribute.attributeName) == fk.PrimaryKeyName) { + targetCell = col; + // allow recursion + } + if (isForeignTable && + dbTypeEnds(attribute.attributeName) == + fk.ReferencesPropertyName) { + sourceCell = col; + } + if (targetCell && sourceCell) + break; + } + } + } + } + } + } + } + if (targetCell && sourceCell) + insertEdge(targetCell, sourceCell, edge); + } + }); + graph.scrollCellToVisible(graph.getSelectionCell()); + } + wndFromInput.setVisible(false); + return { + cells, + rowCell, + tableCell, + dx, + }; +} +/** + * add row to uml table + * @param ui + * @param propertyModel + * @param tableName + * @param rowCell + * @param tableCell + * @returns + */ +function AddRow(ui, propertyModel, tableName, rowCell, tableCell) { + const cellName = propertyModel.Name + + (propertyModel.ColumnProperties + ? " " + propertyModel.ColumnProperties + : ""); + rowCell = new mxCell(cellName, new mxGeometry(0, 0, 90, 26), "shape=partialRectangle;top=0;left=0;right=0;bottom=0;align=left;verticalAlign=top;spacingTop=-2;fillColor=none;spacingLeft=64;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;dropTarget=0;"); + rowCell.vertex = true; + const columnType = propertyModel.IsPrimaryKey && propertyModel.IsForeignKey + ? "PK | FK" + : propertyModel.IsPrimaryKey + ? "PK" + : propertyModel.IsForeignKey + ? "FK" + : ""; + const left = sb.cloneCell(rowCell, columnType); + left.connectable = false; + left.style = + "shape=partialRectangle;top=0;left=0;bottom=0;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=180;points=[];portConstraint=eastwest;part=1;"; + left.geometry.width = 54; + left.geometry.height = 26; + rowCell.insert(left); + const size = ui.editor.graph.getPreferredSizeForCell(rowCell); + if (tableCell) { + if (size !== null && tableCell.geometry.width < size.width + 10) { + tableCell.geometry.width = size.width + 10; + } + tableCell.insert(rowCell); + tableCell.geometry.height += 26; + } + return { + rowCell, + tableCell, + }; +} },{"./constants":5}]},{},[4]); diff --git a/package.json b/package.json index c7def0b..8b3724c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqltooling-drawio", - "version": "0.0.5", + "version": "0.0.6", "description": "plugins for sql tooling in drawio", "main": "index.js", "engines": { From a506b1be7bac8bebcf2b1319e45668a9c33bd399 Mon Sep 17 00:00:00 2001 From: lastlink Date: Sat, 6 Jul 2024 14:02:48 -0400 Subject: [PATCH 6/8] update quote error --- eslint.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 0c7f194..8d0f128 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -9,7 +9,7 @@ export default [ files: ["**/*.{js,mjs,cjs,ts}"], rules: { semi: ["error", "always"], - quotes: ["error", "double"], + quotes: ["off", "double"], "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/camelcase": "off", "@typescript-eslint/no-unsafe-function-type": "off", From e4ddfcc812594abebf14361cc514a91a43c64e80 Mon Sep 17 00:00:00 2001 From: lastlink Date: Sat, 6 Jul 2024 14:04:51 -0400 Subject: [PATCH 7/8] code cleanup and format --- src/nosql-ts.ts | 527 +++++++++++++++++++--------------- src/nosql.ts | 462 ++++++++++++++++------------- src/sql.ts | 517 +++++++++++++++++---------------- src/types/sql-plugin-types.ts | 22 +- src/utils/constants-nosql.ts | 6 +- src/utils/nosqlUtils.ts | 41 +-- 6 files changed, 858 insertions(+), 717 deletions(-) diff --git a/src/nosql-ts.ts b/src/nosql-ts.ts index a803419..8b9c141 100644 --- a/src/nosql-ts.ts +++ b/src/nosql-ts.ts @@ -1,14 +1,45 @@ -import { DbDefinition, DbRelationshipDefinition } from "@funktechno/little-mermaid-2-the-sql/lib/src/types"; -import { DatabaseModelResult, TableAttribute, TableEntity } from "./types/sql-plugin-types"; -import { DatabaseModel, ForeignKeyModel, PrimaryKeyModel, PropertyModel, TableModel } from "@funktechno/sqlsimpleparser/lib/types"; +import { + DbDefinition, + DbRelationshipDefinition, +} from "@funktechno/little-mermaid-2-the-sql/lib/src/types"; +import { + DatabaseModelResult, + TableAttribute, + TableEntity, +} from "./types/sql-plugin-types"; +import { + DatabaseModel, + ForeignKeyModel, + PrimaryKeyModel, + PropertyModel, + TableModel, +} from "@funktechno/sqlsimpleparser/lib/types"; import { JSONSchema4, JSONSchema4TypeName } from "json-schema"; -import { convertCoreTypesToJsonSchema, convertOpenApiToCoreTypes, jsonSchemaDocumentToOpenApi } from "core-types-json-schema"; -import { JsonSchemaDocumentToOpenApiOptions, PartialOpenApiSchema } from "openapi-json-schema"; +import { + convertCoreTypesToJsonSchema, + convertOpenApiToCoreTypes, + jsonSchemaDocumentToOpenApi, +} from "core-types-json-schema"; +import { + JsonSchemaDocumentToOpenApiOptions, + PartialOpenApiSchema, +} from "openapi-json-schema"; import { convertTypeScriptToCoreTypes } from "core-types-ts/dist/lib/ts-to-core-types"; import { convertCoreTypesToTypeScript } from "core-types-ts"; -import { CreateTableUI, GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; +import { + CreateTableUI, + GetColumnQuantifiers, + RemoveNameQuantifiers, + dbTypeEnds, + getDbLabel, + getMermaidDiagramDb, +} from "./utils/sharedUtils"; import { pluginVersion } from "./utils/constants"; -import { ConvertOpenApiToDatabaseModel, dbToOpenApi, GeneratePropertyModel } from "./utils/nosqlUtils"; +import { + ConvertOpenApiToDatabaseModel, + dbToOpenApi, + GeneratePropertyModel, +} from "./utils/nosqlUtils"; import { defaultReset, defaultResetOpenApi } from "./utils/constants-nosql"; declare const window: Customwindow; @@ -17,257 +48,281 @@ declare const window: Customwindow; * SQL Tools Plugin for importing and exporting typescript interfaces. * Version: */ -Draw.loadPlugin(function(ui) { - - //Create Base div - const divGenSQL = document.createElement("div"); - divGenSQL.style.userSelect = "none"; - divGenSQL.style.overflow = "hidden"; - divGenSQL.style.padding = "10px"; - divGenSQL.style.height = "100%"; - - const sqlInputGenSQL = document.createElement("textarea"); - sqlInputGenSQL.style.height = "200px"; - sqlInputGenSQL.style.width = "100%"; - const sqlExportDefault = "-- click a nosql type button"; - sqlInputGenSQL.value = sqlExportDefault; - mxUtils.br(divGenSQL); - divGenSQL.appendChild(sqlInputGenSQL); - const theMenuExportAs = ui.menus.get("exportAs"); - let buttonLabel = "tonosql=To NoSQL"; - // vscode extension support - // FIXME: not compatible with vscode getting unexpected syntax error - if(!(theMenuExportAs && !window.VsCodeApi)) { - buttonLabel = "tonosql=Export As NoSQL"; +Draw.loadPlugin(function (ui) { + //Create Base div + const divGenSQL = document.createElement("div"); + divGenSQL.style.userSelect = "none"; + divGenSQL.style.overflow = "hidden"; + divGenSQL.style.padding = "10px"; + divGenSQL.style.height = "100%"; + + const sqlInputGenSQL = document.createElement("textarea"); + sqlInputGenSQL.style.height = "200px"; + sqlInputGenSQL.style.width = "100%"; + const sqlExportDefault = "-- click a nosql type button"; + sqlInputGenSQL.value = sqlExportDefault; + mxUtils.br(divGenSQL); + divGenSQL.appendChild(sqlInputGenSQL); + const theMenuExportAs = ui.menus.get("exportAs"); + let buttonLabel = "tonosql=To NoSQL"; + // vscode extension support + // FIXME: not compatible with vscode getting unexpected syntax error + if (!(theMenuExportAs && !window.VsCodeApi)) { + buttonLabel = "tonosql=Export As NoSQL"; + } + // Extends Extras menu + mxResources.parse(buttonLabel); + + const wndGenSQL = new mxWindow( + mxResources.get("tonosql"), + divGenSQL, + document.body.offsetWidth - 480, + 140, + 320, + 320, + true, + true + ); + wndGenSQL.destroyOnClose = false; + wndGenSQL.setMaximizable(false); + wndGenSQL.setResizable(false); + wndGenSQL.setClosable(true); + + function generateNoSql(type: "ts" | "openapi" | undefined) { + // get diagram model + const db = getMermaidDiagramDb(ui, type); + const openapi = dbToOpenApi(db); + let result = ""; + if (type == "ts") { + const { data: doc } = convertOpenApiToCoreTypes(openapi); + const { data: sourceCode } = convertCoreTypesToTypeScript(doc); + result = + `/*\n\tGenerated in drawio\n\tDatabase: ${type}\n\tPlugin: nosql\n\tVersion: ${pluginVersion}\n*/\n\n` + + result; + result += sourceCode; + } else if (type == "openapi") { + result = JSON.stringify(openapi, null, 2); } - // Extends Extras menu - mxResources.parse(buttonLabel); - - const wndGenSQL = new mxWindow(mxResources.get("tonosql"), divGenSQL, document.body.offsetWidth - 480, 140, - 320, 320, true, true); - wndGenSQL.destroyOnClose = false; - wndGenSQL.setMaximizable(false); - wndGenSQL.setResizable(false); - wndGenSQL.setClosable(true); - - function generateNoSql(type: "ts" | "openapi" | undefined) { - // get diagram model - const db = getMermaidDiagramDb(ui, type); - const openapi = dbToOpenApi(db); - let result = ""; - if(type == "ts"){ - - const { data: doc } = convertOpenApiToCoreTypes( openapi ); - const { data: sourceCode } = convertCoreTypesToTypeScript( doc ); - result = `/*\n\tGenerated in drawio\n\tDatabase: ${type}\n\tPlugin: nosql\n\tVersion: ${pluginVersion}\n*/\n\n` + result; - result += sourceCode; - - } else if(type == "openapi"){ - result = JSON.stringify(openapi, null, 2); - } - sqlInputGenSQL.value = result; - }; + sqlInputGenSQL.value = result; + } - mxUtils.br(divGenSQL); + mxUtils.br(divGenSQL); - const resetBtnGenSQL = mxUtils.button(mxResources.get("reset"), function() { - sqlInputGenSQL.value = sqlExportDefault; - }); + const resetBtnGenSQL = mxUtils.button(mxResources.get("reset"), function () { + sqlInputGenSQL.value = sqlExportDefault; + }); - resetBtnGenSQL.style.marginTop = "8px"; - resetBtnGenSQL.style.marginRight = "4px"; - resetBtnGenSQL.style.padding = "4px"; - divGenSQL.appendChild(resetBtnGenSQL); + resetBtnGenSQL.style.marginTop = "8px"; + resetBtnGenSQL.style.marginRight = "4px"; + resetBtnGenSQL.style.padding = "4px"; + divGenSQL.appendChild(resetBtnGenSQL); - let btnGenSQL_ts = mxUtils.button("TS", function() { - generateNoSql("ts"); - }); + let btnGenSQL_ts = mxUtils.button("TS", function () { + generateNoSql("ts"); + }); - btnGenSQL_ts.style.marginTop = "8px"; - btnGenSQL_ts.style.padding = "4px"; - divGenSQL.appendChild(btnGenSQL_ts); + btnGenSQL_ts.style.marginTop = "8px"; + btnGenSQL_ts.style.padding = "4px"; + divGenSQL.appendChild(btnGenSQL_ts); - btnGenSQL_ts = mxUtils.button("OpenAPI", function() { - generateNoSql("openapi"); - }); + btnGenSQL_ts = mxUtils.button("OpenAPI", function () { + generateNoSql("openapi"); + }); - btnGenSQL_ts.style.marginTop = "8px"; - btnGenSQL_ts.style.padding = "4px"; - divGenSQL.appendChild(btnGenSQL_ts); + btnGenSQL_ts.style.marginTop = "8px"; + btnGenSQL_ts.style.padding = "4px"; + divGenSQL.appendChild(btnGenSQL_ts); - // Adds action - ui.actions.addAction("tonosql", function() { - wndGenSQL.setVisible(!wndGenSQL.isVisible()); + // Adds action + ui.actions.addAction("tonosql", function () { + wndGenSQL.setVisible(!wndGenSQL.isVisible()); - if (wndGenSQL.isVisible()) { - sqlInputGenSQL.focus(); - } - }); - // end export sql methods - - // import diagrams from sql text methods - - - //Table Info - let foreignKeyList: ForeignKeyModel[] = []; - let primaryKeyList: PrimaryKeyModel[] = []; - let tableList: TableModel[] = []; - let cells: mxCell[] = []; - let tableCell: mxCell|null = null; - let rowCell: mxCell|null = null; - let dx = 0; - let exportedTables = 0; - - - //Create Base div - const divFromNOSQL = document.createElement("div"); - divFromNOSQL.style.userSelect = "none"; - divFromNOSQL.style.overflow = "hidden"; - divFromNOSQL.style.padding = "10px"; - divFromNOSQL.style.height = "100%"; - - const sqlInputFromNOSQL = document.createElement("textarea"); - sqlInputFromNOSQL.style.height = "200px"; - sqlInputFromNOSQL.style.width = "100%"; - - sqlInputFromNOSQL.value = defaultReset; - mxUtils.br(divFromNOSQL); - divFromNOSQL.appendChild(sqlInputFromNOSQL); - - // const graph = ui.editor.graph; - - // Extends Extras menu - mxResources.parse("fromNoSql=From NoSQL"); - - const wndFromNOSQL = new mxWindow(mxResources.get("fromNoSql"), divFromNOSQL, document.body.offsetWidth - 480, 140, - 320, 320, true, true); - wndFromNOSQL.destroyOnClose = false; - wndFromNOSQL.setMaximizable(false); - wndFromNOSQL.setResizable(false); - wndFromNOSQL.setClosable(true); - - function parseFromInput(text: string, type?: "ts" | "openapi" | undefined) { - // reset values - cells = []; - tableCell = null; - rowCell = null; - try { - let openApi: PartialOpenApiSchema|null = null; - const openApiOptions: JsonSchemaDocumentToOpenApiOptions = { - title: "nosql default options", - version: pluginVersion - }; - if(type == "openapi"){ - // should already be a json, but going to serialize to openapi for validation - const data = JSON.parse(text); - const { data: doc } = convertOpenApiToCoreTypes( data ); - const { data: jsonSchema } = convertCoreTypesToJsonSchema( doc ); - // was losing format option, just going to check if exception thrown here - jsonSchemaDocumentToOpenApi( jsonSchema, openApiOptions ); - openApi = data; - } else if(type == "ts"){ - // serialize typescript classes to openapi spec - const { data: doc } = convertTypeScriptToCoreTypes( text ); - const { data: jsonSchema } = convertCoreTypesToJsonSchema( doc ); - openApi = jsonSchemaDocumentToOpenApi( jsonSchema, openApiOptions ); - } - const schemas = openApi?.components?.schemas; - if(schemas){ - const models = ConvertOpenApiToDatabaseModel(schemas); - foreignKeyList = models.ForeignKeyList; - primaryKeyList = models.PrimaryKeyList; - tableList = models.TableList; - exportedTables = tableList.length; - const createTableResult = CreateTableUI(ui, wndFromNOSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type); - if(createTableResult){ - cells = createTableResult.cells; - dx = createTableResult.dx; - tableCell = createTableResult.tableCell; - rowCell = createTableResult.rowCell; - } - } - - } catch (error) { - console.log(`unable to serialize the response:${type}`); - console.log(error); + if (wndGenSQL.isVisible()) { + sqlInputGenSQL.focus(); + } + }); + // end export sql methods + + // import diagrams from sql text methods + + //Table Info + let foreignKeyList: ForeignKeyModel[] = []; + let primaryKeyList: PrimaryKeyModel[] = []; + let tableList: TableModel[] = []; + let cells: mxCell[] = []; + let tableCell: mxCell | null = null; + let rowCell: mxCell | null = null; + let dx = 0; + let exportedTables = 0; + + //Create Base div + const divFromNOSQL = document.createElement("div"); + divFromNOSQL.style.userSelect = "none"; + divFromNOSQL.style.overflow = "hidden"; + divFromNOSQL.style.padding = "10px"; + divFromNOSQL.style.height = "100%"; + + const sqlInputFromNOSQL = document.createElement("textarea"); + sqlInputFromNOSQL.style.height = "200px"; + sqlInputFromNOSQL.style.width = "100%"; + + sqlInputFromNOSQL.value = defaultReset; + mxUtils.br(divFromNOSQL); + divFromNOSQL.appendChild(sqlInputFromNOSQL); + + // const graph = ui.editor.graph; + + // Extends Extras menu + mxResources.parse("fromNoSql=From NoSQL"); + + const wndFromNOSQL = new mxWindow( + mxResources.get("fromNoSql"), + divFromNOSQL, + document.body.offsetWidth - 480, + 140, + 320, + 320, + true, + true + ); + wndFromNOSQL.destroyOnClose = false; + wndFromNOSQL.setMaximizable(false); + wndFromNOSQL.setResizable(false); + wndFromNOSQL.setClosable(true); + + function parseFromInput(text: string, type?: "ts" | "openapi" | undefined) { + // reset values + cells = []; + tableCell = null; + rowCell = null; + try { + let openApi: PartialOpenApiSchema | null = null; + const openApiOptions: JsonSchemaDocumentToOpenApiOptions = { + title: "nosql default options", + version: pluginVersion, + }; + if (type == "openapi") { + // should already be a json, but going to serialize to openapi for validation + const data = JSON.parse(text); + const { data: doc } = convertOpenApiToCoreTypes(data); + const { data: jsonSchema } = convertCoreTypesToJsonSchema(doc); + // was losing format option, just going to check if exception thrown here + jsonSchemaDocumentToOpenApi(jsonSchema, openApiOptions); + openApi = data; + } else if (type == "ts") { + // serialize typescript classes to openapi spec + const { data: doc } = convertTypeScriptToCoreTypes(text); + const { data: jsonSchema } = convertCoreTypesToJsonSchema(doc); + openApi = jsonSchemaDocumentToOpenApi(jsonSchema, openApiOptions); + } + const schemas = openApi?.components?.schemas; + if (schemas) { + const models = ConvertOpenApiToDatabaseModel(schemas); + foreignKeyList = models.ForeignKeyList; + primaryKeyList = models.PrimaryKeyList; + tableList = models.TableList; + exportedTables = tableList.length; + const createTableResult = CreateTableUI( + ui, + wndFromNOSQL, + tableList, + cells, + rowCell, + tableCell, + foreignKeyList, + dx, + type + ); + if (createTableResult) { + cells = createTableResult.cells; + dx = createTableResult.dx; + tableCell = createTableResult.tableCell; + rowCell = createTableResult.rowCell; } - }; + } + } catch (error) { + console.log(`unable to serialize the response:${type}`); + console.log(error); + } + } - mxUtils.br(divFromNOSQL); + mxUtils.br(divFromNOSQL); - const resetBtnFromNOSQL = mxUtils.button(mxResources.get("Reset TS"), function() { - sqlInputFromNOSQL.value = defaultReset; - }); + const resetBtnFromNOSQL = mxUtils.button( + mxResources.get("Reset TS"), + function () { + sqlInputFromNOSQL.value = defaultReset; + } + ); - resetBtnFromNOSQL.style.marginTop = "8px"; - resetBtnFromNOSQL.style.marginRight = "4px"; - resetBtnFromNOSQL.style.padding = "4px"; - divFromNOSQL.appendChild(resetBtnFromNOSQL); + resetBtnFromNOSQL.style.marginTop = "8px"; + resetBtnFromNOSQL.style.marginRight = "4px"; + resetBtnFromNOSQL.style.padding = "4px"; + divFromNOSQL.appendChild(resetBtnFromNOSQL); - const resetOpenAPIBtnFromNOSQL = mxUtils.button("Reset OpenAPI", function() { - sqlInputFromNOSQL.value = defaultResetOpenApi; - }); + const resetOpenAPIBtnFromNOSQL = mxUtils.button("Reset OpenAPI", function () { + sqlInputFromNOSQL.value = defaultResetOpenApi; + }); - resetOpenAPIBtnFromNOSQL.style.marginTop = "8px"; - resetOpenAPIBtnFromNOSQL.style.marginRight = "4px"; - resetOpenAPIBtnFromNOSQL.style.padding = "4px"; - divFromNOSQL.appendChild(resetOpenAPIBtnFromNOSQL); + resetOpenAPIBtnFromNOSQL.style.marginTop = "8px"; + resetOpenAPIBtnFromNOSQL.style.marginRight = "4px"; + resetOpenAPIBtnFromNOSQL.style.padding = "4px"; + divFromNOSQL.appendChild(resetOpenAPIBtnFromNOSQL); - const btnFromNOSQL_ts = mxUtils.button("Insert TS", function() { - parseFromInput(sqlInputFromNOSQL.value, "ts"); - }); + const btnFromNOSQL_ts = mxUtils.button("Insert TS", function () { + parseFromInput(sqlInputFromNOSQL.value, "ts"); + }); - btnFromNOSQL_ts.style.marginTop = "8px"; - btnFromNOSQL_ts.style.padding = "4px"; - divFromNOSQL.appendChild(btnFromNOSQL_ts); + btnFromNOSQL_ts.style.marginTop = "8px"; + btnFromNOSQL_ts.style.padding = "4px"; + divFromNOSQL.appendChild(btnFromNOSQL_ts); - const btnFromNOSQL_OpenAPI = mxUtils.button("Insert OpenAPI", function() { - parseFromInput(sqlInputFromNOSQL.value, "openapi"); - }); + const btnFromNOSQL_OpenAPI = mxUtils.button("Insert OpenAPI", function () { + parseFromInput(sqlInputFromNOSQL.value, "openapi"); + }); - btnFromNOSQL_OpenAPI.style.marginTop = "8px"; - btnFromNOSQL_OpenAPI.style.padding = "4px"; - divFromNOSQL.appendChild(btnFromNOSQL_OpenAPI); + btnFromNOSQL_OpenAPI.style.marginTop = "8px"; + btnFromNOSQL_OpenAPI.style.padding = "4px"; + divFromNOSQL.appendChild(btnFromNOSQL_OpenAPI); - // Adds action - ui.actions.addAction("fromNoSql", function() { - wndFromNOSQL.setVisible(!wndFromNOSQL.isVisible()); + // Adds action + ui.actions.addAction("fromNoSql", function () { + wndFromNOSQL.setVisible(!wndFromNOSQL.isVisible()); - if (wndFromNOSQL.isVisible()) { - sqlInputFromNOSQL.focus(); - } - }); - // end import diagrams from sql text methods - - // finalize menu buttons - const theMenu = ui.menus.get("insert"); - if(theMenu) { - const oldMenu = theMenu.funct; - theMenu.funct = function(...args) { - const [menu, parent] = args; - oldMenu.apply(this, args); - ui.menus.addMenuItems(menu, ["fromNoSql"], parent); - }; + if (wndFromNOSQL.isVisible()) { + sqlInputFromNOSQL.focus(); } - if(theMenuExportAs && !window.VsCodeApi) { - const oldMenuExportAs = theMenuExportAs.funct; - - theMenuExportAs.funct = function(...args) { - const [menu, parent] = args; - oldMenuExportAs.apply(this, args); - ui.menus.addMenuItems(menu, ["tonosql"], parent); - }; - } else { - // vscode file export sql menu - const menu = ui.menus.get("file"); - if(menu && menu.enabled) { - const oldMenuExportAs = menu.funct; - menu.funct = function(...args) { - const [menu, parent] = args; - oldMenuExportAs.apply(this, args); - ui.menus.addMenuItems(menu, ["tonosql"], parent); - }; - } + }); + // end import diagrams from sql text methods + + // finalize menu buttons + const theMenu = ui.menus.get("insert"); + if (theMenu) { + const oldMenu = theMenu.funct; + theMenu.funct = function (...args) { + const [menu, parent] = args; + oldMenu.apply(this, args); + ui.menus.addMenuItems(menu, ["fromNoSql"], parent); + }; + } + if (theMenuExportAs && !window.VsCodeApi) { + const oldMenuExportAs = theMenuExportAs.funct; + + theMenuExportAs.funct = function (...args) { + const [menu, parent] = args; + oldMenuExportAs.apply(this, args); + ui.menus.addMenuItems(menu, ["tonosql"], parent); + }; + } else { + // vscode file export sql menu + const menu = ui.menus.get("file"); + if (menu && menu.enabled) { + const oldMenuExportAs = menu.funct; + menu.funct = function (...args) { + const [menu, parent] = args; + oldMenuExportAs.apply(this, args); + ui.menus.addMenuItems(menu, ["tonosql"], parent); + }; } + } }); - diff --git a/src/nosql.ts b/src/nosql.ts index a981233..093a7b5 100644 --- a/src/nosql.ts +++ b/src/nosql.ts @@ -1,12 +1,39 @@ -import { DbDefinition, DbRelationshipDefinition } from "@funktechno/little-mermaid-2-the-sql/lib/src/types"; +import { + DbDefinition, + DbRelationshipDefinition, +} from "@funktechno/little-mermaid-2-the-sql/lib/src/types"; import { TableAttribute, TableEntity } from "./types/sql-plugin-types"; -import { DatabaseModel, ForeignKeyModel, PrimaryKeyModel, PropertyModel, TableModel } from "@funktechno/sqlsimpleparser/lib/types"; +import { + DatabaseModel, + ForeignKeyModel, + PrimaryKeyModel, + PropertyModel, + TableModel, +} from "@funktechno/sqlsimpleparser/lib/types"; import { JSONSchema4, JSONSchema4TypeName } from "json-schema"; -import { convertCoreTypesToJsonSchema, convertOpenApiToCoreTypes, jsonSchemaDocumentToOpenApi } from "core-types-json-schema"; -import { JsonSchemaDocumentToOpenApiOptions, PartialOpenApiSchema } from "openapi-json-schema"; -import { CreateTableUI, GetColumnQuantifiers, RemoveNameQuantifiers, dbTypeEnds, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; +import { + convertCoreTypesToJsonSchema, + convertOpenApiToCoreTypes, + jsonSchemaDocumentToOpenApi, +} from "core-types-json-schema"; +import { + JsonSchemaDocumentToOpenApiOptions, + PartialOpenApiSchema, +} from "openapi-json-schema"; +import { + CreateTableUI, + GetColumnQuantifiers, + RemoveNameQuantifiers, + dbTypeEnds, + getDbLabel, + getMermaidDiagramDb, +} from "./utils/sharedUtils"; import { pluginVersion } from "./utils/constants"; -import { ConvertOpenApiToDatabaseModel, dbToOpenApi, GeneratePropertyModel } from "./utils/nosqlUtils"; +import { + ConvertOpenApiToDatabaseModel, + dbToOpenApi, + GeneratePropertyModel, +} from "./utils/nosqlUtils"; import { defaultResetOpenApi } from "./utils/constants-nosql"; declare const window: Customwindow; @@ -15,224 +42,245 @@ declare const window: Customwindow; * SQL Tools Plugin for importing and exporting typescript interfaces. * Version: */ -Draw.loadPlugin(function(ui) { - - //Create Base div - const divGenSQL = document.createElement("div"); - divGenSQL.style.userSelect = "none"; - divGenSQL.style.overflow = "hidden"; - divGenSQL.style.padding = "10px"; - divGenSQL.style.height = "100%"; - - const sqlInputGenSQL = document.createElement("textarea"); - sqlInputGenSQL.style.height = "200px"; - sqlInputGenSQL.style.width = "100%"; - const sqlExportDefault = "-- click a nosql type button"; - sqlInputGenSQL.value = sqlExportDefault; - mxUtils.br(divGenSQL); - divGenSQL.appendChild(sqlInputGenSQL); - const theMenuExportAs = ui.menus.get("exportAs"); - let buttonLabel = "tonosql=To NoSQL"; - // vscode extension support - // FIXME: not compatible with vscode getting unexpected syntax error - if(!(theMenuExportAs && !window.VsCodeApi)) { - buttonLabel = "tonosql=Export As NoSQL"; +Draw.loadPlugin(function (ui) { + //Create Base div + const divGenSQL = document.createElement("div"); + divGenSQL.style.userSelect = "none"; + divGenSQL.style.overflow = "hidden"; + divGenSQL.style.padding = "10px"; + divGenSQL.style.height = "100%"; + + const sqlInputGenSQL = document.createElement("textarea"); + sqlInputGenSQL.style.height = "200px"; + sqlInputGenSQL.style.width = "100%"; + const sqlExportDefault = "-- click a nosql type button"; + sqlInputGenSQL.value = sqlExportDefault; + mxUtils.br(divGenSQL); + divGenSQL.appendChild(sqlInputGenSQL); + const theMenuExportAs = ui.menus.get("exportAs"); + let buttonLabel = "tonosql=To NoSQL"; + // vscode extension support + // FIXME: not compatible with vscode getting unexpected syntax error + if (!(theMenuExportAs && !window.VsCodeApi)) { + buttonLabel = "tonosql=Export As NoSQL"; + } + // Extends Extras menu + mxResources.parse(buttonLabel); + + const wndGenSQL = new mxWindow( + mxResources.get("tonosql"), + divGenSQL, + document.body.offsetWidth - 480, + 140, + 320, + 320, + true, + true + ); + wndGenSQL.destroyOnClose = false; + wndGenSQL.setMaximizable(false); + wndGenSQL.setResizable(false); + wndGenSQL.setClosable(true); + + function generateNoSql(type: "ts" | "openapi" | undefined) { + // get diagram model + const db = getMermaidDiagramDb(ui, type); + const openapi = dbToOpenApi(db); + let result = ""; + if (type == "openapi") { + result = JSON.stringify(openapi, null, 2); + } else { + throw new Error(`type:${type} is not supported`); } - // Extends Extras menu - mxResources.parse(buttonLabel); - - const wndGenSQL = new mxWindow(mxResources.get("tonosql"), divGenSQL, document.body.offsetWidth - 480, 140, - 320, 320, true, true); - wndGenSQL.destroyOnClose = false; - wndGenSQL.setMaximizable(false); - wndGenSQL.setResizable(false); - wndGenSQL.setClosable(true); - - function generateNoSql(type: "ts" | "openapi" | undefined) { - // get diagram model - const db = getMermaidDiagramDb(ui, type); - const openapi = dbToOpenApi(db); - let result = ""; - if(type == "openapi"){ - result = JSON.stringify(openapi, null, 2); - } else { - throw new Error(`type:${type} is not supported`); - } - sqlInputGenSQL.value = result; - }; + sqlInputGenSQL.value = result; + } - mxUtils.br(divGenSQL); + mxUtils.br(divGenSQL); - const resetBtnGenSQL = mxUtils.button(mxResources.get("reset"), function() { - sqlInputGenSQL.value = sqlExportDefault; - }); + const resetBtnGenSQL = mxUtils.button(mxResources.get("reset"), function () { + sqlInputGenSQL.value = sqlExportDefault; + }); - resetBtnGenSQL.style.marginTop = "8px"; - resetBtnGenSQL.style.marginRight = "4px"; - resetBtnGenSQL.style.padding = "4px"; - divGenSQL.appendChild(resetBtnGenSQL); + resetBtnGenSQL.style.marginTop = "8px"; + resetBtnGenSQL.style.marginRight = "4px"; + resetBtnGenSQL.style.padding = "4px"; + divGenSQL.appendChild(resetBtnGenSQL); - const btnGenSQL_ts = mxUtils.button("OpenAPI", function() { - generateNoSql("openapi"); - }); + const btnGenSQL_ts = mxUtils.button("OpenAPI", function () { + generateNoSql("openapi"); + }); - btnGenSQL_ts.style.marginTop = "8px"; - btnGenSQL_ts.style.padding = "4px"; - divGenSQL.appendChild(btnGenSQL_ts); + btnGenSQL_ts.style.marginTop = "8px"; + btnGenSQL_ts.style.padding = "4px"; + divGenSQL.appendChild(btnGenSQL_ts); - // Adds action - ui.actions.addAction("tonosql", function() { - wndGenSQL.setVisible(!wndGenSQL.isVisible()); + // Adds action + ui.actions.addAction("tonosql", function () { + wndGenSQL.setVisible(!wndGenSQL.isVisible()); - if (wndGenSQL.isVisible()) { - sqlInputGenSQL.focus(); + if (wndGenSQL.isVisible()) { + sqlInputGenSQL.focus(); + } + }); + // end export sql methods + + // import diagrams from sql text methods + + //Table Info + let foreignKeyList: ForeignKeyModel[] = []; + let primaryKeyList: PrimaryKeyModel[] = []; + let tableList: TableModel[] = []; + let cells: mxCell[] = []; + let tableCell: mxCell | null = null; + let rowCell: mxCell | null = null; + let dx = 0; + let exportedTables = 0; + + //Create Base div + const divFromNOSQL = document.createElement("div"); + divFromNOSQL.style.userSelect = "none"; + divFromNOSQL.style.overflow = "hidden"; + divFromNOSQL.style.padding = "10px"; + divFromNOSQL.style.height = "100%"; + + const sqlInputFromNOSQL = document.createElement("textarea"); + sqlInputFromNOSQL.style.height = "200px"; + sqlInputFromNOSQL.style.width = "100%"; + sqlInputFromNOSQL.value = defaultResetOpenApi; + mxUtils.br(divFromNOSQL); + divFromNOSQL.appendChild(sqlInputFromNOSQL); + + // const graph = ui.editor.graph; + + // Extends Extras menu + mxResources.parse("fromNoSql=From NoSQL"); + + const wndFromNOSQL = new mxWindow( + mxResources.get("fromNoSql"), + divFromNOSQL, + document.body.offsetWidth - 480, + 140, + 320, + 320, + true, + true + ); + wndFromNOSQL.destroyOnClose = false; + wndFromNOSQL.setMaximizable(false); + wndFromNOSQL.setResizable(false); + wndFromNOSQL.setClosable(true); + + function parseFromInput(text: string, type?: "ts" | "openapi" | undefined) { + // reset values + cells = []; + tableCell = null; + rowCell = null; + try { + let openApi: PartialOpenApiSchema | null = null; + const openApiOptions: JsonSchemaDocumentToOpenApiOptions = { + title: "nosql default options", + version: pluginVersion, + }; + if (type == "openapi") { + // should already be a json, but going to serialize to openapi for validation + const data = JSON.parse(text); + const { data: doc } = convertOpenApiToCoreTypes(data); + const { data: jsonSchema } = convertCoreTypesToJsonSchema(doc); + // was losing format option, just going to check if exception thrown here + jsonSchemaDocumentToOpenApi(jsonSchema, openApiOptions); + openApi = data; + } else { + throw new Error(`type:${type} is not supported`); + } + const schemas = openApi?.components?.schemas; + if (schemas) { + const models = ConvertOpenApiToDatabaseModel(schemas); + + foreignKeyList = models.ForeignKeyList; + primaryKeyList = models.PrimaryKeyList; + tableList = models.TableList; + exportedTables = tableList.length; + const createTableResult = CreateTableUI( + ui, + wndFromNOSQL, + tableList, + cells, + rowCell, + tableCell, + foreignKeyList, + dx, + type + ); + if (createTableResult) { + cells = createTableResult.cells; + dx = createTableResult.dx; + tableCell = createTableResult.tableCell; + rowCell = createTableResult.rowCell; } - }); - // end export sql methods - - // import diagrams from sql text methods - - - //Table Info - let foreignKeyList: ForeignKeyModel[] = []; - let primaryKeyList: PrimaryKeyModel[] = []; - let tableList: TableModel[] = []; - let cells: mxCell[] = []; - let tableCell: mxCell|null = null; - let rowCell: mxCell|null = null; - let dx = 0; - let exportedTables = 0; - + } + } catch (error) { + console.log(`unable to serialize the response:${type}`); + console.log(error); + } + } - //Create Base div - const divFromNOSQL = document.createElement("div"); - divFromNOSQL.style.userSelect = "none"; - divFromNOSQL.style.overflow = "hidden"; - divFromNOSQL.style.padding = "10px"; - divFromNOSQL.style.height = "100%"; + mxUtils.br(divFromNOSQL); - const sqlInputFromNOSQL = document.createElement("textarea"); - sqlInputFromNOSQL.style.height = "200px"; - sqlInputFromNOSQL.style.width = "100%"; + const resetOpenAPIBtnFromNOSQL = mxUtils.button("Reset OpenAPI", function () { sqlInputFromNOSQL.value = defaultResetOpenApi; - mxUtils.br(divFromNOSQL); - divFromNOSQL.appendChild(sqlInputFromNOSQL); - - // const graph = ui.editor.graph; - - // Extends Extras menu - mxResources.parse("fromNoSql=From NoSQL"); - - const wndFromNOSQL = new mxWindow(mxResources.get("fromNoSql"), divFromNOSQL, document.body.offsetWidth - 480, 140, - 320, 320, true, true); - wndFromNOSQL.destroyOnClose = false; - wndFromNOSQL.setMaximizable(false); - wndFromNOSQL.setResizable(false); - wndFromNOSQL.setClosable(true); - - function parseFromInput(text: string, type?: "ts" | "openapi" | undefined) { - // reset values - cells = []; - tableCell = null; - rowCell = null; - try { - let openApi: PartialOpenApiSchema|null = null; - const openApiOptions: JsonSchemaDocumentToOpenApiOptions = { - title: "nosql default options", - version: pluginVersion - }; - if(type == "openapi"){ - // should already be a json, but going to serialize to openapi for validation - const data = JSON.parse(text); - const { data: doc } = convertOpenApiToCoreTypes( data ); - const { data: jsonSchema } = convertCoreTypesToJsonSchema( doc ); - // was losing format option, just going to check if exception thrown here - jsonSchemaDocumentToOpenApi( jsonSchema, openApiOptions ); - openApi = data; - } else { - throw new Error(`type:${type} is not supported`); - } - const schemas = openApi?.components?.schemas; - if(schemas){ - const models = ConvertOpenApiToDatabaseModel(schemas); - - foreignKeyList = models.ForeignKeyList; - primaryKeyList = models.PrimaryKeyList; - tableList = models.TableList; - exportedTables = tableList.length; - const createTableResult = CreateTableUI(ui, wndFromNOSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type); - if(createTableResult){ - cells = createTableResult.cells; - dx = createTableResult.dx; - tableCell = createTableResult.tableCell; - rowCell = createTableResult.rowCell; - } - } - - } catch (error) { - console.log(`unable to serialize the response:${type}`); - console.log(error); - } - }; - - mxUtils.br(divFromNOSQL); + }); - const resetOpenAPIBtnFromNOSQL = mxUtils.button("Reset OpenAPI", function() { - sqlInputFromNOSQL.value = defaultResetOpenApi; - }); + resetOpenAPIBtnFromNOSQL.style.marginTop = "8px"; + resetOpenAPIBtnFromNOSQL.style.marginRight = "4px"; + resetOpenAPIBtnFromNOSQL.style.padding = "4px"; + divFromNOSQL.appendChild(resetOpenAPIBtnFromNOSQL); - resetOpenAPIBtnFromNOSQL.style.marginTop = "8px"; - resetOpenAPIBtnFromNOSQL.style.marginRight = "4px"; - resetOpenAPIBtnFromNOSQL.style.padding = "4px"; - divFromNOSQL.appendChild(resetOpenAPIBtnFromNOSQL); + const btnFromNOSQL_OpenAPI = mxUtils.button("Insert OpenAPI", function () { + parseFromInput(sqlInputFromNOSQL.value, "openapi"); + }); - const btnFromNOSQL_OpenAPI = mxUtils.button("Insert OpenAPI", function() { - parseFromInput(sqlInputFromNOSQL.value, "openapi"); - }); + btnFromNOSQL_OpenAPI.style.marginTop = "8px"; + btnFromNOSQL_OpenAPI.style.padding = "4px"; + divFromNOSQL.appendChild(btnFromNOSQL_OpenAPI); - btnFromNOSQL_OpenAPI.style.marginTop = "8px"; - btnFromNOSQL_OpenAPI.style.padding = "4px"; - divFromNOSQL.appendChild(btnFromNOSQL_OpenAPI); + // Adds action + ui.actions.addAction("fromNoSql", function () { + wndFromNOSQL.setVisible(!wndFromNOSQL.isVisible()); - // Adds action - ui.actions.addAction("fromNoSql", function() { - wndFromNOSQL.setVisible(!wndFromNOSQL.isVisible()); - - if (wndFromNOSQL.isVisible()) { - sqlInputFromNOSQL.focus(); - } - }); - // end import diagrams from sql text methods - - // finalize menu buttons - const theMenu = ui.menus.get("insert"); - if(theMenu) { - const oldMenu = theMenu.funct; - theMenu.funct = function(...args) { - const [menu, parent] = args; - oldMenu.apply(this, args); - ui.menus.addMenuItems(menu, ["fromNoSql"], parent); - }; + if (wndFromNOSQL.isVisible()) { + sqlInputFromNOSQL.focus(); } - if(theMenuExportAs && !window.VsCodeApi) { - const oldMenuExportAs = theMenuExportAs.funct; - - theMenuExportAs.funct = function(...args) { - const [menu, parent] = args; - oldMenuExportAs.apply(this, args); - ui.menus.addMenuItems(menu, ["tonosql"], parent); - }; - } else { - // vscode file export sql menu - const menu = ui.menus.get("file"); - if(menu && menu.enabled) { - const oldMenuExportAs = menu.funct; - menu.funct = function(...args) { - const [menu, parent] = args; - oldMenuExportAs.apply(this, args); - ui.menus.addMenuItems(menu, ["tonosql"], parent); - }; - } + }); + // end import diagrams from sql text methods + + // finalize menu buttons + const theMenu = ui.menus.get("insert"); + if (theMenu) { + const oldMenu = theMenu.funct; + theMenu.funct = function (...args) { + const [menu, parent] = args; + oldMenu.apply(this, args); + ui.menus.addMenuItems(menu, ["fromNoSql"], parent); + }; + } + if (theMenuExportAs && !window.VsCodeApi) { + const oldMenuExportAs = theMenuExportAs.funct; + + theMenuExportAs.funct = function (...args) { + const [menu, parent] = args; + oldMenuExportAs.apply(this, args); + ui.menus.addMenuItems(menu, ["tonosql"], parent); + }; + } else { + // vscode file export sql menu + const menu = ui.menus.get("file"); + if (menu && menu.enabled) { + const oldMenuExportAs = menu.funct; + menu.funct = function (...args) { + const [menu, parent] = args; + oldMenuExportAs.apply(this, args); + ui.menus.addMenuItems(menu, ["tonosql"], parent); + }; } + } }); - diff --git a/src/sql.ts b/src/sql.ts index da0b1d4..85464d6 100644 --- a/src/sql.ts +++ b/src/sql.ts @@ -1,9 +1,23 @@ import { DbParser } from "@funktechno/little-mermaid-2-the-sql/lib/src/generate-sql-ddl"; -import { DbDefinition, DbRelationshipDefinition } from "@funktechno/little-mermaid-2-the-sql/lib/src/types"; +import { + DbDefinition, + DbRelationshipDefinition, +} from "@funktechno/little-mermaid-2-the-sql/lib/src/types"; import { TableAttribute, TableEntity } from "./types/sql-plugin-types"; import { SqlSimpleParser } from "@funktechno/sqlsimpleparser"; -import { ForeignKeyModel, PrimaryKeyModel, PropertyModel, TableModel } from "@funktechno/sqlsimpleparser/lib/types"; -import { CreateTableUI, GetColumnQuantifiers, RemoveNameQuantifiers, getDbLabel, getMermaidDiagramDb } from "./utils/sharedUtils"; +import { + ForeignKeyModel, + PrimaryKeyModel, + PropertyModel, + TableModel, +} from "@funktechno/sqlsimpleparser/lib/types"; +import { + CreateTableUI, + GetColumnQuantifiers, + RemoveNameQuantifiers, + getDbLabel, + getMermaidDiagramDb, +} from "./utils/sharedUtils"; import { pluginVersion } from "./utils/constants"; declare const window: Customwindow; @@ -11,264 +25,287 @@ declare const window: Customwindow; * SQL Tools Plugin for importing diagrams from SQL DDL and exporting to SQL. * Version: */ -Draw.loadPlugin(function(ui) { - - // export sql methods - - //Create Base div - const divGenSQL = document.createElement("div"); - divGenSQL.style.userSelect = "none"; - divGenSQL.style.overflow = "hidden"; - divGenSQL.style.padding = "10px"; - divGenSQL.style.height = "100%"; - - const sqlInputGenSQL = document.createElement("textarea"); - sqlInputGenSQL.style.height = "200px"; - sqlInputGenSQL.style.width = "100%"; - const sqlExportDefault = "-- click a database type button"; +Draw.loadPlugin(function (ui) { + // export sql methods + + //Create Base div + const divGenSQL = document.createElement("div"); + divGenSQL.style.userSelect = "none"; + divGenSQL.style.overflow = "hidden"; + divGenSQL.style.padding = "10px"; + divGenSQL.style.height = "100%"; + + const sqlInputGenSQL = document.createElement("textarea"); + sqlInputGenSQL.style.height = "200px"; + sqlInputGenSQL.style.width = "100%"; + const sqlExportDefault = "-- click a database type button"; + sqlInputGenSQL.value = sqlExportDefault; + mxUtils.br(divGenSQL); + divGenSQL.appendChild(sqlInputGenSQL); + const theMenuExportAs = ui.menus.get("exportAs"); + let buttonLabel = "tosql=To SQL"; + // vscode extension support + if (!(theMenuExportAs && !window.VsCodeApi)) { + buttonLabel = "tosql=Export As SQL"; + } + // Extends Extras menu + mxResources.parse(buttonLabel); + + const wndGenSQL = new mxWindow( + mxResources.get("tosql"), + divGenSQL, + document.body.offsetWidth - 480, + 140, + 320, + 320, + true, + true + ); + wndGenSQL.destroyOnClose = false; + wndGenSQL.setMaximizable(false); + wndGenSQL.setResizable(false); + wndGenSQL.setClosable(true); + + function generateSql( + type: "mysql" | "sqlserver" | "sqlite" | "postgres" | undefined + ) { + // get diagram model + const db = getMermaidDiagramDb(ui, type); + // load parser + const parser = new DbParser(type as string, db as unknown as DbDefinition); + // generate sql + let sql = parser.getSQLDataDefinition(); + sql = + `/*\n\tGenerated in drawio\n\tDatabase: ${type}\n\tPlugin: sql\n\tVersion: ${pluginVersion}\n*/\n\n` + + sql; + sql = sql.trim(); + // update sql value in text area + sqlInputGenSQL.value = sql; + // TODO: use selection as well? + // const modelSelected = ui.editor.graph.getSelectionModel(); + } + + mxUtils.br(divGenSQL); + + const resetBtnGenSQL = mxUtils.button(mxResources.get("reset"), function () { sqlInputGenSQL.value = sqlExportDefault; - mxUtils.br(divGenSQL); - divGenSQL.appendChild(sqlInputGenSQL); - const theMenuExportAs = ui.menus.get("exportAs"); - let buttonLabel = "tosql=To SQL"; - // vscode extension support - if(!(theMenuExportAs && !window.VsCodeApi)) { - buttonLabel = "tosql=Export As SQL"; - } - // Extends Extras menu - mxResources.parse(buttonLabel); - - const wndGenSQL = new mxWindow(mxResources.get("tosql"), divGenSQL, document.body.offsetWidth - 480, 140, - 320, 320, true, true); - wndGenSQL.destroyOnClose = false; - wndGenSQL.setMaximizable(false); - wndGenSQL.setResizable(false); - wndGenSQL.setClosable(true); - - function generateSql(type: "mysql" | "sqlserver" | "sqlite" | "postgres" | undefined) { - - // get diagram model - const db = getMermaidDiagramDb(ui, type); - // load parser - const parser = new DbParser(type as string, db as unknown as DbDefinition); - // generate sql - let sql = parser.getSQLDataDefinition(); - sql = `/*\n\tGenerated in drawio\n\tDatabase: ${type}\n\tPlugin: sql\n\tVersion: ${pluginVersion}\n*/\n\n` + sql; - sql = sql.trim(); - // update sql value in text area - sqlInputGenSQL.value = sql; - // TODO: use selection as well? - // const modelSelected = ui.editor.graph.getSelectionModel(); - }; + }); - mxUtils.br(divGenSQL); + resetBtnGenSQL.style.marginTop = "8px"; + resetBtnGenSQL.style.marginRight = "4px"; + resetBtnGenSQL.style.padding = "4px"; + divGenSQL.appendChild(resetBtnGenSQL); - const resetBtnGenSQL = mxUtils.button(mxResources.get("reset"), function() { - sqlInputGenSQL.value = sqlExportDefault; - }); + const btnGenSQL_mysql = mxUtils.button("MySQL", function () { + generateSql("mysql"); + }); - resetBtnGenSQL.style.marginTop = "8px"; - resetBtnGenSQL.style.marginRight = "4px"; - resetBtnGenSQL.style.padding = "4px"; - divGenSQL.appendChild(resetBtnGenSQL); + btnGenSQL_mysql.style.marginTop = "8px"; + btnGenSQL_mysql.style.padding = "4px"; + divGenSQL.appendChild(btnGenSQL_mysql); - const btnGenSQL_mysql = mxUtils.button("MySQL", function() { - generateSql("mysql"); - }); + const btnGenSQL_sqlserver = mxUtils.button("SQL Server", function () { + generateSql("sqlserver"); + }); - btnGenSQL_mysql.style.marginTop = "8px"; - btnGenSQL_mysql.style.padding = "4px"; - divGenSQL.appendChild(btnGenSQL_mysql); + btnGenSQL_sqlserver.style.marginTop = "8px"; + btnGenSQL_sqlserver.style.padding = "4px"; + divGenSQL.appendChild(btnGenSQL_sqlserver); - const btnGenSQL_sqlserver = mxUtils.button("SQL Server", function() { - generateSql("sqlserver"); - }); + const btnGenSQL_postgres = mxUtils.button("PostgreSQL", function () { + generateSql("postgres"); + }); - btnGenSQL_sqlserver.style.marginTop = "8px"; - btnGenSQL_sqlserver.style.padding = "4px"; - divGenSQL.appendChild(btnGenSQL_sqlserver); + btnGenSQL_postgres.style.marginTop = "8px"; + btnGenSQL_postgres.style.padding = "4px"; + divGenSQL.appendChild(btnGenSQL_postgres); - const btnGenSQL_postgres = mxUtils.button("PostgreSQL", function() { - generateSql("postgres"); - }); + const btnGenSQL_sqlite = mxUtils.button("Sqlite", function () { + generateSql("sqlite"); + }); - btnGenSQL_postgres.style.marginTop = "8px"; - btnGenSQL_postgres.style.padding = "4px"; - divGenSQL.appendChild(btnGenSQL_postgres); + btnGenSQL_sqlite.style.marginTop = "8px"; + btnGenSQL_sqlite.style.padding = "4px"; + divGenSQL.appendChild(btnGenSQL_sqlite); - const btnGenSQL_sqlite = mxUtils.button("Sqlite", function() { - generateSql("sqlite"); - }); + // Adds action + ui.actions.addAction("tosql", function () { + wndGenSQL.setVisible(!wndGenSQL.isVisible()); - btnGenSQL_sqlite.style.marginTop = "8px"; - btnGenSQL_sqlite.style.padding = "4px"; - divGenSQL.appendChild(btnGenSQL_sqlite); + if (wndGenSQL.isVisible()) { + sqlInputGenSQL.focus(); + } + }); + // end export sql methods + + // import diagrams from sql text methods + + //Table Info + let foreignKeyList: ForeignKeyModel[] = []; + let primaryKeyList: PrimaryKeyModel[] = []; + let tableList: TableModel[] = []; + let cells: mxCell[] = []; + let tableCell: mxCell | null = null; + let rowCell: mxCell | null = null; + let dx = 0; + let exportedTables = 0; + + //Create Base div + const divFromSQL = document.createElement("div"); + divFromSQL.style.userSelect = "none"; + divFromSQL.style.overflow = "hidden"; + divFromSQL.style.padding = "10px"; + divFromSQL.style.height = "100%"; + + const sqlInputFromSQL = document.createElement("textarea"); + sqlInputFromSQL.style.height = "200px"; + sqlInputFromSQL.style.width = "100%"; + const defaultReset = `/*\n\tDrawio default value\n\tPlugin: sql\n\tVersion: ${pluginVersion}\n*/\n\nCREATE TABLE Persons\n(\n PersonID int NOT NULL,\n LastName constchar(255),\n " + + "FirstName constchar(255),\n Address constchar(255),\n City constchar(255),\n Primary Key(PersonID)\n);\n\n" + + "CREATE TABLE Orders\n(\n OrderID int NOT NULL PRIMARY KEY,\n PersonID int NOT NULL,\n FOREIGN KEY ([PersonID]) REFERENCES [Persons]([PersonID])" + + "\n);`; - // Adds action - ui.actions.addAction("tosql", function() { - wndGenSQL.setVisible(!wndGenSQL.isVisible()); + sqlInputFromSQL.value = defaultReset; + mxUtils.br(divFromSQL); + divFromSQL.appendChild(sqlInputFromSQL); + + // Extends Extras menu + mxResources.parse("fromSql=From SQL"); + + const wndFromSQL = new mxWindow( + mxResources.get("fromSql"), + divFromSQL, + document.body.offsetWidth - 480, + 140, + 320, + 320, + true, + true + ); + wndFromSQL.destroyOnClose = false; + wndFromSQL.setMaximizable(false); + wndFromSQL.setResizable(false); + wndFromSQL.setClosable(true); + + function parseSql( + text: string, + type?: "mysql" | "sqlite" | "postgres" | "sqlserver" | undefined + ) { + // reset values + cells = []; + tableCell = null; + rowCell = null; + // load parser + const parser = new SqlSimpleParser(type); + + const models = parser.feed(text).WithoutEnds().WithEnds().ToModel(); + + foreignKeyList = models.ForeignKeyList; + primaryKeyList = models.PrimaryKeyList; + tableList = models.TableList; + exportedTables = tableList.length; + + //Create Table in UI + const createTableResult = CreateTableUI( + ui, + wndFromSQL, + tableList, + cells, + rowCell, + tableCell, + foreignKeyList, + dx, + type + ); + if (createTableResult) { + cells = createTableResult.cells; + dx = createTableResult.dx; + tableCell = createTableResult.tableCell; + rowCell = createTableResult.rowCell; + } + } - if (wndGenSQL.isVisible()) { - sqlInputGenSQL.focus(); - } - }); - // end export sql methods + mxUtils.br(divFromSQL); - // import diagrams from sql text methods + const resetBtnFromSQL = mxUtils.button(mxResources.get("reset"), function () { + sqlInputFromSQL.value = defaultReset; + }); + resetBtnFromSQL.style.marginTop = "8px"; + resetBtnFromSQL.style.marginRight = "4px"; + resetBtnFromSQL.style.padding = "4px"; + divFromSQL.appendChild(resetBtnFromSQL); - //Table Info - let foreignKeyList: ForeignKeyModel[] = []; - let primaryKeyList: PrimaryKeyModel[] = []; - let tableList: TableModel[] = []; - let cells: mxCell[] = []; - let tableCell: mxCell|null = null; - let rowCell: mxCell|null = null; - let dx = 0; - let exportedTables = 0; + const btnFromSQL_mysql = mxUtils.button("Insert MySQL", function () { + parseSql(sqlInputFromSQL.value, "mysql"); + }); + btnFromSQL_mysql.style.marginTop = "8px"; + btnFromSQL_mysql.style.padding = "4px"; + divFromSQL.appendChild(btnFromSQL_mysql); - //Create Base div - const divFromSQL = document.createElement("div"); - divFromSQL.style.userSelect = "none"; - divFromSQL.style.overflow = "hidden"; - divFromSQL.style.padding = "10px"; - divFromSQL.style.height = "100%"; + const btnFromSQL_sqlserver = mxUtils.button("Insert SQL Server", function () { + parseSql(sqlInputFromSQL.value, "sqlserver"); + }); - const sqlInputFromSQL = document.createElement("textarea"); - sqlInputFromSQL.style.height = "200px"; - sqlInputFromSQL.style.width = "100%"; - const defaultReset = `/*\n\tDrawio default value\n\tPlugin: sql\n\tVersion: ${pluginVersion}\n*/\n\nCREATE TABLE Persons\n(\n PersonID int NOT NULL,\n LastName constchar(255),\n " + - "FirstName constchar(255),\n Address constchar(255),\n City constchar(255),\n Primary Key(PersonID)\n);\n\n" + - "CREATE TABLE Orders\n(\n OrderID int NOT NULL PRIMARY KEY,\n PersonID int NOT NULL,\n FOREIGN KEY ([PersonID]) REFERENCES [Persons]([PersonID])" + - "\n);`; + btnFromSQL_sqlserver.style.marginTop = "8px"; + btnFromSQL_sqlserver.style.padding = "4px"; + divFromSQL.appendChild(btnFromSQL_sqlserver); - sqlInputFromSQL.value = defaultReset; - mxUtils.br(divFromSQL); - divFromSQL.appendChild(sqlInputFromSQL); - - // Extends Extras menu - mxResources.parse("fromSql=From SQL"); - - const wndFromSQL = new mxWindow(mxResources.get("fromSql"), divFromSQL, document.body.offsetWidth - 480, 140, - 320, 320, true, true); - wndFromSQL.destroyOnClose = false; - wndFromSQL.setMaximizable(false); - wndFromSQL.setResizable(false); - wndFromSQL.setClosable(true); - - function parseSql(text: string, type?: "mysql" | "sqlite" | "postgres" | "sqlserver" | undefined) { - // reset values - cells = []; - tableCell = null; - rowCell = null; - // load parser - const parser = new SqlSimpleParser(type); - - - const models = parser - .feed(text) - .WithoutEnds() - .WithEnds() - .ToModel(); - - - foreignKeyList = models.ForeignKeyList; - primaryKeyList = models.PrimaryKeyList; - tableList = models.TableList; - exportedTables = tableList.length; - - //Create Table in UI - const createTableResult = CreateTableUI(ui, wndFromSQL, tableList, cells, rowCell, tableCell, foreignKeyList, dx, type); - if(createTableResult){ - cells = createTableResult.cells; - dx = createTableResult.dx; - tableCell = createTableResult.tableCell; - rowCell = createTableResult.rowCell; - } - }; + const btnFromSQL_postgres = mxUtils.button("Insert PostgreSQL", function () { + parseSql(sqlInputFromSQL.value, "postgres"); + }); + + btnFromSQL_postgres.style.marginTop = "8px"; + btnFromSQL_postgres.style.padding = "4px"; + divFromSQL.appendChild(btnFromSQL_postgres); + + const btnFromSQL_sqlite = mxUtils.button("Insert Sqlite", function () { + parseSql(sqlInputFromSQL.value, "sqlite"); + }); - mxUtils.br(divFromSQL); - - const resetBtnFromSQL = mxUtils.button(mxResources.get("reset"), function() { - sqlInputFromSQL.value = defaultReset; - }); - - resetBtnFromSQL.style.marginTop = "8px"; - resetBtnFromSQL.style.marginRight = "4px"; - resetBtnFromSQL.style.padding = "4px"; - divFromSQL.appendChild(resetBtnFromSQL); - - const btnFromSQL_mysql = mxUtils.button("Insert MySQL", function() { - parseSql(sqlInputFromSQL.value, "mysql"); - }); - - btnFromSQL_mysql.style.marginTop = "8px"; - btnFromSQL_mysql.style.padding = "4px"; - divFromSQL.appendChild(btnFromSQL_mysql); - - const btnFromSQL_sqlserver = mxUtils.button("Insert SQL Server", function() { - parseSql(sqlInputFromSQL.value, "sqlserver"); - }); - - btnFromSQL_sqlserver.style.marginTop = "8px"; - btnFromSQL_sqlserver.style.padding = "4px"; - divFromSQL.appendChild(btnFromSQL_sqlserver); - - const btnFromSQL_postgres = mxUtils.button("Insert PostgreSQL", function() { - parseSql(sqlInputFromSQL.value, "postgres"); - }); - - btnFromSQL_postgres.style.marginTop = "8px"; - btnFromSQL_postgres.style.padding = "4px"; - divFromSQL.appendChild(btnFromSQL_postgres); - - const btnFromSQL_sqlite = mxUtils.button("Insert Sqlite", function() { - parseSql(sqlInputFromSQL.value, "sqlite"); - }); - - btnFromSQL_sqlite.style.marginTop = "8px"; - btnFromSQL_sqlite.style.padding = "4px"; - divFromSQL.appendChild(btnFromSQL_sqlite); - - // Adds action - ui.actions.addAction("fromSql", function() { - wndFromSQL.setVisible(!wndFromSQL.isVisible()); - - if (wndFromSQL.isVisible()) { - sqlInputFromSQL.focus(); - } - }); - // end import diagrams from sql text methods - - // finalize menu buttons - const theMenu = ui.menus.get("insert"); - if(theMenu) { - const oldMenu = theMenu.funct; - theMenu.funct = function(...args) { - const [menu, parent] = args; - oldMenu.apply(this, args); - ui.menus.addMenuItems(menu, ["fromSql"], parent); - }; + btnFromSQL_sqlite.style.marginTop = "8px"; + btnFromSQL_sqlite.style.padding = "4px"; + divFromSQL.appendChild(btnFromSQL_sqlite); + + // Adds action + ui.actions.addAction("fromSql", function () { + wndFromSQL.setVisible(!wndFromSQL.isVisible()); + + if (wndFromSQL.isVisible()) { + sqlInputFromSQL.focus(); } - if(theMenuExportAs && !window.VsCodeApi) { - const oldMenuExportAs = theMenuExportAs.funct; - - theMenuExportAs.funct = function(...args) { - const [menu, parent] = args; - oldMenuExportAs.apply(this, args); - ui.menus.addMenuItems(menu, ["tosql"], parent); - }; - } else { - // vscode file export sql menu - const menu = ui.menus.get("file"); - if(menu && menu.enabled) { - const oldMenuExportAs = menu.funct; - menu.funct = function(...args) { - const [menu, parent] = args; - oldMenuExportAs.apply(this, args); - ui.menus.addMenuItems(menu, ["tosql"], parent); - }; - } + }); + // end import diagrams from sql text methods + + // finalize menu buttons + const theMenu = ui.menus.get("insert"); + if (theMenu) { + const oldMenu = theMenu.funct; + theMenu.funct = function (...args) { + const [menu, parent] = args; + oldMenu.apply(this, args); + ui.menus.addMenuItems(menu, ["fromSql"], parent); + }; + } + if (theMenuExportAs && !window.VsCodeApi) { + const oldMenuExportAs = theMenuExportAs.funct; + + theMenuExportAs.funct = function (...args) { + const [menu, parent] = args; + oldMenuExportAs.apply(this, args); + ui.menus.addMenuItems(menu, ["tosql"], parent); + }; + } else { + // vscode file export sql menu + const menu = ui.menus.get("file"); + if (menu && menu.enabled) { + const oldMenuExportAs = menu.funct; + menu.funct = function (...args) { + const [menu, parent] = args; + oldMenuExportAs.apply(this, args); + ui.menus.addMenuItems(menu, ["tosql"], parent); + }; } -}); \ No newline at end of file + } +}); diff --git a/src/types/sql-plugin-types.ts b/src/types/sql-plugin-types.ts index ece170b..6ef832a 100644 --- a/src/types/sql-plugin-types.ts +++ b/src/types/sql-plugin-types.ts @@ -1,23 +1,23 @@ import { DbRelationshipDefinition } from "@funktechno/little-mermaid-2-the-sql/lib/src/types"; export interface ColumnQuantifiers { - Start: string; - End: string; + Start: string; + End: string; } export interface TableEntity { - name: string; - attributes: TableAttribute[]; + name: string; + attributes: TableAttribute[]; } export interface TableAttribute { - attributeType: string; - attributeName: string; - attributeKeyType?: string; - // "PK" | "FK" + attributeType: string; + attributeName: string; + attributeKeyType?: string; + // "PK" | "FK" } export interface DatabaseModelResult { - getEntities: () => Record; - getRelationships: () => DbRelationshipDefinition[]; -} \ No newline at end of file + getEntities: () => Record; + getRelationships: () => DbRelationshipDefinition[]; +} diff --git a/src/utils/constants-nosql.ts b/src/utils/constants-nosql.ts index 43cd000..39d45af 100644 --- a/src/utils/constants-nosql.ts +++ b/src/utils/constants-nosql.ts @@ -91,7 +91,7 @@ export const defaultResetOpenApi = ` } `; -const JSONSchemaTypes:JSONSchema4TypeName[] = [ +const JSONSchemaTypes: JSONSchema4TypeName[] = [ "string", "number", "integer", @@ -99,7 +99,7 @@ const JSONSchemaTypes:JSONSchema4TypeName[] = [ "object", "array", "null", - "any" + "any", ]; -export const validJSONSchemaTypes:string[] = JSONSchemaTypes; +export const validJSONSchemaTypes: string[] = JSONSchemaTypes; diff --git a/src/utils/nosqlUtils.ts b/src/utils/nosqlUtils.ts index e7a97a8..872dcf8 100644 --- a/src/utils/nosqlUtils.ts +++ b/src/utils/nosqlUtils.ts @@ -142,7 +142,10 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { ); } } - attributeTypeResult = attributeTypeResult.substring(firstSpaceIndex, lastSpaceIndex); + attributeTypeResult = attributeTypeResult.substring( + firstSpaceIndex, + lastSpaceIndex + ); if (attributeTypeResult.indexOf(formatKeyword) !== -1) { const formatIndex = attributeTypeResult.indexOf(formatKeyword); formatValue = attributeTypeResult @@ -188,32 +191,37 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { if (validJSONSchemaTypes.indexOf(type) != -1) { // } else { - // else { removeType = true; $ref = `#/components/schemas/${RemoveNameQuantifiers(type)}`; } } - if(["array", "object"].indexOf(type) !== -1) { - const relationships = db.getRelationships().filter(x=> x.entityA == key); + if (["array", "object"].indexOf(type) !== -1) { + const relationships = db + .getRelationships() + .filter((x) => x.entityA == key); const roleLookup = `[${key}.${propName}]`; // FIND MATCH - const rel = relationships.find(x => x.roleA.indexOf(roleLookup) != -1); - if(rel) { + const rel = relationships.find( + (x) => x.roleA.indexOf(roleLookup) != -1 + ); + if (rel) { const commentFKIndexes = getCommentIndexes(rel.entityB); - const entityBName = rel.entityB.substring(0, commentFKIndexes.beforeStart).trim(); + const entityBName = rel.entityB + .substring(0, commentFKIndexes.beforeStart) + .trim(); $ref = `#/components/schemas/${entityBName}`; } - if($ref) { + if ($ref) { // if array additionalProperties.$ref - if(type == "array") { + if (type == "array") { items = { - $ref: $ref + $ref: $ref, }; } // if object items.$ref - if(type == "object") { + if (type == "object") { additionalProperties = { - $ref: $ref + $ref: $ref, }; } } @@ -223,7 +231,7 @@ export function dbToOpenApi(db: DatabaseModelResult): PartialOpenApiSchema { title: `${schemaKey}.${propName}`, type: type, }; - if(additionalProperties) { + if (additionalProperties) { property.additionalProperties = additionalProperties; } if (items) { @@ -277,9 +285,7 @@ export function GeneratePropertyModel( if (property.items && typeof property.items === objectKeyword) { if ((property.items as JSONSchema4).format && !property.format) { property.format = (property.items as JSONSchema4).format; - // columnProperties = `${(property.items as JSONSchema4).format}[]`; } - // else if ((property.items as JSONSchema4).type) columnProperties = `${(property.items as JSONSchema4).type}[]`; } @@ -395,10 +401,6 @@ export function ConvertOpenApiToDatabaseModel( propertyKey, property ); - // if ( - // propertyModel.ColumnProperties.includes(objectKeyword) || - // propertyModel.ColumnProperties.includes(arrayKeyword) - // ) { if (refName) { const primaryKeyModel: ForeignKeyModel = { PrimaryKeyTableName: tableModel.Name, @@ -420,7 +422,6 @@ export function ConvertOpenApiToDatabaseModel( models.ForeignKeyList.push(primaryKeyModel); propertyModel.IsForeignKey = true; } - // } tableModel.Properties.push(propertyModel); } From 201aae10b088b93647287e8417b6f0f7cdef93f3 Mon Sep 17 00:00:00 2001 From: lastlink Date: Sat, 6 Jul 2024 14:06:48 -0400 Subject: [PATCH 8/8] build from formated --- dist/nosql-ts.js | 32 ++++++++++++++------------------ dist/nosql.js | 28 +++++++++++----------------- dist/sql.js | 12 ++++-------- 3 files changed, 29 insertions(+), 43 deletions(-) diff --git a/dist/nosql-ts.js b/dist/nosql-ts.js index 03ffcd4..6937f18 100644 --- a/dist/nosql-ts.js +++ b/dist/nosql-ts.js @@ -200894,7 +200894,9 @@ Draw.loadPlugin(function (ui) { if (type == "ts") { const { data: doc } = (0, core_types_json_schema_1.convertOpenApiToCoreTypes)(openapi); const { data: sourceCode } = (0, core_types_ts_1.convertCoreTypesToTypeScript)(doc); - result = `/*\n\tGenerated in drawio\n\tDatabase: ${type}\n\tPlugin: nosql\n\tVersion: ${constants_1.pluginVersion}\n*/\n\n` + result; + result = + `/*\n\tGenerated in drawio\n\tDatabase: ${type}\n\tPlugin: nosql\n\tVersion: ${constants_1.pluginVersion}\n*/\n\n` + + result; result += sourceCode; } else if (type == "openapi") { @@ -200902,7 +200904,6 @@ Draw.loadPlugin(function (ui) { } sqlInputGenSQL.value = result; } - ; mxUtils.br(divGenSQL); const resetBtnGenSQL = mxUtils.button(mxResources.get("reset"), function () { sqlInputGenSQL.value = sqlExportDefault; @@ -200971,7 +200972,7 @@ Draw.loadPlugin(function (ui) { let openApi = null; const openApiOptions = { title: "nosql default options", - version: constants_1.pluginVersion + version: constants_1.pluginVersion, }; if (type == "openapi") { // should already be a json, but going to serialize to openapi for validation @@ -201009,7 +201010,6 @@ Draw.loadPlugin(function (ui) { console.log(error); } } - ; mxUtils.br(divFromNOSQL); const resetBtnFromNOSQL = mxUtils.button(mxResources.get("Reset TS"), function () { sqlInputFromNOSQL.value = constants_nosql_1.defaultReset; @@ -201178,7 +201178,7 @@ const JSONSchemaTypes = [ "object", "array", "null", - "any" + "any", ]; exports.validJSONSchemaTypes = JSONSchemaTypes; @@ -201357,32 +201357,35 @@ function dbToOpenApi(db) { // } else { - // else { removeType = true; $ref = `#/components/schemas/${(0, sharedUtils_1.RemoveNameQuantifiers)(type)}`; } } if (["array", "object"].indexOf(type) !== -1) { - const relationships = db.getRelationships().filter(x => x.entityA == key); + const relationships = db + .getRelationships() + .filter((x) => x.entityA == key); const roleLookup = `[${key}.${propName}]`; // FIND MATCH - const rel = relationships.find(x => x.roleA.indexOf(roleLookup) != -1); + const rel = relationships.find((x) => x.roleA.indexOf(roleLookup) != -1); if (rel) { const commentFKIndexes = (0, sharedUtils_1.getCommentIndexes)(rel.entityB); - const entityBName = rel.entityB.substring(0, commentFKIndexes.beforeStart).trim(); + const entityBName = rel.entityB + .substring(0, commentFKIndexes.beforeStart) + .trim(); $ref = `#/components/schemas/${entityBName}`; } if ($ref) { // if array additionalProperties.$ref if (type == "array") { items = { - $ref: $ref + $ref: $ref, }; } // if object items.$ref if (type == "object") { additionalProperties = { - $ref: $ref + $ref: $ref, }; } } @@ -201443,9 +201446,7 @@ function GeneratePropertyModel(tableName, propertyName, property) { if (property.items && typeof property.items === constants_1.objectKeyword) { if (property.items.format && !property.format) { property.format = property.items.format; - // columnProperties = `${(property.items as JSONSchema4).format}[]`; } - // else if (property.items.type) columnProperties = `${property.items.type}[]`; } @@ -201549,10 +201550,6 @@ function ConvertOpenApiToDatabaseModel(schemas) { property.type = refName; } const propertyModel = GeneratePropertyModel(tableModel.Name, propertyKey, property); - // if ( - // propertyModel.ColumnProperties.includes(objectKeyword) || - // propertyModel.ColumnProperties.includes(arrayKeyword) - // ) { if (refName) { const primaryKeyModel = { PrimaryKeyTableName: tableModel.Name, @@ -201574,7 +201571,6 @@ function ConvertOpenApiToDatabaseModel(schemas) { models.ForeignKeyList.push(primaryKeyModel); propertyModel.IsForeignKey = true; } - // } tableModel.Properties.push(propertyModel); } } diff --git a/dist/nosql.js b/dist/nosql.js index 70f7bf4..b39b6f4 100644 --- a/dist/nosql.js +++ b/dist/nosql.js @@ -4650,7 +4650,6 @@ Draw.loadPlugin(function (ui) { } sqlInputGenSQL.value = result; } - ; mxUtils.br(divGenSQL); const resetBtnGenSQL = mxUtils.button(mxResources.get("reset"), function () { sqlInputGenSQL.value = sqlExportDefault; @@ -4713,7 +4712,7 @@ Draw.loadPlugin(function (ui) { let openApi = null; const openApiOptions = { title: "nosql default options", - version: constants_1.pluginVersion + version: constants_1.pluginVersion, }; if (type == "openapi") { // should already be a json, but going to serialize to openapi for validation @@ -4748,7 +4747,6 @@ Draw.loadPlugin(function (ui) { console.log(error); } } - ; mxUtils.br(divFromNOSQL); const resetOpenAPIBtnFromNOSQL = mxUtils.button("Reset OpenAPI", function () { sqlInputFromNOSQL.value = constants_nosql_1.defaultResetOpenApi; @@ -4904,7 +4902,7 @@ const JSONSchemaTypes = [ "object", "array", "null", - "any" + "any", ]; exports.validJSONSchemaTypes = JSONSchemaTypes; @@ -5083,32 +5081,35 @@ function dbToOpenApi(db) { // } else { - // else { removeType = true; $ref = `#/components/schemas/${(0, sharedUtils_1.RemoveNameQuantifiers)(type)}`; } } if (["array", "object"].indexOf(type) !== -1) { - const relationships = db.getRelationships().filter(x => x.entityA == key); + const relationships = db + .getRelationships() + .filter((x) => x.entityA == key); const roleLookup = `[${key}.${propName}]`; // FIND MATCH - const rel = relationships.find(x => x.roleA.indexOf(roleLookup) != -1); + const rel = relationships.find((x) => x.roleA.indexOf(roleLookup) != -1); if (rel) { const commentFKIndexes = (0, sharedUtils_1.getCommentIndexes)(rel.entityB); - const entityBName = rel.entityB.substring(0, commentFKIndexes.beforeStart).trim(); + const entityBName = rel.entityB + .substring(0, commentFKIndexes.beforeStart) + .trim(); $ref = `#/components/schemas/${entityBName}`; } if ($ref) { // if array additionalProperties.$ref if (type == "array") { items = { - $ref: $ref + $ref: $ref, }; } // if object items.$ref if (type == "object") { additionalProperties = { - $ref: $ref + $ref: $ref, }; } } @@ -5169,9 +5170,7 @@ function GeneratePropertyModel(tableName, propertyName, property) { if (property.items && typeof property.items === constants_1.objectKeyword) { if (property.items.format && !property.format) { property.format = property.items.format; - // columnProperties = `${(property.items as JSONSchema4).format}[]`; } - // else if (property.items.type) columnProperties = `${property.items.type}[]`; } @@ -5275,10 +5274,6 @@ function ConvertOpenApiToDatabaseModel(schemas) { property.type = refName; } const propertyModel = GeneratePropertyModel(tableModel.Name, propertyKey, property); - // if ( - // propertyModel.ColumnProperties.includes(objectKeyword) || - // propertyModel.ColumnProperties.includes(arrayKeyword) - // ) { if (refName) { const primaryKeyModel = { PrimaryKeyTableName: tableModel.Name, @@ -5300,7 +5295,6 @@ function ConvertOpenApiToDatabaseModel(schemas) { models.ForeignKeyList.push(primaryKeyModel); propertyModel.IsForeignKey = true; } - // } tableModel.Properties.push(propertyModel); } } diff --git a/dist/sql.js b/dist/sql.js index bcdea80..5ae96f4 100644 --- a/dist/sql.js +++ b/dist/sql.js @@ -935,14 +935,15 @@ Draw.loadPlugin(function (ui) { const parser = new generate_sql_ddl_1.DbParser(type, db); // generate sql let sql = parser.getSQLDataDefinition(); - sql = `/*\n\tGenerated in drawio\n\tDatabase: ${type}\n\tPlugin: sql\n\tVersion: ${constants_1.pluginVersion}\n*/\n\n` + sql; + sql = + `/*\n\tGenerated in drawio\n\tDatabase: ${type}\n\tPlugin: sql\n\tVersion: ${constants_1.pluginVersion}\n*/\n\n` + + sql; sql = sql.trim(); // update sql value in text area sqlInputGenSQL.value = sql; // TODO: use selection as well? // const modelSelected = ui.editor.graph.getSelectionModel(); } - ; mxUtils.br(divGenSQL); const resetBtnGenSQL = mxUtils.button(mxResources.get("reset"), function () { sqlInputGenSQL.value = sqlExportDefault; @@ -1023,11 +1024,7 @@ Draw.loadPlugin(function (ui) { rowCell = null; // load parser const parser = new sqlsimpleparser_1.SqlSimpleParser(type); - const models = parser - .feed(text) - .WithoutEnds() - .WithEnds() - .ToModel(); + const models = parser.feed(text).WithoutEnds().WithEnds().ToModel(); foreignKeyList = models.ForeignKeyList; primaryKeyList = models.PrimaryKeyList; tableList = models.TableList; @@ -1041,7 +1038,6 @@ Draw.loadPlugin(function (ui) { rowCell = createTableResult.rowCell; } } - ; mxUtils.br(divFromSQL); const resetBtnFromSQL = mxUtils.button(mxResources.get("reset"), function () { sqlInputFromSQL.value = defaultReset;