diff --git a/.changeset/big-squids-lick.md b/.changeset/big-squids-lick.md new file mode 100644 index 00000000000..293c1752ade --- /dev/null +++ b/.changeset/big-squids-lick.md @@ -0,0 +1,9 @@ +--- +'@finos/legend-extension-dsl-diagram': patch +'@finos/legend-extension-external-store-service': patch +'@finos/legend-extension-mapping-generation': patch +'@finos/legend-graph': patch +'@finos/legend-query': patch +'@finos/legend-studio': patch +'@finos/legend-studio-extension-query-builder': patch +--- diff --git a/.changeset/grumpy-houses-compete.md b/.changeset/grumpy-houses-compete.md new file mode 100644 index 00000000000..4dd8907625a --- /dev/null +++ b/.changeset/grumpy-houses-compete.md @@ -0,0 +1,5 @@ +--- +'@finos/eslint-plugin-legend-studio': minor +--- + +Support `Typscript` [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html), by using `@typescript-eslint/no-redeclare` instead of `no-redeclare` diff --git a/.changeset/light-jobs-serve.md b/.changeset/light-jobs-serve.md new file mode 100644 index 00000000000..696a284a908 --- /dev/null +++ b/.changeset/light-jobs-serve.md @@ -0,0 +1,5 @@ +--- +'@finos/legend-graph': major +--- + +**BREAKING CHANGE:** Move logic out of metamodels, such as `Class.getProperty()`, `Database.getSchema()`, etc. and expose them as helper methods. diff --git a/.changeset/mighty-kings-fly.md b/.changeset/mighty-kings-fly.md new file mode 100644 index 00000000000..7e400f50c5a --- /dev/null +++ b/.changeset/mighty-kings-fly.md @@ -0,0 +1,13 @@ +--- +'@finos/eslint-plugin-legend-studio': patch +'@finos/legend-dev-utils': patch +'@finos/legend-extension-dsl-diagram': patch +'@finos/legend-extension-dsl-text': patch +'@finos/legend-extension-external-store-service': patch +'@finos/legend-extension-mapping-generation': patch +'@finos/legend-graph': patch +'@finos/legend-query': patch +'@finos/legend-shared': patch +'@finos/legend-studio': patch +'@finos/legend-studio-extension-query-builder': patch +--- diff --git a/.changeset/nine-experts-tease.md b/.changeset/nine-experts-tease.md new file mode 100644 index 00000000000..078e788258b --- /dev/null +++ b/.changeset/nine-experts-tease.md @@ -0,0 +1,11 @@ +--- +'@finos/eslint-plugin-legend-studio': patch +'@finos/legend-extension-dsl-diagram': patch +'@finos/legend-extension-dsl-text': patch +'@finos/legend-extension-external-store-service': patch +'@finos/legend-extension-mapping-generation': patch +'@finos/legend-graph': patch +'@finos/legend-query': patch +'@finos/legend-studio': patch +'@finos/legend-studio-extension-query-builder': patch +--- diff --git a/.changeset/old-buses-sell.md b/.changeset/old-buses-sell.md new file mode 100644 index 00000000000..3d20526fe15 --- /dev/null +++ b/.changeset/old-buses-sell.md @@ -0,0 +1,5 @@ +--- +'@finos/legend-graph': major +--- + +**BREAKING CHANGE:** Remove `Stubable` interface and all stub logic in metamodels, such as `createStub()`, `isStub()`, these methods are now cleaned up and organized in `model creater helpers` which will be exported as utilities from this package. diff --git a/.changeset/perfect-ways-double.md b/.changeset/perfect-ways-double.md new file mode 100644 index 00000000000..293c1752ade --- /dev/null +++ b/.changeset/perfect-ways-double.md @@ -0,0 +1,9 @@ +--- +'@finos/legend-extension-dsl-diagram': patch +'@finos/legend-extension-external-store-service': patch +'@finos/legend-extension-mapping-generation': patch +'@finos/legend-graph': patch +'@finos/legend-query': patch +'@finos/legend-studio': patch +'@finos/legend-studio-extension-query-builder': patch +--- diff --git a/.changeset/pretty-monkeys-matter.md b/.changeset/pretty-monkeys-matter.md new file mode 100644 index 00000000000..fa079cb715f --- /dev/null +++ b/.changeset/pretty-monkeys-matter.md @@ -0,0 +1,8 @@ +--- +'@finos/legend-extension-dsl-diagram': patch +'@finos/legend-extension-mapping-generation': patch +'@finos/legend-graph': patch +'@finos/legend-query': patch +'@finos/legend-studio': patch +'@finos/legend-studio-extension-query-builder': patch +--- diff --git a/.changeset/purple-crabs-sell.md b/.changeset/purple-crabs-sell.md new file mode 100644 index 00000000000..078e788258b --- /dev/null +++ b/.changeset/purple-crabs-sell.md @@ -0,0 +1,11 @@ +--- +'@finos/eslint-plugin-legend-studio': patch +'@finos/legend-extension-dsl-diagram': patch +'@finos/legend-extension-dsl-text': patch +'@finos/legend-extension-external-store-service': patch +'@finos/legend-extension-mapping-generation': patch +'@finos/legend-graph': patch +'@finos/legend-query': patch +'@finos/legend-studio': patch +'@finos/legend-studio-extension-query-builder': patch +--- diff --git a/.changeset/shaggy-goats-leave.md b/.changeset/shaggy-goats-leave.md new file mode 100644 index 00000000000..078e788258b --- /dev/null +++ b/.changeset/shaggy-goats-leave.md @@ -0,0 +1,11 @@ +--- +'@finos/eslint-plugin-legend-studio': patch +'@finos/legend-extension-dsl-diagram': patch +'@finos/legend-extension-dsl-text': patch +'@finos/legend-extension-external-store-service': patch +'@finos/legend-extension-mapping-generation': patch +'@finos/legend-graph': patch +'@finos/legend-query': patch +'@finos/legend-studio': patch +'@finos/legend-studio-extension-query-builder': patch +--- diff --git a/.changeset/tiny-shrimps-learn.md b/.changeset/tiny-shrimps-learn.md new file mode 100644 index 00000000000..1941b926c12 --- /dev/null +++ b/.changeset/tiny-shrimps-learn.md @@ -0,0 +1,5 @@ +--- +'@finos/legend-graph': major +--- + +Rename `fullPath` to `path` in `Package`. Where this change really makes a difference is for the root package: previously, `path` was the `name` of the root package element, from now on, `path` will be `empty string`, this makes the handling of root package when constructing element path more consistent. diff --git a/package.json b/package.json index 4d49a1412e4..70b36125167 100644 --- a/package.json +++ b/package.json @@ -80,16 +80,16 @@ "glob-parent": "^6.0.1" }, "devDependencies": { - "@actions/core": "1.8.0", - "@actions/github": "5.0.1", + "@actions/core": "1.8.1", + "@actions/github": "5.0.2", "@babel/core": "7.17.10", "@changesets/cli": "2.22.0", "@finos/babel-preset-legend-studio": "workspace:*", "@finos/eslint-plugin-legend-studio": "workspace:*", "@finos/legend-dev-utils": "workspace:*", "@finos/stylelint-config-legend-studio": "workspace:*", - "@types/jest": "27.5.0", - "@types/node": "17.0.31", + "@types/jest": "27.5.1", + "@types/node": "17.0.32", "chalk": "5.0.1", "cross-env": "7.0.3", "envinfo": "7.8.1", @@ -108,7 +108,7 @@ "sort-package-json": "1.57.0", "stylelint": "14.8.2", "typescript": "4.6.4", - "yargs": "17.4.1" + "yargs": "17.5.0" }, "packageManager": "yarn@3.2.0", "engines": { diff --git a/packages/eslint-plugin/src/configs/recommended.js b/packages/eslint-plugin/src/configs/recommended.js index 004ba00258a..eea1d89f202 100644 --- a/packages/eslint-plugin/src/configs/recommended.js +++ b/packages/eslint-plugin/src/configs/recommended.js @@ -69,7 +69,7 @@ const ES_RULES = { 'no-process-exit': ERROR, 'no-proto': ERROR, 'no-prototype-builtins': ERROR, - 'no-redeclare': ERROR, + 'no-redeclare': OFF, 'no-regex-spaces': ERROR, 'no-return-assign': ERROR, /** @@ -137,6 +137,7 @@ const TYPESCRIPT_RULES = { ], '@typescript-eslint/func-call-spacing': ERROR, '@typescript-eslint/no-inferrable-types': [WARN, { ignoreParameters: true }], + '@typescript-eslint/no-redeclare': [ERROR, { ignoreDeclarationMerge: true }], '@typescript-eslint/no-var-requires': OFF, '@typescript-eslint/no-unused-vars': [ WARN, diff --git a/packages/legend-dev-utils/package.json b/packages/legend-dev-utils/package.json index 9c3f0f12fb2..9fc88dddf00 100644 --- a/packages/legend-dev-utils/package.json +++ b/packages/legend-dev-utils/package.json @@ -60,7 +60,7 @@ "@changesets/write": "0.1.8", "@juggle/resize-observer": "3.3.1", "@manypkg/get-packages": "1.1.3", - "@pmmmwh/react-refresh-webpack-plugin": "0.5.5", + "@pmmmwh/react-refresh-webpack-plugin": "0.5.6", "autoprefixer": "10.4.7", "babel-jest": "28.1.0", "babel-loader": "8.2.5", diff --git a/packages/legend-extension-dsl-diagram/src/DiagramRenderer.ts b/packages/legend-extension-dsl-diagram/src/DiagramRenderer.ts index 80dc3a18c6b..d7cdcb9d99b 100644 --- a/packages/legend-extension-dsl-diagram/src/DiagramRenderer.ts +++ b/packages/legend-extension-dsl-diagram/src/DiagramRenderer.ts @@ -36,6 +36,10 @@ import { GenericType, Property, Multiplicity, + getAllSuperclasses, + getAllOwnClassProperties, + generateMultiplicityString, + getRawGenericType, } from '@finos/legend-graph'; import { action, makeObservable, observable } from 'mobx'; import type { Diagram } from './models/metamodels/pure/packageableElements/diagram/DSLDiagram_Diagram'; @@ -595,11 +599,11 @@ export class DiagramRenderer { // Do not allow creating self-inheritance startClassView.class.value !== targetClassView.class.value && // Avoid creating inhertance that already existed - !startClassView.class.value.allSuperclasses.includes( + !getAllSuperclasses(startClassView.class.value).includes( targetClassView.class.value, ) && // Avoid loop (might be expensive) - !targetClassView.class.value.allSuperclasses.includes( + !getAllSuperclasses(targetClassView.class.value).includes( startClassView.class.value, ) ) { @@ -924,7 +928,7 @@ export class DiagramRenderer { ); } // Add property view - addedClass.getAllOwnedProperties().forEach((property) => { + getAllOwnClassProperties(addedClass).forEach((property) => { if (property.genericType.value.rawType === _class) { diagram_addPropertyView( this.diagram, @@ -938,7 +942,7 @@ export class DiagramRenderer { ); } }); - _class.getAllOwnedProperties().forEach((property) => { + getAllOwnClassProperties(_class).forEach((property) => { if (property.genericType.value.rawType === addedClass) { diagram_addPropertyView( this.diagram, @@ -1394,14 +1398,14 @@ export class DiagramRenderer { this.ctx.font = `${(this.fontSize - 1) * (measureOnly ? 1 : this.zoom)}px ${ this.fontFamily }`; + const multiplicityString = generateMultiplicityString( + property.multiplicity.lowerBound, + property.multiplicity.upperBound, + ); if (!measureOnly) { - this.ctx.fillText( - `[${property.multiplicity.str}]`, - propX + txtMeasure, - propY, - ); + this.ctx.fillText(`[${multiplicityString}]`, propX + txtMeasure, propY); } - txtMeasure += this.ctx.measureText(`[${property.multiplicity.str}]`).width; + txtMeasure += this.ctx.measureText(`[${multiplicityString}]`).width; return txtMeasure; } @@ -1451,7 +1455,7 @@ export class DiagramRenderer { // Calculate box for properties if (!classView.hideProperties) { - classView.class.value.getAllOwnedProperties().forEach((property) => { + getAllOwnClassProperties(classView.class.value).forEach((property) => { if (!this.hasPropertyView(classView, property)) { const propertyTextMeasure = this.drawClassViewProperty( classView, @@ -1632,7 +1636,7 @@ export class DiagramRenderer { ); this.ctx.stroke(); - for (const property of classView.class.value.getAllOwnedProperties()) { + for (const property of getAllOwnClassProperties(classView.class.value)) { if (!this.hasPropertyView(classView, property)) { this.ctx.fillStyle = property instanceof DerivedProperty @@ -1671,8 +1675,12 @@ export class DiagramRenderer { ): PositionedRectangle { this.ctx.font = `${this.fontSize}px ${this.fontFamily}`; const propertyName = getPropertyDisplayName(property); + const multiplictyString = generateMultiplicityString( + property.multiplicity.lowerBound, + property.multiplicity.upperBound, + ); const textSize = this.ctx.measureText(propertyName).width; - const mulSize = this.ctx.measureText(property.multiplicity.str).width; + const mulSize = this.ctx.measureText(multiplictyString).width; this.ctx.font = `${this.fontSize * this.zoom}px ${this.fontFamily}`; const posX = textPositionX(textSize); const posY = textPositionY(textSize); @@ -1689,7 +1697,7 @@ export class DiagramRenderer { ); if (!measureOnly) { this.ctx.fillText( - property.multiplicity.str, + multiplictyString, multiplicityPosition.x, multiplicityPosition.y, ); @@ -2341,7 +2349,7 @@ export class DiagramRenderer { else if ('ArrowDown' === e.key) { const views = uniqBy( this.selectedClasses.flatMap((x) => - x.class.value.subclasses.flatMap( + x.class.value._subclasses.flatMap( (c) => new ClassView( this.diagram, @@ -3115,7 +3123,7 @@ export class DiagramRenderer { cursorY += this.classViewSpaceY; // Check hover class property - for (const property of _class.getAllOwnedProperties()) { + for (const property of getAllOwnClassProperties(_class)) { if (!this.hasPropertyView(classView, property)) { this.ctx.font = `${(this.fontSize - 1) * this.zoom}px ${ this.fontFamily @@ -3204,7 +3212,7 @@ export class DiagramRenderer { diagram, uuid(), PackageableElementExplicitReference.create( - generation.value.getRawType(Class), + getRawGenericType(generation.value, Class), ), ), ), diff --git a/packages/legend-extension-dsl-diagram/src/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.ts b/packages/legend-extension-dsl-diagram/src/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.ts index e5b84557173..9025cd31697 100644 --- a/packages/legend-extension-dsl-diagram/src/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.ts +++ b/packages/legend-extension-dsl-diagram/src/models/protocols/pure/v1/transformation/pureGraph/V1_DSLDiagram_GraphBuilderHelper.ts @@ -110,7 +110,7 @@ export const V1_buildPropertyView = ( getClassView(diagram, guaranteeNonNullable(propertyView.targetView)), `Property view 'targetView' field is missing`, ); - const property = context.resolveOwnedProperty(propertyView.property); + const property = context.resolveOwnProperty(propertyView.property); const view = new PropertyView( diagram, property, diff --git a/packages/legend-extension-dsl-text/src/models/protocols/pure/DSLText_PureProtocolProcessorPlugin.ts b/packages/legend-extension-dsl-text/src/models/protocols/pure/DSLText_PureProtocolProcessorPlugin.ts index 206fec89017..82df9564f9d 100644 --- a/packages/legend-extension-dsl-text/src/models/protocols/pure/DSLText_PureProtocolProcessorPlugin.ts +++ b/packages/legend-extension-dsl-text/src/models/protocols/pure/DSLText_PureProtocolProcessorPlugin.ts @@ -140,7 +140,7 @@ export class DSLText_PureProtocolProcessorPlugin extends PureProtocolProcessorPl const protocol = new V1_Text(); V1_initPackageableElement(protocol, metamodel); protocol.name = metamodel.name; - protocol.package = metamodel.package?.fullPath ?? ''; + protocol.package = metamodel.package?.path ?? ''; protocol.content = metamodel.content; protocol.type = metamodel.type; return protocol; diff --git a/packages/legend-extension-external-store-service/src/models/metamodels/pure/model/packageableElements/store/serviceStore/mapping/ESService_RootServiceInstanceSetImplementation.ts b/packages/legend-extension-external-store-service/src/models/metamodels/pure/model/packageableElements/store/serviceStore/mapping/ESService_RootServiceInstanceSetImplementation.ts index 375c060df84..7642252ce77 100644 --- a/packages/legend-extension-external-store-service/src/models/metamodels/pure/model/packageableElements/store/serviceStore/mapping/ESService_RootServiceInstanceSetImplementation.ts +++ b/packages/legend-extension-external-store-service/src/models/metamodels/pure/model/packageableElements/store/serviceStore/mapping/ESService_RootServiceInstanceSetImplementation.ts @@ -17,7 +17,6 @@ import { type Hashable, hashArray } from '@finos/legend-shared'; import { InstanceSetImplementation, - type PropertyMapping, type SetImplementationVisitor, } from '@finos/legend-graph'; import { SERVICE_STORE_HASH_STRUCTURE } from '../../../../../../../ESService_ModelUtils'; @@ -45,26 +44,4 @@ export class RootServiceInstanceSetImplementation accept_SetImplementationVisitor(visitor: SetImplementationVisitor): T { return visitor.visit_SetImplementation(this); } - - getEmbeddedSetImplmentations(): InstanceSetImplementation[] { - return []; - } - - findPropertyMapping( - propertyName: string, - targetId: string | undefined, - ): PropertyMapping | undefined { - let properties = undefined; - properties = this.propertyMappings.filter( - (propertyMapping) => propertyMapping.property.value.name === propertyName, - ); - if (targetId === undefined || properties.length === 1) { - return properties[0]; - } - return properties.find( - (propertyMapping) => - propertyMapping.targetSetImplementation && - propertyMapping.targetSetImplementation.id.value === targetId, - ); - } } diff --git a/packages/legend-extension-external-store-service/src/models/protocols/pure/ESService_PureProtocolProcessorPlugin.ts b/packages/legend-extension-external-store-service/src/models/protocols/pure/ESService_PureProtocolProcessorPlugin.ts index 30e3d917908..2fa3ad87603 100644 --- a/packages/legend-extension-external-store-service/src/models/protocols/pure/ESService_PureProtocolProcessorPlugin.ts +++ b/packages/legend-extension-external-store-service/src/models/protocols/pure/ESService_PureProtocolProcessorPlugin.ts @@ -214,7 +214,7 @@ export class ESService_PureProtocolProcessorPlugin const protocol = new V1_ServiceStore(); V1_initPackageableElement(protocol, metamodel); protocol.name = metamodel.name; - protocol.package = metamodel.package?.fullPath ?? ''; + protocol.package = metamodel.package?.path ?? ''; protocol.description = metamodel.description; protocol.elements = metamodel.elements.map((element) => V1_transformServiceStoreElement(element, context), diff --git a/packages/legend-extension-mapping-generation/src/components/MappingGenerationEditor.tsx b/packages/legend-extension-mapping-generation/src/components/MappingGenerationEditor.tsx index 2e60abad96a..8149618131c 100644 --- a/packages/legend-extension-mapping-generation/src/components/MappingGenerationEditor.tsx +++ b/packages/legend-extension-mapping-generation/src/components/MappingGenerationEditor.tsx @@ -41,7 +41,11 @@ import { } from '@finos/legend-application'; import type { MappingGenerationEditorState } from '../stores/MappingGenerationEditorState'; import { flowResult, runInAction } from 'mobx'; -import { Mapping, createValidationError } from '@finos/legend-graph'; +import { + Mapping, + createValidationError, + isStubbed_PackageableElement, +} from '@finos/legend-graph'; const StringEditor = observer( (props: { @@ -295,9 +299,11 @@ const MappingSelectorEditor = observer( editorStore, } = props; // mapping - const isMappingEmpty = selectedMapping?.value.isStub - ? createValidationError(['Mapping cannot be empty']) - : undefined; + const isMappingEmpty = + selectedMapping?.value && + isStubbed_PackageableElement(selectedMapping.value) + ? createValidationError(['Mapping cannot be empty']) + : undefined; const mapping = selectedMapping?.value; const mappingOptions = editorStore.mappingOptions; const noMappingLabel = ( diff --git a/packages/legend-graph/src/DSLMapping_Exports.ts b/packages/legend-graph/src/DSLMapping_Exports.ts index 9b8de1eed0b..dbca6f0808a 100644 --- a/packages/legend-graph/src/DSLMapping_Exports.ts +++ b/packages/legend-graph/src/DSLMapping_Exports.ts @@ -64,6 +64,7 @@ export { ObjectInputData, ObjectInputType, } from './models/metamodels/pure/packageableElements/store/modelToModel/mapping/ObjectInputData'; +export { type EmbeddedSetImplementation } from './models/metamodels/pure/packageableElements/mapping/EmbeddedSetImplementation'; // protocols export { diff --git a/packages/legend-graph/src/GraphManagerState.ts b/packages/legend-graph/src/GraphManagerState.ts index 279841ce561..e3c83b092dd 100644 --- a/packages/legend-graph/src/GraphManagerState.ts +++ b/packages/legend-graph/src/GraphManagerState.ts @@ -34,6 +34,7 @@ import type { } from './graphManager/AbstractPureGraphManager'; import type { GraphPluginManager } from './GraphPluginManager'; import { getElementRootPackage } from './helpers/DomainHelper'; +import { getLeafSetImplementations } from './helpers/DSLMapping_Helper'; import { ROOT_PACKAGE_NAME } from './MetaModelConst'; import { AssociationImplementation } from './models/metamodels/pure/packageableElements/mapping/AssociationImplementation'; import type { EnumerationMapping } from './models/metamodels/pure/packageableElements/mapping/EnumerationMapping'; @@ -214,7 +215,7 @@ export class GraphManagerState { } else if (mappingElement instanceof AssociationImplementation) { mappedProperties = mappingElement.propertyMappings; } else if (mappingElement instanceof OperationSetImplementation) { - mappedProperties = mappingElement.leafSetImplementations + mappedProperties = getLeafSetImplementations(mappingElement) .filter((me): me is InstanceSetImplementation => this.isInstanceSetImplementation(me), ) @@ -242,6 +243,6 @@ export class GraphManagerState { } isElementReadOnly(element: PackageableElement): boolean { - return getElementRootPackage(element).path !== ROOT_PACKAGE_NAME.MAIN; + return getElementRootPackage(element).name !== ROOT_PACKAGE_NAME.MAIN; } } diff --git a/packages/legend-graph/src/MetaModelConst.ts b/packages/legend-graph/src/MetaModelConst.ts index 394c8cd0591..223bdb98d1e 100644 --- a/packages/legend-graph/src/MetaModelConst.ts +++ b/packages/legend-graph/src/MetaModelConst.ts @@ -17,6 +17,7 @@ export const SOURCE_INFORMATION_KEY = 'sourceInformation'; export const MULTIPLICITY_INFINITE = '*'; export const ELEMENT_PATH_DELIMITER = '::'; +export const MULTIPLICITY_RANGE_OPERATOR = '..'; export const UNIT_PATH_DELIMITER = '~'; export const LAMBDA_PIPE = '|'; export const DEFAULT_SOURCE_PARAMETER_NAME = 'src'; diff --git a/packages/legend-graph/src/MetaModelUtils.ts b/packages/legend-graph/src/MetaModelUtils.ts index ccb911a558f..1d52c305fe9 100644 --- a/packages/legend-graph/src/MetaModelUtils.ts +++ b/packages/legend-graph/src/MetaModelUtils.ts @@ -26,12 +26,14 @@ import { SOURCE_INFORMATION_KEY, ELEMENT_PATH_DELIMITER, + CORE_HASH_STRUCTURE, } from './MetaModelConst'; import { findLast, guaranteeNonNullable, hashArray, hashObject, + hashString, } from '@finos/legend-shared'; export const extractElementNameFromPath = (fullPath: string): string => @@ -80,15 +82,17 @@ export const isValidFullPath = (fullPath: string): boolean => export const isValidPath = (path: string): boolean => Boolean(path.match(/^(?:\w[\w$_-]*)(?:::\w[\w$_-]*)*$/)); +export const fromElementPathToMappingElementId = (className: string): string => + className.split(ELEMENT_PATH_DELIMITER).join('_'); + +// -------------------------------- HASHING ------------------------------------- +// TODO: this should be moved after we refactor `hashing` out of metamodels + // NOTE: this is over-simplification as there could be source information fields with other names export const hashObjectWithoutSourceInformation = (val: object): string => hashObject(val, { excludeKeys: (key: string) => key === SOURCE_INFORMATION_KEY, }); - -export const fromElementPathToMappingElementId = (className: string): string => - className.split(ELEMENT_PATH_DELIMITER).join('_'); - export const hashLambda = ( parameters: object | undefined, body: object | undefined, @@ -97,3 +101,8 @@ export const hashLambda = ( parameters ? hashObjectWithoutSourceInformation(parameters) : '', body ? hashObjectWithoutSourceInformation(body) : '', ]); + +export const hashElementPointer = (pointerType: string, path: string): string => + [CORE_HASH_STRUCTURE.PACKAGEABLE_ELEMENT_POINTER, pointerType, path] + .map(hashString) + .join(','); diff --git a/packages/legend-graph/src/StoreRelational_Exports.ts b/packages/legend-graph/src/StoreRelational_Exports.ts index 86a3a8210df..40f7c675d06 100644 --- a/packages/legend-graph/src/StoreRelational_Exports.ts +++ b/packages/legend-graph/src/StoreRelational_Exports.ts @@ -42,7 +42,6 @@ export * from './models/metamodels/pure/packageableElements/store/relational/mod export { RelationalInputData, RelationalInputType, - getRelationalInputType, } from './models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInputData'; export { RelationalPropertyMapping } from './models/metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping'; export { RelationalInstanceSetImplementation } from './models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInstanceSetImplementation'; diff --git a/packages/legend-graph/src/__tests__/Inference.test.ts b/packages/legend-graph/src/__tests__/Inference.test.ts index 3b08e4b1d13..6a855082a7b 100644 --- a/packages/legend-graph/src/__tests__/Inference.test.ts +++ b/packages/legend-graph/src/__tests__/Inference.test.ts @@ -28,6 +28,7 @@ import { TEST__excludeSectionIndex, TEST__getTestGraphManagerState, } from '../GraphManagerTestUtils'; +import { getTag } from '../helpers/DomainHelper'; test(unitTest('Infer default mapping element ID'), async () => { const graphManagerState = TEST__getTestGraphManagerState(); @@ -94,9 +95,10 @@ test( let enumeration = graphManagerState.graph.getEnumeration('test::tEnum'); const tagValue = enumeration.taggedValues[0]; if (tagValue) { - tagValue.tag.value = graphManagerState.graph - .getProfile('test::tProf') - .getTag('s4'); + tagValue.tag.value = getTag( + graphManagerState.graph.getProfile('test::tProf'), + 's4', + ); tagValue.tag.ownerReference.value = graphManagerState.graph.getProfile('test::tProf'); } @@ -120,9 +122,10 @@ test( enumeration = graphManagerState.graph.getEnumeration('test::tEnum'); const taggedValue = enumeration.taggedValues[0]; if (taggedValue) { - taggedValue.tag.value = graphManagerState.graph - .getProfile('test2::tProf') - .getTag('s1'); + taggedValue.tag.value = getTag( + graphManagerState.graph.getProfile('test2::tProf'), + 's1', + ); taggedValue.tag.ownerReference.value = graphManagerState.graph.getProfile('test2::tProf'); } diff --git a/packages/legend-graph/src/__tests__/MetaModelUtils.test.ts b/packages/legend-graph/src/__tests__/MetaModelUtils.test.ts index eb5494dad37..fcbc7835a5e 100644 --- a/packages/legend-graph/src/__tests__/MetaModelUtils.test.ts +++ b/packages/legend-graph/src/__tests__/MetaModelUtils.test.ts @@ -34,7 +34,6 @@ import { ObjectInputData, ObjectInputType, } from '../models/metamodels/pure/packageableElements/store/modelToModel/mapping/ObjectInputData'; -import { Class } from '../models/metamodels/pure/packageableElements/domain/Class'; import { PackageableElementExplicitReference } from '../models/metamodels/pure/packageableElements/PackageableElementReference'; import { TEST__buildGraphWithEntities, @@ -43,6 +42,7 @@ import { import { TEST_DATA__MilestonedClassRoundtrip } from './roundtripTestData/TEST_DATA__DomainRoundtrip'; import type { Entity } from '@finos/legend-model-storage'; import { getMilestoneTemporalStereotype } from '../helpers/DomainHelper'; +import { stub_Class } from '../graphManager/action/creation/DomainModelCreatorHelper'; test( unitTest( @@ -77,19 +77,19 @@ test( test(unitTest('JSON Object input data should be minified'), () => { const test1 = new ObjectInputData( - PackageableElementExplicitReference.create(Class.createStub()), + PackageableElementExplicitReference.create(stub_Class()), ObjectInputType.JSON, '{"a":1}', ); const test2 = new ObjectInputData( - PackageableElementExplicitReference.create(Class.createStub()), + PackageableElementExplicitReference.create(stub_Class()), ObjectInputType.JSON, '{\n "a":1\n}', ); const test3 = new ObjectInputData( - PackageableElementExplicitReference.create(Class.createStub()), + PackageableElementExplicitReference.create(stub_Class()), ObjectInputType.JSON, '{\n "a":1, \n "b" : {\n "b1":"hello"\n} \n}', ); diff --git a/packages/legend-graph/src/__tests__/buildGraph/relational/EmbeddedRelational.test.ts b/packages/legend-graph/src/__tests__/buildGraph/relational/EmbeddedRelational.test.ts index fe381aaa6e5..4368940d712 100644 --- a/packages/legend-graph/src/__tests__/buildGraph/relational/EmbeddedRelational.test.ts +++ b/packages/legend-graph/src/__tests__/buildGraph/relational/EmbeddedRelational.test.ts @@ -26,9 +26,13 @@ import { TEST__getTestGraphManagerState, } from '../../../GraphManagerTestUtils'; import type { GraphManagerState } from '../../../GraphManagerState'; -import { getOwnClassMappingsByClass } from '../../../helpers/MappingHelper'; +import { + findPropertyMapping, + getOwnClassMappingsByClass, +} from '../../../helpers/DSLMapping_Helper'; import { RootRelationalInstanceSetImplementation } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/RootRelationalInstanceSetImplementation'; import { EmbeddedRelationalInstanceSetImplementation } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/EmbeddedRelationalInstanceSetImplementation'; +import { getClassProperty } from '../../../helpers/DomainHelper'; let graphManagerState: GraphManagerState; @@ -68,7 +72,7 @@ test(unitTest('Embedded Relational Mapping'), () => { expect(personClassMapping.propertyMappings).toHaveLength(4); // address embedded const addressEmbedded = guaranteeType( - personClassMapping.findPropertyMapping('address', undefined), + findPropertyMapping(personClassMapping, 'address', undefined), EmbeddedRelationalInstanceSetImplementation, ); expect(addressEmbedded.propertyMappings).toHaveLength(2); @@ -84,7 +88,7 @@ test(unitTest('Embedded Relational Mapping'), () => { expect(addressEmbedded.class.value).toBe(addressClass); // firm embedded const firmEmbedded = guaranteeType( - personClassMapping.findPropertyMapping('firm', undefined), + findPropertyMapping(personClassMapping, 'firm', undefined), EmbeddedRelationalInstanceSetImplementation, ); expect(firmEmbedded.propertyMappings).toHaveLength(3); @@ -95,7 +99,7 @@ test(unitTest('Embedded Relational Mapping'), () => { expect(firmEmbedded.class.value).toBe(firmClass); // firm address embedded const firmEmbeddedAddress = guaranteeType( - firmEmbedded.findPropertyMapping('address', undefined), + findPropertyMapping(firmEmbedded, 'address', undefined), EmbeddedRelationalInstanceSetImplementation, ); expect(firmEmbeddedAddress.id.value).toBe( @@ -107,6 +111,6 @@ test(unitTest('Embedded Relational Mapping'), () => { personClassMapping, ); expect(firmEmbeddedAddress.property.value).toBe( - firmClass.getProperty('address'), + getClassProperty(firmClass, 'address'), ); }); diff --git a/packages/legend-graph/src/__tests__/buildGraph/relational/InlineEmbeddedRelational.test.ts b/packages/legend-graph/src/__tests__/buildGraph/relational/InlineEmbeddedRelational.test.ts index 0f9631eea3f..ea5198e3558 100644 --- a/packages/legend-graph/src/__tests__/buildGraph/relational/InlineEmbeddedRelational.test.ts +++ b/packages/legend-graph/src/__tests__/buildGraph/relational/InlineEmbeddedRelational.test.ts @@ -26,7 +26,7 @@ import { TEST__getTestGraphManagerState, } from '../../../GraphManagerTestUtils'; import type { GraphManagerState } from '../../../GraphManagerState'; -import { getOwnClassMappingsByClass } from '../../../helpers/MappingHelper'; +import { getOwnClassMappingsByClass } from '../../../helpers/DSLMapping_Helper'; import { RootRelationalInstanceSetImplementation } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/RootRelationalInstanceSetImplementation'; let graphManagerState: GraphManagerState; @@ -56,8 +56,8 @@ test(unitTest('Inline Embedded Relational Mapping'), () => { ); expect(personClassMapping.id.value).toBe('alias1'); expect(personClassMapping.propertyMappings).toHaveLength(3); - // const otherwiseFirmMapping = guaranteeType(personClassMapping.findPropertyMapping('firm', undefined), OtherwiseEmbeddedRelationalInstanceSetImplementation); - // const legalNamePropertyMapping = guaranteeType(otherwiseFirmMapping.findPropertyMapping('legalName', undefined), RelationalPropertyMapping); + // const otherwiseFirmMapping = guaranteeType(findPropertyMapping(personClassMapping, 'firm', undefined), OtherwiseEmbeddedRelationalInstanceSetImplementation); + // const legalNamePropertyMapping = guaranteeType(findPropertyMapping(otherwiseFirmMapping, 'legalName', undefined), RelationalPropertyMapping); // expect(legalNamePropertyMapping.owner).toBe(otherwiseFirmMapping); // expect(otherwiseFirmMapping.id.value).toBe('alias1_firm'); // expect(otherwiseFirmMapping.primaryKey).toHaveLength(2); diff --git a/packages/legend-graph/src/__tests__/buildGraph/relational/OtherwiseEmbeddedRelational.test.ts b/packages/legend-graph/src/__tests__/buildGraph/relational/OtherwiseEmbeddedRelational.test.ts index 1266166afe2..c87b7bb6f2d 100644 --- a/packages/legend-graph/src/__tests__/buildGraph/relational/OtherwiseEmbeddedRelational.test.ts +++ b/packages/legend-graph/src/__tests__/buildGraph/relational/OtherwiseEmbeddedRelational.test.ts @@ -26,7 +26,10 @@ import { TEST__buildGraphWithEntities, TEST__getTestGraphManagerState, } from '../../../GraphManagerTestUtils'; -import { getOwnClassMappingsByClass } from '../../../helpers/MappingHelper'; +import { + findPropertyMapping, + getOwnClassMappingsByClass, +} from '../../../helpers/DSLMapping_Helper'; import { RootRelationalInstanceSetImplementation } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/RootRelationalInstanceSetImplementation'; import { OtherwiseEmbeddedRelationalInstanceSetImplementation } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/OtherwiseEmbeddedRelationalInstanceSetImplementation'; import { RelationalPropertyMapping } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping'; @@ -59,11 +62,11 @@ test(unitTest('Otherwise Embedded Relational Mapping'), () => { expect(personClassMapping.id.value).toBe('alias1'); expect(personClassMapping.propertyMappings).toHaveLength(2); const otherwiseFirmMapping = guaranteeType( - personClassMapping.findPropertyMapping('firm', undefined), + findPropertyMapping(personClassMapping, 'firm', undefined), OtherwiseEmbeddedRelationalInstanceSetImplementation, ); - // const legalNamePropertyMapping = guaranteeType(otherwiseFirmMapping.findPropertyMapping('legalName', undefined), RelationalPropertyMapping); + // const legalNamePropertyMapping = guaranteeType(findPropertyMapping(otherwiseFirmMapping, 'legalName', undefined), RelationalPropertyMapping); // expect(legalNamePropertyMapping.owner).toBe(otherwiseFirmMapping); expect(otherwiseFirmMapping.id.value).toBe('alias1_firm'); expect(otherwiseFirmMapping.primaryKey).toHaveLength(1); diff --git a/packages/legend-graph/src/__tests__/buildGraph/relational/PropertyThroughAssociationGraphSuccess.test.ts b/packages/legend-graph/src/__tests__/buildGraph/relational/PropertyThroughAssociationGraphSuccess.test.ts index 8f417a3d2a3..22d5c033a35 100644 --- a/packages/legend-graph/src/__tests__/buildGraph/relational/PropertyThroughAssociationGraphSuccess.test.ts +++ b/packages/legend-graph/src/__tests__/buildGraph/relational/PropertyThroughAssociationGraphSuccess.test.ts @@ -30,9 +30,13 @@ import { DynaFunction, TableAliasColumn, } from '../../../models/metamodels/pure/packageableElements/store/relational/model/RelationalOperationElement'; -import { getOwnClassMappingsByClass } from '../../../helpers/MappingHelper'; +import { + findPropertyMapping, + getOwnClassMappingsByClass, +} from '../../../helpers/DSLMapping_Helper'; import { RootRelationalInstanceSetImplementation } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/RootRelationalInstanceSetImplementation'; import { RelationalPropertyMapping } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping'; +import { getTable } from '../../../helpers/StoreRelational_Helper'; let graphManagerState: GraphManagerState; @@ -53,8 +57,8 @@ test(unitTest('Relational Mapping with property from association'), () => { expect(database.schemas).toHaveLength(1); const defaultSchema = guaranteeNonNullable(database.schemas[0]); expect(defaultSchema.tables).toHaveLength(2); - defaultSchema.getTable('personTable'); - defaultSchema.getTable('firmTable'); + getTable(defaultSchema, 'personTable'); + getTable(defaultSchema, 'firmTable'); // join expect(database.joins).toHaveLength(1); const firmPersonJoin = guaranteeNonNullable(database.joins[0]); @@ -115,7 +119,7 @@ test(unitTest('Relational Mapping with property from association'), () => { expect(firmPrimaryKey.column.value.name).toBe('ID'); // association property const firmProperty = guaranteeType( - personClassMapping.findPropertyMapping('firm', undefined), + findPropertyMapping(personClassMapping, 'firm', undefined), RelationalPropertyMapping, ); expect(firmProperty.targetSetImplementation).toBe(firmClassMapping); diff --git a/packages/legend-graph/src/__tests__/buildGraph/relational/SimpleRelationalGraphBuildSuccess.test.ts b/packages/legend-graph/src/__tests__/buildGraph/relational/SimpleRelationalGraphBuildSuccess.test.ts index 7446d7b6ab7..cb933384ad1 100644 --- a/packages/legend-graph/src/__tests__/buildGraph/relational/SimpleRelationalGraphBuildSuccess.test.ts +++ b/packages/legend-graph/src/__tests__/buildGraph/relational/SimpleRelationalGraphBuildSuccess.test.ts @@ -30,12 +30,16 @@ import { } from '../../../GraphManagerTestUtils'; import { Database } from '../../../models/metamodels/pure/packageableElements/store/relational/model/Database'; import { RootRelationalInstanceSetImplementation } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/RootRelationalInstanceSetImplementation'; -import { getOwnClassMappingsByClass } from '../../../helpers/MappingHelper'; +import { + findPropertyMapping, + getOwnClassMappingsByClass, +} from '../../../helpers/DSLMapping_Helper'; import { EmbeddedRelationalInstanceSetImplementation } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/EmbeddedRelationalInstanceSetImplementation'; import { RelationalPropertyMapping } from '../../../models/metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping'; import { PRIMITIVE_TYPE } from '../../../MetaModelConst'; import { TEST_DATA__SemiStructuredRelationalTypeRoundtrip } from './TEST_DATA__SemiStructuredRelationalTypeRoundtrip'; import { DSLExternalFormat_GraphPreset } from '../../../graph/DSLExternalFormat_Extension'; +import { getSchema, getTable } from '../../../helpers/StoreRelational_Helper'; let graphManagerState: GraphManagerState; @@ -56,20 +60,20 @@ test(unitTest('Relational database is loaded properly'), () => { expect(db.schemas).toHaveLength(2); expect(db.filters).toHaveLength(4); expect(db.joins).toHaveLength(21); - const defaultSchema = db.getSchema('default'); + const defaultSchema = getSchema(db, 'default'); expect(defaultSchema.tables).toHaveLength(8); expect(defaultSchema.views).toHaveLength(7); - const interactionTable = defaultSchema.getTable('interactionTable'); + const interactionTable = getTable(defaultSchema, 'interactionTable'); expect(interactionTable.columns).toHaveLength(5); expect(interactionTable.primaryKey[0]?.name).toBe('ID'); - const productSchema = db.getSchema('productSchema'); + const productSchema = getSchema(db, 'productSchema'); expect(productSchema.tables).toHaveLength(1); expect(productSchema.views).toHaveLength(0); expect(db.includes).toHaveLength(1); // dbInc const dbInc = guaranteeType(db.includes[0]?.value, Database); expect(dbInc.path).toBe('meta::relational::tests::dbInc'); - const dbIncDefaultSchema = dbInc.getSchema('default'); + const dbIncDefaultSchema = getSchema(dbInc, 'default'); expect(dbIncDefaultSchema.tables).toHaveLength(9); expect(dbIncDefaultSchema.views).toHaveLength(3); // add join/fiilter tests @@ -106,7 +110,7 @@ test(unitTest('Relational Mapping is loaded properly'), () => { ); expect(firmExtensionSetImpl.propertyMappings).toHaveLength(3); const embeddedProperty = guaranteeType( - firmExtensionSetImpl.findPropertyMapping('employeesExt', undefined), + findPropertyMapping(firmExtensionSetImpl, 'employeesExt', undefined), EmbeddedRelationalInstanceSetImplementation, ); expect(embeddedProperty.propertyMappings).toHaveLength(1); diff --git a/packages/legend-graph/src/graph/DependencyManager.ts b/packages/legend-graph/src/graph/DependencyManager.ts index 6fa77c03b5a..b9b7da7813e 100644 --- a/packages/legend-graph/src/graph/DependencyManager.ts +++ b/packages/legend-graph/src/graph/DependencyManager.ts @@ -78,7 +78,7 @@ export class DependencyManager { */ initialize(dependencyEntitiesMap: Map): void { Array.from(dependencyEntitiesMap.keys()).forEach((dependencyKey) => { - // NOTE: all dependency models will share the dependency manager package root. + // NOTE: all dependency models will share the dependency manager root package. this.projectDependencyModelsIndex.set( dependencyKey, new DependencyModel(this.extensionElementClasses, this.root), diff --git a/packages/legend-graph/src/graph/PureGraphPlugin.ts b/packages/legend-graph/src/graph/PureGraphPlugin.ts index 7a7aeb7e549..e6b37f4426b 100644 --- a/packages/legend-graph/src/graph/PureGraphPlugin.ts +++ b/packages/legend-graph/src/graph/PureGraphPlugin.ts @@ -18,9 +18,10 @@ import { AbstractPlugin, type Clazz } from '@finos/legend-shared'; import type { PackageableElement } from '../models/metamodels/pure/packageableElements/PackageableElement'; import type { PureModel } from './PureModel'; import type { GraphPluginManager } from '../GraphPluginManager'; -import type { TestablesCollector } from '../models/metamodels/pure/test/Testable'; +import type { Testable } from '../models/metamodels/pure/test/Testable'; export type DeadReferencesCleaner = (graph: PureModel) => void; +export type TestablesCollector = (graph: PureModel) => Testable[]; /** * Plugins for Pure graph (aka `PureModel`). These plugins concern the operations of the graph alone and diff --git a/packages/legend-graph/src/graph/PureModel.ts b/packages/legend-graph/src/graph/PureModel.ts index cdb30815e96..b326de2bc5d 100644 --- a/packages/legend-graph/src/graph/PureModel.ts +++ b/packages/legend-graph/src/graph/PureModel.ts @@ -36,8 +36,6 @@ import type { Type } from '../models/metamodels/pure/packageableElements/domain/ import { Class } from '../models/metamodels/pure/packageableElements/domain/Class'; import type { Mapping } from '../models/metamodels/pure/packageableElements/mapping/Mapping'; import type { Profile } from '../models/metamodels/pure/packageableElements/domain/Profile'; -import type { Stereotype } from '../models/metamodels/pure/packageableElements/domain/Stereotype'; -import type { Tag } from '../models/metamodels/pure/packageableElements/domain/Tag'; import type { Store } from '../models/metamodels/pure/packageableElements/store/Store'; import { DependencyManager } from '../graph/DependencyManager'; import { ConcreteFunctionDefinition } from '../models/metamodels/pure/packageableElements/domain/ConcreteFunctionDefinition'; @@ -220,21 +218,6 @@ export class PureModel extends BasicModel { return [...this.ownTestables].concat(...extraTestables); } - getProfileStereotype = ( - path: string, - value: string, - ): Stereotype | undefined => this.getProfile(path).getStereotype(value); - getProfileTag = (path: string, value: string): Tag | undefined => - this.getProfile(path).getTag(value); - getNullableClass = (path: string): Class | undefined => - returnUndefOnError(() => this.getClass(path)); - getNullableMapping = (path: string): Mapping | undefined => - returnUndefOnError(() => this.getMapping(path)); - getNullableFileGeneration = ( - path: string, - ): FileGenerationSpecification | undefined => - returnUndefOnError(() => this.getFileGeneration(path)); - getPrimitiveType = (type: PRIMITIVE_TYPE): PrimitiveType => guaranteeNonNullable( this.coreModel.primitiveTypesIndex.get(type), @@ -393,6 +376,15 @@ export class PureModel extends BasicModel { `Can't find element '${path}'`, ); + getNullableClass = (path: string): Class | undefined => + returnUndefOnError(() => this.getClass(path)); + getNullableMapping = (path: string): Mapping | undefined => + returnUndefOnError(() => this.getMapping(path)); + getNullableFileGeneration = ( + path: string, + ): FileGenerationSpecification | undefined => + returnUndefOnError(() => this.getFileGeneration(path)); + getNullableElement( path: string, includePackage?: boolean, diff --git a/packages/legend-graph/src/graphManager/AbstractPureGraphManager.ts b/packages/legend-graph/src/graphManager/AbstractPureGraphManager.ts index b18fb94b299..e3bdc966878 100644 --- a/packages/legend-graph/src/graphManager/AbstractPureGraphManager.ts +++ b/packages/legend-graph/src/graphManager/AbstractPureGraphManager.ts @@ -65,7 +65,6 @@ import type { ModelGenerationConfiguration } from '../models/ModelGenerationConf import type { DEPRECATED__ServiceTestResult } from './action/service/DEPRECATED__ServiceTestResult'; import type { RunTestsTestableInput } from '../models/metamodels/pure/test/result/RunTestsTestableInput'; import type { TestResult } from '../models/metamodels/pure/test/result/TestResult'; -import type { PureGraphManagerPlugin } from './PureGraphManagerPlugin'; export interface TEMPORARY__EngineSetupConfig { env: string; @@ -220,9 +219,8 @@ export abstract class AbstractPureGraphManager { // ------------------------------------------- Test ------------------------------------------- abstract runTests( + inputs: RunTestsTestableInput[], graph: PureModel, - pureGraphManagerPlugins: PureGraphManagerPlugin[], - testableInputs: RunTestsTestableInput[], ): Promise; // ------------------------------------------- ValueSpecification ------------------------------------------- diff --git a/packages/legend-graph/src/graphManager/PureGraphManagerPlugin.ts b/packages/legend-graph/src/graphManager/PureGraphManagerPlugin.ts index 4fc0376471d..676b3ec7fd7 100644 --- a/packages/legend-graph/src/graphManager/PureGraphManagerPlugin.ts +++ b/packages/legend-graph/src/graphManager/PureGraphManagerPlugin.ts @@ -15,12 +15,10 @@ */ import { AbstractPlugin } from '@finos/legend-shared'; +import type { PureModel } from '../graph/PureModel'; import type { GraphPluginManager } from '../GraphPluginManager'; import type { PackageableElement } from '../models/metamodels/pure/packageableElements/PackageableElement'; -import type { - TestableIDBuilder, - TestableFinder, -} from '../models/metamodels/pure/test/Testable'; +import type { Testable } from '../models/metamodels/pure/test/Testable'; import type { ObserverContext } from './action/changeDetection/CoreObserverHelper'; /** @@ -31,11 +29,22 @@ import type { ObserverContext } from './action/changeDetection/CoreObserverHelpe export type PureGrammarElementLabeler = ( metamodel: PackageableElement, ) => string | undefined; + export type ElementObserver = ( metamodel: PackageableElement, context: ObserverContext, ) => PackageableElement | undefined; +export type TestableIDBuilder = ( + testable: Testable, + graph: PureModel, +) => string | undefined; + +export type TestableFinder = ( + id: string, + graph: PureModel, +) => Testable | undefined; + export abstract class PureGraphManagerPlugin extends AbstractPlugin { /** * This helps to better type-checking for this empty abtract type diff --git a/packages/legend-graph/src/graphManager/action/changeDetection/CoreObserverHelper.ts b/packages/legend-graph/src/graphManager/action/changeDetection/CoreObserverHelper.ts index 2d2bf5e8f6a..577f109207c 100644 --- a/packages/legend-graph/src/graphManager/action/changeDetection/CoreObserverHelper.ts +++ b/packages/legend-graph/src/graphManager/action/changeDetection/CoreObserverHelper.ts @@ -95,7 +95,6 @@ export const observe_Multiplicity = skipObserved( makeObservable(metamodel, { lowerBound: observable, upperBound: observable, - str: computed, hashCode: computed, }), ); diff --git a/packages/legend-graph/src/graphManager/action/changeDetection/DSLMapping_ObserverHelper.ts b/packages/legend-graph/src/graphManager/action/changeDetection/DSLMapping_ObserverHelper.ts index 0133c8b0077..cfdc63813de 100644 --- a/packages/legend-graph/src/graphManager/action/changeDetection/DSLMapping_ObserverHelper.ts +++ b/packages/legend-graph/src/graphManager/action/changeDetection/DSLMapping_ObserverHelper.ts @@ -171,7 +171,6 @@ export const observe_PurePropertyMapping = skipObservedWithContext( transformer: observable, transform: observable, explodeProperty: observable, - isStub: computed, hashCode: computed, }); @@ -334,9 +333,7 @@ export const observe_SetImplementationReference = skipObserved( export const observe_SetImplementationContainer = skipObserved( (metamodel: SetImplementationContainer): SetImplementationContainer => { - makeObservable(metamodel, { - isStub: computed, - }); + makeObservable(metamodel, {}); observe_SetImplementationReference(metamodel.setImplementation); @@ -352,7 +349,6 @@ export const observe_Abstract_OperationSetImplementation = ( makeObservable(metamodel, { parameters: observable, operation: observable, - isStub: computed, hashCode: computed, }); @@ -392,7 +388,6 @@ export const observe_PureInstanceSetImplementation = skipObservedWithContext( makeObservable(metamodel, { filter: observable, - isStub: computed, hashCode: computed, }); @@ -539,7 +534,6 @@ export const observe_SourceValue = skipObserved( (metamodel: SourceValue): SourceValue => makeObservable(metamodel, { value: observable, - isStub: computed, }), ); @@ -547,7 +541,6 @@ export const observe_EnumValueMapping = skipObserved( (metamodel: EnumValueMapping): EnumValueMapping => { makeObservable(metamodel, { sourceValues: observable, - isStub: computed, hashCode: computed, }); @@ -563,7 +556,6 @@ export const observe_EnumerationMapping = skipObserved( makeObservable(metamodel, { sourceType: observable, enumValueMappings: observable, - isStub: computed, hashCode: computed, }); @@ -692,10 +684,6 @@ export const observe_Mapping = skipObservedWithContext( enumerationMappings: observable, associationMappings: observable, tests: observable, - allOwnClassMappings: computed, - allOwnEnumerationMappings: computed, - allIncludedMappings: computed, - isStub: computed, _elementHashCode: override, }); @@ -869,7 +857,6 @@ export const observe_StoreConnections = skipObservedWithContext( (metamodel: StoreConnections, context): StoreConnections => { makeObservable(metamodel, { storeConnections: observable, - isStub: computed, hashCode: computed, }); @@ -887,7 +874,6 @@ export const observe_EngineRuntime = skipObservedWithContext( makeObservable(metamodel, { mappings: observable, connections: observable, - allIdentifiedConnections: computed, hashCode: computed, }); diff --git a/packages/legend-graph/src/graphManager/action/changeDetection/DomainObserverHelper.ts b/packages/legend-graph/src/graphManager/action/changeDetection/DomainObserverHelper.ts index e607d51cf33..af0bbcc9bf2 100644 --- a/packages/legend-graph/src/graphManager/action/changeDetection/DomainObserverHelper.ts +++ b/packages/legend-graph/src/graphManager/action/changeDetection/DomainObserverHelper.ts @@ -123,7 +123,6 @@ export const observe_StereotypeReference = skipObserved( (metamodel: StereotypeReference): StereotypeReference => { makeObservable(metamodel, { value: observable, - isStub: computed, pointerHashCode: computed, }); @@ -137,7 +136,6 @@ export const observe_TagReference = skipObserved( (metamodel: TagReference): TagReference => { makeObservable(metamodel, { value: observable, - isStub: computed, pointerHashCode: computed, }); @@ -149,7 +147,6 @@ export const observe_TaggedValue = skipObserved( (metamodel: TaggedValue): TaggedValue => { makeObservable(metamodel, { value: observable, - isStub: computed, hashCode: computed, }); @@ -163,7 +160,6 @@ export const observe_GenericType = skipObserved( (metamodel: GenericType): GenericType => makeObservable(metamodel, { rawType: observable, - isStub: computed, }), ); @@ -171,7 +167,6 @@ export const observe_GenericTypeReference = skipObserved( (metamodel: GenericTypeReference): GenericTypeReference => { makeObservable(metamodel, { value: observable, - isStub: computed, }); observe_GenericType(metamodel.value); @@ -223,7 +218,6 @@ export const observe_Stereotype = skipObserved( (metamodel: Stereotype): Stereotype => makeObservable(metamodel, { value: observable, - isStub: computed, }), ); @@ -231,7 +225,6 @@ export const observe_Tag = skipObserved( (metamodel: Tag): Tag => makeObservable(metamodel, { value: observable, - isStub: computed, }), ); @@ -241,7 +234,6 @@ export const observe_Profile = skipObserved((metamodel: Profile): Profile => { makeObservable(metamodel, { stereotypes: observable, tags: observable, - isStub: computed, _elementHashCode: override, }); @@ -258,7 +250,6 @@ export const observe_Enum = skipObserved((metamodel: Enum): Enum => { name: observable, stereotypes: observable, taggedValues: observable, - isStub: computed, hashCode: computed, }); @@ -272,7 +263,6 @@ export const observe_EnumValueReference = skipObserved( (metamodel: EnumValueReference): EnumValueReference => { makeObservable(metamodel, { value: observable, - isStub: computed, }); observe_PackageableElementReference(metamodel.ownerReference); @@ -289,7 +279,6 @@ export const observe_Enumeration = skipObserved( values: observable, stereotypes: observable, taggedValues: observable, - isStub: computed, _elementHashCode: override, }); @@ -343,7 +332,6 @@ export const observe_Property = skipObserved( multiplicity: observable, stereotypes: observable, taggedValues: observable, - isStub: computed, hashCode: computed, }); @@ -365,7 +353,6 @@ export const observe_DerivedProperty = skipObserved( taggedValues: observable, body: observable.ref, // only observe the reference, the object itself is not observed parameters: observable.ref, // only observe the reference, the object itself is not observed - isStub: computed, hashCode: computed, }); @@ -382,7 +369,6 @@ export const observe_PropertyReference = skipObserved( (metamodel: PropertyReference): PropertyReference => { makeObservable(metamodel, { value: observable, - isStub: computed, pointerHashCode: computed, }); @@ -400,7 +386,6 @@ export const observe_Constraint = skipObserved( externalId: observable, enforcementLevel: observable, messageFunction: observable, - isStub: computed, hashCode: computed, }); @@ -418,18 +403,15 @@ export const observe_Class = skipObserved((metamodel: Class): Class => { observe_Abstract_PackageableElement(metamodel); makeObservable(metamodel, { + _subclasses: observable, properties: observable, propertiesFromAssociations: observable, derivedProperties: observable, generalizations: observable, - subclasses: observable, constraints: observable, stereotypes: observable, taggedValues: observable, - allSuperclasses: computed, - allSubclasses: computed, dispose: override, - isStub: computed, _elementHashCode: override, }); @@ -455,7 +437,6 @@ export const observe_Association = skipObserved( stereotypes: observable, taggedValues: observable, derivedProperties: observable, - isStub: computed, _elementHashCode: override, }); diff --git a/packages/legend-graph/src/graphManager/action/changeDetection/RawValueSpecificationObserver.ts b/packages/legend-graph/src/graphManager/action/changeDetection/RawValueSpecificationObserver.ts index e455176ca7c..d6e45c7159d 100644 --- a/packages/legend-graph/src/graphManager/action/changeDetection/RawValueSpecificationObserver.ts +++ b/packages/legend-graph/src/graphManager/action/changeDetection/RawValueSpecificationObserver.ts @@ -52,7 +52,6 @@ export const observe_RawLambda = skipObserved( makeObservable(metamodel, { body: observable.ref, // only observe the reference, the object itself is not observed parameters: observable.ref, // only observe the reference, the object itself is not observed - isStub: computed, hashCode: computed, }), ); @@ -62,7 +61,6 @@ export const observe_RawVariableExpression = skipObserved( makeObservable(metamodel, { name: observable, multiplicity: observable, - isStub: computed, hashCode: computed, }); diff --git a/packages/legend-graph/src/graphManager/action/changeDetection/StoreFlatData_ObserverHelper.ts b/packages/legend-graph/src/graphManager/action/changeDetection/StoreFlatData_ObserverHelper.ts index 8cfdf2b7227..fc241257cae 100644 --- a/packages/legend-graph/src/graphManager/action/changeDetection/StoreFlatData_ObserverHelper.ts +++ b/packages/legend-graph/src/graphManager/action/changeDetection/StoreFlatData_ObserverHelper.ts @@ -165,7 +165,6 @@ export const observe_FlatData = skipObserved( makeObservable(metamodel, { sections: observable, - recordTypes: computed, _elementHashCode: override, }); @@ -223,7 +222,6 @@ export const observe_EmbeddedFlatDataPropertyMapping = skipObservedWithContext( makeObservable(metamodel, { rootInstanceSetImplementation: observable, - isStub: computed, hashCode: computed, }); @@ -238,7 +236,6 @@ export const observe_FlatDataPropertyMapping = skipObservedWithContext( makeObservable(metamodel, { transformer: observable, transform: observable, - isStub: computed, hashCode: computed, }); diff --git a/packages/legend-graph/src/graphManager/action/creation/DSLMapping_ModelCreatorHelper.ts b/packages/legend-graph/src/graphManager/action/creation/DSLMapping_ModelCreatorHelper.ts new file mode 100644 index 00000000000..cfd4993d867 --- /dev/null +++ b/packages/legend-graph/src/graphManager/action/creation/DSLMapping_ModelCreatorHelper.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2020-present, Goldman Sachs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { isNonNullable } from '@finos/legend-shared'; +import type { EnumValueMapping } from '../../../models/metamodels/pure/packageableElements/mapping/EnumValueMapping'; +import { Mapping } from '../../../models/metamodels/pure/packageableElements/mapping/Mapping'; +import type { SetImplementationContainer } from '../../../models/metamodels/pure/packageableElements/mapping/SetImplementationContainer'; +import type { StoreConnections } from '../../../models/metamodels/pure/packageableElements/runtime/Runtime'; + +export const stub_Mapping = (): Mapping => new Mapping(''); + +export const isStubbed_EnumValueMapping = (value: EnumValueMapping): boolean => + !value.sourceValues.filter(isNonNullable).length; + +export const isStubbed_StoreConnections = (value: StoreConnections): boolean => + !value.storeConnections.length; + +export const isStubbed_SetImplementationContainer = ( + value: SetImplementationContainer, +): boolean => !value.setImplementation.value.id.value; diff --git a/packages/legend-graph/src/graphManager/action/creation/DomainModelCreatorHelper.ts b/packages/legend-graph/src/graphManager/action/creation/DomainModelCreatorHelper.ts new file mode 100644 index 00000000000..61454b2e2a9 --- /dev/null +++ b/packages/legend-graph/src/graphManager/action/creation/DomainModelCreatorHelper.ts @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2020-present, Goldman Sachs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Profile } from '../../../models/metamodels/pure/packageableElements/domain/Profile'; +import { Tag } from '../../../models/metamodels/pure/packageableElements/domain/Tag'; +import { Enum } from '../../../models/metamodels/pure/packageableElements/domain/Enum'; +import { Stereotype } from '../../../models/metamodels/pure/packageableElements/domain/Stereotype'; +import { TaggedValue } from '../../../models/metamodels/pure/packageableElements/domain/TaggedValue'; +import { TagExplicitReference } from '../../../models/metamodels/pure/packageableElements/domain/TagReference'; +import type { Enumeration } from '../../../models/metamodels/pure/packageableElements/domain/Enumeration'; +import { Class } from '../../../models/metamodels/pure/packageableElements/domain/Class'; +import { Constraint } from '../../../models/metamodels/pure/packageableElements/domain/Constraint'; +import { stub_RawLambda } from './RawValueSpecificationCreatorHelper'; +import type { PackageableElement } from '../../../models/metamodels/pure/packageableElements/PackageableElement'; +import { Multiplicity } from '../../../models/metamodels/pure/packageableElements/domain/Multiplicity'; +import { GenericTypeExplicitReference } from '../../../models/metamodels/pure/packageableElements/domain/GenericTypeReference'; +import { GenericType } from '../../../models/metamodels/pure/packageableElements/domain/GenericType'; +import type { Type } from '../../../models/metamodels/pure/packageableElements/domain/Type'; +import { DerivedProperty } from '../../../models/metamodels/pure/packageableElements/domain/DerivedProperty'; +import { Property } from '../../../models/metamodels/pure/packageableElements/domain/Property'; + +export const stub_Tag = (profile: Profile): Tag => new Tag(profile, ''); +export const stub_TaggedValue = (tag: Tag): TaggedValue => + new TaggedValue(TagExplicitReference.create(tag), ''); +export const stub_Stereotype = (profile: Profile): Stereotype => + new Stereotype(profile, ''); +export const stub_Profile = (): Profile => new Profile(''); +export const stub_Enum = (enumeration: Enumeration): Enum => + new Enum('', enumeration); +export const stub_Constraint = (_class: Class): Constraint => + new Constraint('', _class, stub_RawLambda()); +export const stub_Class = (): Class => new Class(''); +export const stub_Property = (type: Type, _class: Class): Property => + new Property( + '', + // NOTE: this multiplicity is subjected to change so we cannot pass + // the one from the graph typical multiplicity index + new Multiplicity(1, 1), + GenericTypeExplicitReference.create(new GenericType(type)), + _class, + ); +export const stub_DerivedProperty = ( + type: Type, + _class: Class, +): DerivedProperty => + new DerivedProperty( + '', + // NOTE: this multiplicity is subjected to change so we cannot pass + // the one from the graph typical multiplicity index + new Multiplicity(1, 1), + GenericTypeExplicitReference.create(new GenericType(type)), + _class, + ); + +export const isStubbed_PackageableElement = ( + element: PackageableElement, +): boolean => !element.package && !element.name; diff --git a/packages/legend-graph/src/graphManager/action/creation/RawValueSpecificationCreatorHelper.ts b/packages/legend-graph/src/graphManager/action/creation/RawValueSpecificationCreatorHelper.ts new file mode 100644 index 00000000000..347c2186520 --- /dev/null +++ b/packages/legend-graph/src/graphManager/action/creation/RawValueSpecificationCreatorHelper.ts @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2020-present, Goldman Sachs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Multiplicity } from '../../../models/metamodels/pure/packageableElements/domain/Multiplicity'; +import type { Type } from '../../../models/metamodels/pure/packageableElements/domain/Type'; +import { PackageableElementExplicitReference } from '../../../models/metamodels/pure/packageableElements/PackageableElementReference'; +import { RawLambda } from '../../../models/metamodels/pure/rawValueSpecification/RawLambda'; +import { RawVariableExpression } from '../../../models/metamodels/pure/rawValueSpecification/RawVariableExpression'; + +export const stub_RawVariableExpression = (type: Type): RawVariableExpression => + new RawVariableExpression( + '', + // NOTE: this multiplicity is subjected to change so we cannot pass + // the one from the graph typical multiplicity index + new Multiplicity(1, 1), + PackageableElementExplicitReference.create(type), + ); + +export const stub_RawLambda = (): RawLambda => + new RawLambda(undefined, undefined); + +export const create_RawLambda = ( + parameters: object | undefined, + body: object | undefined, +): RawLambda => new RawLambda(parameters, body); + +export const isStubbed_RawLambda = (rawLambda: RawLambda): boolean => + !rawLambda.body && !rawLambda.parameters; diff --git a/packages/legend-graph/src/graphManager/action/creation/StoreRelational_ModelCreatorHelper.ts b/packages/legend-graph/src/graphManager/action/creation/StoreRelational_ModelCreatorHelper.ts new file mode 100644 index 00000000000..be5bf5c6932 --- /dev/null +++ b/packages/legend-graph/src/graphManager/action/creation/StoreRelational_ModelCreatorHelper.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2020-present, Goldman Sachs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { isEmpty } from '@finos/legend-shared'; +import type { RawRelationalOperationElement } from '../../../models/metamodels/pure/packageableElements/store/relational/model/RawRelationalOperationElement'; +import { Database } from '../../../StoreRelational_Exports'; + +export const stub_RawRelationalOperationElement = + (): RawRelationalOperationElement => ({}); + +export const isStubbed_RawRelationalOperationElement = ( + operation: RawRelationalOperationElement, +): boolean => isEmpty(operation); + +export const stub_Database = (): Database => new Database(''); diff --git a/packages/legend-graph/src/helpers/DSLGeneration_Helper.ts b/packages/legend-graph/src/helpers/DSLGeneration_Helper.ts new file mode 100644 index 00000000000..16a586011f2 --- /dev/null +++ b/packages/legend-graph/src/helpers/DSLGeneration_Helper.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2020-present, Goldman Sachs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ConfigurationProperty } from '../models/metamodels/pure/packageableElements/fileGeneration/ConfigurationProperty'; +import type { FileGenerationSpecification } from '../models/metamodels/pure/packageableElements/fileGeneration/FileGenerationSpecification'; + +export const getNullableFileGenerationConfig = ( + fileGeneration: FileGenerationSpecification, + name: string, +): ConfigurationProperty | undefined => + fileGeneration.configurationProperties.find( + (property) => name === property.name, + ); diff --git a/packages/legend-graph/src/helpers/MappingHelper.ts b/packages/legend-graph/src/helpers/DSLMapping_Helper.ts similarity index 53% rename from packages/legend-graph/src/helpers/MappingHelper.ts rename to packages/legend-graph/src/helpers/DSLMapping_Helper.ts index 6b8934f2693..d05afb47c09 100644 --- a/packages/legend-graph/src/helpers/MappingHelper.ts +++ b/packages/legend-graph/src/helpers/DSLMapping_Helper.ts @@ -15,10 +15,13 @@ */ import { + assertTrue, filterByType, findLast, + generateEnumerableNameFromToken, guaranteeNonNullable, uniq, + UnsupportedOperationError, } from '@finos/legend-shared'; import type { EnumerationMapping } from '../models/metamodels/pure/packageableElements/mapping/EnumerationMapping'; import type { SetImplementation } from '../models/metamodels/pure/packageableElements/mapping/SetImplementation'; @@ -27,11 +30,42 @@ import type { Enumeration } from '../models/metamodels/pure/packageableElements/ import type { Mapping } from '../models/metamodels/pure/packageableElements/mapping/Mapping'; import { AggregationAwareSetImplementation } from '../models/metamodels/pure/packageableElements/mapping/aggregationAware/AggregationAwareSetImplementation'; import { RootRelationalInstanceSetImplementation } from '../models/metamodels/pure/packageableElements/store/relational/mapping/RootRelationalInstanceSetImplementation'; +import type { PropertyMapping } from '../models/metamodels/pure/packageableElements/mapping/PropertyMapping'; +import type { InstanceSetImplementation } from '../models/metamodels/pure/packageableElements/mapping/InstanceSetImplementation'; +import type { + EngineRuntime, + IdentifiedConnection, +} from '../models/metamodels/pure/packageableElements/runtime/Runtime'; +import { OperationSetImplementation } from '../models/metamodels/pure/packageableElements/mapping/OperationSetImplementation'; +import { ObjectInputType } from '../models/metamodels/pure/packageableElements/store/modelToModel/mapping/ObjectInputData'; + +// ----------------------------------------- Mapping ----------------------------------------- + +/** + * Get all included mappings, accounted for loop and duplication (which should be caught by compiler) + */ +export const getAllIncludedMappings = (mapping: Mapping): Mapping[] => { + const visited = new Set(); + visited.add(mapping); + const resolveIncludes = (_mapping: Mapping): void => { + _mapping.includes.forEach((incMapping) => { + if (!visited.has(incMapping.included.value)) { + visited.add(incMapping.included.value); + resolveIncludes(incMapping.included.value); + } + }); + }; + resolveIncludes(mapping); + visited.delete(mapping); + return Array.from(visited); +}; export const getAllClassMappings = (mapping: Mapping): SetImplementation[] => uniq( - mapping.allOwnClassMappings.concat( - mapping.allIncludedMappings.map((e) => e.allOwnClassMappings).flat(), + mapping.classMappings.concat( + getAllIncludedMappings(mapping) + .map((e) => e.classMappings) + .flat(), ), ); @@ -39,9 +73,9 @@ export const getAllEnumerationMappings = ( mapping: Mapping, ): EnumerationMapping[] => uniq( - mapping.allOwnEnumerationMappings.concat( - mapping.allIncludedMappings - .map((e) => e.allOwnEnumerationMappings) + mapping.enumerationMappings.concat( + getAllIncludedMappings(mapping) + .map((e) => e.enumerationMappings) .flat(), ), ); @@ -72,7 +106,7 @@ export const getOwnClassMappingById = ( ): SetImplementation => guaranteeNonNullable( [ - ...mapping.allOwnClassMappings, + ...mapping.classMappings, ...extractClassMappingsFromAggregationAwareClassMappings(mapping), ].find((classMapping) => classMapping.id.value === id), `Can't find class mapping with ID '${id}' in mapping '${mapping.path}'`, @@ -96,7 +130,7 @@ export const getOwnClassMappingsByClass = ( ): SetImplementation[] => // TODO: Add association property Mapping to class mappings, AggregationAwareSetImplementation, mappingClass // NOTE: Add in the proper order so find root can resolve properly down the line - mapping.allOwnClassMappings.filter( + mapping.classMappings.filter( (classMapping) => classMapping.class.value === _class, ); @@ -165,3 +199,102 @@ export const getRootSetImplementation = ( _class: Class, ): SetImplementation | undefined => findRootSetImplementation(getClassMappingsByClass(mapping, _class)); + +export const findPropertyMapping = ( + instanceSetImplementation: InstanceSetImplementation, + propertyName: string, + targetId: string | undefined, +): PropertyMapping | undefined => { + let properties = undefined; + properties = instanceSetImplementation.propertyMappings.filter( + (propertyMapping) => propertyMapping.property.value.name === propertyName, + ); + if (targetId === undefined || properties.length === 1) { + return properties[0]; + } + return properties.find( + (propertyMapping) => + propertyMapping.targetSetImplementation && + propertyMapping.targetSetImplementation.id.value === targetId, + ); +}; + +/** + * Get all child set implementation of an operation set implementation (including itself). + * This takes into account loops and duplication. + */ +export const getAllChildSetImplementations = ( + operationSetImplementation: OperationSetImplementation, +): SetImplementation[] => { + const visitedOperations = new Set(); + visitedOperations.add(operationSetImplementation); + const _leaves = new Set(); + const resolveLeaves = (_opSetImpl: OperationSetImplementation): void => { + _opSetImpl.parameters.forEach((p) => { + const setImp = p.setImplementation.value; + if ( + setImp instanceof OperationSetImplementation && + !visitedOperations.has(setImp) + ) { + visitedOperations.add(setImp); + resolveLeaves(setImp); + } else { + _leaves.add(setImp); + } + }); + }; + resolveLeaves(operationSetImplementation); + visitedOperations.delete(operationSetImplementation); + return Array.from(_leaves).concat(Array.from(visitedOperations)); +}; + +/** + * Get all leaf set implementations (i.e. no operation) of an operation set implementation + * This takes into account loops and duplication. + */ +export const getLeafSetImplementations = ( + operationSetImplementation: OperationSetImplementation, +): SetImplementation[] => + getAllChildSetImplementations(operationSetImplementation).filter( + (child) => !(child instanceof OperationSetImplementation), + ); + +export const getObjectInputType = (type: string): ObjectInputType => { + switch (type) { + case ObjectInputType.JSON: + return ObjectInputType.JSON; + case ObjectInputType.XML: + return ObjectInputType.XML; + default: + throw new UnsupportedOperationError( + `Encountered unsupported object input type '${type}'`, + ); + } +}; + +// ----------------------------------------- Runtime ----------------------------------------- + +export const getAllIdentifiedConnections = ( + runtime: EngineRuntime, +): IdentifiedConnection[] => + runtime.connections.flatMap( + (storeConnections) => storeConnections.storeConnections, + ); + +export const generateIdentifiedConnectionId = ( + runtime: EngineRuntime, +): string => { + const generatedId = generateEnumerableNameFromToken( + getAllIdentifiedConnections(runtime).map( + (identifiedConnection) => identifiedConnection.id, + ), + 'connection', + ); + assertTrue( + !getAllIdentifiedConnections(runtime).find( + (identifiedConnection) => identifiedConnection.id === generatedId, + ), + `Can't auto-generate connection ID with value '${generatedId}'`, + ); + return generatedId; +}; diff --git a/packages/legend-graph/src/helpers/ServiceHelper.ts b/packages/legend-graph/src/helpers/DSLService_Helper.ts similarity index 99% rename from packages/legend-graph/src/helpers/ServiceHelper.ts rename to packages/legend-graph/src/helpers/DSLService_Helper.ts index 6470a754108..4ed645afbef 100644 --- a/packages/legend-graph/src/helpers/ServiceHelper.ts +++ b/packages/legend-graph/src/helpers/DSLService_Helper.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { addUniqueEntry } from '@finos/legend-shared'; import { type ValidationIssue, diff --git a/packages/legend-graph/src/helpers/DatabaseHelper.ts b/packages/legend-graph/src/helpers/DatabaseHelper.ts deleted file mode 100644 index 98f7f604cb3..00000000000 --- a/packages/legend-graph/src/helpers/DatabaseHelper.ts +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright (c) 2020-present, Goldman Sachs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { guaranteeType } from '@finos/legend-shared'; -import { Database } from '../models/metamodels/pure/packageableElements/store/relational/model/Database'; -import type { Filter } from '../models/metamodels/pure/packageableElements/store/relational/model/Filter'; -import type { Schema } from '../models/metamodels/pure/packageableElements/store/relational/model/Schema'; -import type { Table } from '../models/metamodels/pure/packageableElements/store/relational/model/Table'; - -const collectIncludedDBs = ( - results: Set, - databases: Database[], -): void => { - databases.forEach((i) => { - const includedDb = guaranteeType(i, Database); - if (!results.has(includedDb)) { - results.add(includedDb); - collectIncludedDBs( - results, - includedDb.includes.map((s) => guaranteeType(s.value, Database)), - ); - } - }); -}; - -export const getAllIncludedDbs = (db: Database): Set => { - const includes = db.includes; - const results = new Set(); - results.add(db); - if (!includes.length) { - return results; - } - collectIncludedDBs( - results, - db.includes.map((includedStore) => - guaranteeType(includedStore.value, Database), - ), - ); - return results; -}; - -export const getDbNullableSchema = ( - name: string, - db: Database, -): Schema | undefined => db.schemas.find((schema) => schema.name === name); - -export const getSchemaNullableTable = ( - name: string, - schema: Schema, -): Table | undefined => schema.tables.find((table) => table.name === name); - -export const getDatabaseNullableFilter = ( - filterName: string, - db: Database, -): Filter | undefined => - db.filters.find((filter) => filter.name === filterName); - -export const getDbNullableTable = ( - _table: string, - _schema: string, - db: Database, -): Table | undefined => { - const schema = getDbNullableSchema(_schema, db); - if (schema) { - return getSchemaNullableTable(_table, schema); - } - return undefined; -}; diff --git a/packages/legend-graph/src/helpers/DomainHelper.ts b/packages/legend-graph/src/helpers/DomainHelper.ts index a3ed9c281df..20ba66c9765 100644 --- a/packages/legend-graph/src/helpers/DomainHelper.ts +++ b/packages/legend-graph/src/helpers/DomainHelper.ts @@ -21,24 +21,42 @@ import { ELEMENT_PATH_DELIMITER, RESERVERD_PACKAGE_NAMES, MILESTONING_STEREOTYPE, + PRIMITIVE_TYPE, } from '../MetaModelConst'; -import { Profile } from '../models/metamodels/pure/packageableElements/domain/Profile'; -import { Tag } from '../models/metamodels/pure/packageableElements/domain/Tag'; -import { Enum } from '../models/metamodels/pure/packageableElements/domain/Enum'; -import { Stereotype } from '../models/metamodels/pure/packageableElements/domain/Stereotype'; -import { TaggedValue } from '../models/metamodels/pure/packageableElements/domain/TaggedValue'; -import { TagExplicitReference } from '../models/metamodels/pure/packageableElements/domain/TagReference'; -import type { Enumeration } from '../models/metamodels/pure/packageableElements/domain/Enumeration'; import { Package } from '../models/metamodels/pure/packageableElements/domain/Package'; import type { PackageableElement } from '../models/metamodels/pure/packageableElements/PackageableElement'; import { + type Clazz, AssertionError, assertNonEmptyString, assertTrue, + guaranteeNonNullable, guaranteeType, + uniqBy, + UnsupportedOperationError, } from '@finos/legend-shared'; import { createPath } from '../MetaModelUtils'; import type { BasicModel } from '../graph/BasicModel'; +import type { Profile } from '../models/metamodels/pure/packageableElements/domain/Profile'; +import type { Tag } from '../models/metamodels/pure/packageableElements/domain/Tag'; +import type { Stereotype } from '../models/metamodels/pure/packageableElements/domain/Stereotype'; +import type { Type } from '../models/metamodels/pure/packageableElements/domain/Type'; +import { + Measure, + Unit, +} from '../models/metamodels/pure/packageableElements/domain/Measure'; +import { Enumeration } from '../models/metamodels/pure/packageableElements/domain/Enumeration'; +import { PrimitiveType } from '../models/metamodels/pure/packageableElements/domain/PrimitiveType'; +import { Property } from '../models/metamodels/pure/packageableElements/domain/Property'; +import type { Association } from '../models/metamodels/pure/packageableElements/domain/Association'; +import type { + AbstractProperty, + PropertyOwner, +} from '../models/metamodels/pure/packageableElements/domain/AbstractProperty'; +import { DerivedProperty } from '../models/metamodels/pure/packageableElements/domain/DerivedProperty'; +import type { Enum } from '../models/metamodels/pure/packageableElements/domain/Enum'; +import type { Constraint } from '../models/metamodels/pure/packageableElements/domain/Constraint'; +import type { GenericType } from '../models/metamodels/pure/packageableElements/domain/GenericType'; export const addElementToPackage = ( parent: Package, @@ -108,7 +126,7 @@ const _getOrCreatePackage = ( // populate cache after resolving the package if (cache) { - cache.set(createPath(parentPackage.fullPath, packageName), pkg); + cache.set(createPath(parentPackage.path, packageName), pkg); } // traverse the package chain @@ -134,7 +152,7 @@ export const getOrCreatePackage = ( if (cache) { // short-circuit const cachedPackage = cache.get( - createPath(parentPackage.fullPath, relativePackagePath), + createPath(parentPackage.path, relativePackagePath), ); if (cachedPackage) { return cachedPackage; @@ -145,7 +163,7 @@ export const getOrCreatePackage = ( let immediateParentPackageRelativePath = relativePackagePath; while (immediateParentPackageRelativePath !== '') { const fullPath = createPath( - parentPackage.fullPath, + parentPackage.path, immediateParentPackageRelativePath, ); const cachedParentPackage = cache.get(fullPath); @@ -188,15 +206,20 @@ export const getOrCreateGraphPackage = ( return getOrCreatePackage(graph.root, packagePath, true, cache); }; -export const createStubTag = (profile: Profile): Tag => new Tag(profile, ''); -export const createStubTaggedValue = (tag: Tag): TaggedValue => - new TaggedValue(TagExplicitReference.create(tag), ''); -export const createStubStereotype = (profile: Profile): Stereotype => - new Stereotype(profile, ''); -export const createStubProfile = (): Profile => new Profile(''); -export const createStubEnum = (enumeration: Enumeration): Enum => - new Enum('', enumeration); +export const getRawGenericType = ( + genericType: GenericType, + clazz: Clazz, +): T => guaranteeType(genericType.rawType, clazz); +/** + * Extract the type of temporal milestone the class is associated with (using stereotype). + * + * Whatever the type, it means the class is milestoned, which means: + * 1. properties of this type will now be considered milestoned, and will be automatically + * converted into a derived property which accept some temporal parameters (depending + * on the milestoning type) + * 2. when we query properties of this type, we can provide the values for these parameters + */ export const getMilestoneTemporalStereotype = ( val: Class, graph: PureModel, @@ -228,3 +251,248 @@ export const getMilestoneTemporalStereotype = ( }); return stereotype; }; + +export const getTag = (profile: Profile, value: string): Tag => + guaranteeNonNullable( + profile.tags.find((tag) => tag.value === value), + `Can't find tag '${value}' in profile '${profile.path}'`, + ); + +export const getStereotype = (profile: Profile, value: string): Stereotype => + guaranteeNonNullable( + profile.stereotypes.find((stereotype) => stereotype.value === value), + `Can't find stereotype '${value}' in profile '${profile.path}'`, + ); + +export const getEnumValueNames = (enumeration: Enumeration): string[] => + enumeration.values.map((value) => value.name).filter(Boolean); + +export const getEnumValue = (enumeration: Enumeration, name: string): Enum => + guaranteeNonNullable( + enumeration.values.find((value) => value.name === name), + `Can't find enum value '${name}' in enumeration '${enumeration.path}'`, + ); + +export const getFirstAssociatedProperty = ( + association: Association, +): Property => guaranteeNonNullable(association.properties[0]); + +export const getSecondAssociatedProperty = ( + association: Association, +): Property => guaranteeNonNullable(association.properties[1]); + +export const getOtherAssociatedProperty = ( + association: Association, + property: Property, +): Property => { + const idx = association.properties.findIndex((p) => p === property); + assertTrue( + idx !== -1, + `Can't find property '${property.name}' in association '${association.path}'`, + ); + return guaranteeNonNullable(association.properties[(idx + 1) % 2]); +}; + +export const getAssociatedPropertyClass = ( + association: Association, + property: AbstractProperty, +): Class => { + if (property instanceof Property) { + return guaranteeType( + getOtherAssociatedProperty(association, property).genericType + .ownerReference.value, + Class, + `Association property '${property.name}' must be of type 'class'`, + ); + } else if (property instanceof DerivedProperty) { + throw new UnsupportedOperationError( + `Derived property is not currently supported in association`, + ); + } + throw new UnsupportedOperationError( + `Can't get associated class of property`, + property, + ); +}; + +export const getOwnProperty = ( + propertyOwner: PropertyOwner, + name: string, +): Property => + guaranteeNonNullable( + propertyOwner.properties.find((property) => property.name === name), + `Can't find property '${name}' in owner '${propertyOwner.path}'`, + ); + +/** + * Get all super types of a class, accounted for loop and duplication (which should be caught by compiler) + * NOTE: we intentionally leave out `Any` + */ +export const getAllSuperclasses = (c: Class): Class[] => { + const visitedClasses = new Set(); + visitedClasses.add(c); + const resolveSuperTypes = (_class: Class): void => { + _class.generalizations.forEach((gen) => { + const superType = getRawGenericType(gen.value, Class); + if (!visitedClasses.has(superType)) { + visitedClasses.add(superType); + resolveSuperTypes(superType); + } + }); + }; + resolveSuperTypes(c); + visitedClasses.delete(c); + return Array.from(visitedClasses); +}; + +/** + * Get all subclasses of a class, accounted for loop and duplication (which should be caught by compiler) + * NOTE: we intentionally leave out `Any` + */ +export const getAllSubclasses = (c: Class): Class[] => { + const visitedClasses = new Set(); + visitedClasses.add(c); + const resolveSubclasses = (_class: Class): void => { + _class._subclasses.forEach((subclass) => { + if (!visitedClasses.has(subclass)) { + visitedClasses.add(subclass); + resolveSubclasses(subclass); + } + }); + }; + resolveSubclasses(c); + visitedClasses.delete(c); + return Array.from(visitedClasses); +}; + +/** + * Get class and its supertypes' properties recursively, duplications and loops are handled (Which should be caught by compiler) + */ +export const getAllClassProperties = (_class: Class): Property[] => + uniqBy( + getAllSuperclasses(_class) + .concat(_class) + .map((c) => c.propertiesFromAssociations.concat(c.properties)) + .flat(), + (property) => property.name, + ); + +export const getAllClassDerivedProperties = ( + _class: Class, +): DerivedProperty[] => + uniqBy( + getAllSuperclasses(_class) + .concat(_class) + .map((c) => c.derivedProperties) + .flat(), + (property) => property.name, + ); + +export const getClassProperty = (_class: Class, name: string): Property => + guaranteeNonNullable( + getAllClassProperties(_class).find((property) => property.name === name), + `Can't find property '${name}' in class '${_class.path}'`, + ); + +export const getAllOwnClassProperties = (_class: Class): AbstractProperty[] => + _class.properties + .concat(_class.propertiesFromAssociations) + .concat(_class.derivedProperties); + +export const getOwnClassProperty = ( + _class: Class, + name: string, +): AbstractProperty => + guaranteeNonNullable( + getAllOwnClassProperties(_class).find((property) => property.name === name), + `Can't find property '${name}' in class '${_class.path}'`, + ); + +export const getAllClassConstraints = (_class: Class): Constraint[] => + // Perhaps we don't need to care about deduping constraints here like for properties + getAllSuperclasses(_class) + .concat(_class) + .map((c) => c.constraints) + .flat(); + +/** + * Check if the first type subtype of the second type + * + * NOTE: Use this for contravariant and covariant check + * See https://www.originate.com/cheat-codes-for-contravariance-and-covariance + * See https://en.wikipedia.org/wiki/Covariance_and_contravariance_of_vectors + */ +export const isSubType = (type1: Type, type2: Type): boolean => { + if (type1 instanceof Unit) { + return type1.measure === type2; + } else if (type1 instanceof Measure) { + return false; + } else if (type1 instanceof Enumeration) { + return false; + } else if (type1 instanceof PrimitiveType) { + if (!(type2 instanceof PrimitiveType)) { + return false; + } + if (type2.name === PRIMITIVE_TYPE.NUMBER) { + return ( + type1.name === PRIMITIVE_TYPE.INTEGER || + type1.name === PRIMITIVE_TYPE.FLOAT || + type1.name === PRIMITIVE_TYPE.DECIMAL + ); + } + if (type2.name === PRIMITIVE_TYPE.DATE) { + return ( + type1.name === PRIMITIVE_TYPE.STRICTDATE || + type1.name === PRIMITIVE_TYPE.DATETIME || + type1.name === PRIMITIVE_TYPE.LATESTDATE + ); + } + } else if (type1 instanceof Class) { + return ( + type1.path === CORE_PURE_PATH.ANY || + (type2 instanceof Class && getAllSuperclasses(type2).includes(type1)) + ); + } + return false; +}; + +/** + * Check if the first type supertype of the second type + * + * NOTE: Use this for contravariant and covariant check + * See https://www.originate.com/cheat-codes-for-contravariance-and-covariance + * See https://en.wikipedia.org/wiki/Covariance_and_contravariance_of_vectors + */ +export const isSuperType = (type1: Type, type2: Type): boolean => { + if (type1 instanceof Unit) { + return false; + } else if (type1 instanceof Measure) { + return type2 instanceof Unit && type2.measure === type1; + } else if (type1 instanceof Enumeration) { + return false; + } else if (type1 instanceof PrimitiveType) { + if (!(type2 instanceof PrimitiveType)) { + return false; + } + if (type1.name === PRIMITIVE_TYPE.NUMBER) { + return ( + type2.name === PRIMITIVE_TYPE.INTEGER || + type2.name === PRIMITIVE_TYPE.FLOAT || + type2.name === PRIMITIVE_TYPE.DECIMAL + ); + } + if (type1.name === PRIMITIVE_TYPE.DATE) { + return ( + type2.name === PRIMITIVE_TYPE.STRICTDATE || + type2.name === PRIMITIVE_TYPE.DATETIME || + type2.name === PRIMITIVE_TYPE.LATESTDATE + ); + } + } else if (type1 instanceof Class) { + return ( + type2.path === CORE_PURE_PATH.ANY || + (type2 instanceof Class && getAllSubclasses(type2).includes(type1)) + ); + } + return false; +}; diff --git a/packages/legend-graph/src/helpers/PureLanguageHelper.ts b/packages/legend-graph/src/helpers/PureLanguageHelper.ts index 1b04ad04a10..1f691896841 100644 --- a/packages/legend-graph/src/helpers/PureLanguageHelper.ts +++ b/packages/legend-graph/src/helpers/PureLanguageHelper.ts @@ -14,7 +14,11 @@ * limitations under the License. */ -import { PRIMITIVE_TYPE } from '../MetaModelConst'; +import { + MULTIPLICITY_INFINITE, + MULTIPLICITY_RANGE_OPERATOR, + PRIMITIVE_TYPE, +} from '../MetaModelConst'; import type { ConcreteFunctionDefinition } from '../models/metamodels/pure/packageableElements/domain/ConcreteFunctionDefinition'; import type { Type } from '../models/metamodels/pure/packageableElements/domain/Type'; import { PrimitiveType } from '../models/metamodels/pure/packageableElements/domain/PrimitiveType'; @@ -60,6 +64,20 @@ export enum PURE_PARSER { DATA = 'Data', } +export const generateMultiplicityString = ( + lowerBound: number, + upperBound: number | undefined, +): string => { + if (lowerBound === upperBound) { + return lowerBound.toString(); + } else if (lowerBound === 0 && upperBound === undefined) { + return MULTIPLICITY_INFINITE; + } + return `${lowerBound}${MULTIPLICITY_RANGE_OPERATOR}${ + upperBound ?? MULTIPLICITY_INFINITE + }`; +}; + export const generateDefaultParameterValueForType = ( type: Type | undefined, index: number, @@ -120,6 +138,15 @@ export const generateFunctionSignature = ( fullPath: boolean, ): string => `${fullPath ? element.path : element.name}(${element.parameters - .map((p) => `${p.name}: ${p.type.value.name}[${p.multiplicity.str}]`) + .map( + (p) => + `${p.name}: ${p.type.value.name}[${generateMultiplicityString( + p.multiplicity.lowerBound, + p.multiplicity.upperBound, + )}]`, + ) .join(', ')})` + - `: ${element.returnType.value.name}[${element.returnMultiplicity.str}]`; + `: ${element.returnType.value.name}[${generateMultiplicityString( + element.returnMultiplicity.lowerBound, + element.returnMultiplicity.upperBound, + )}]`; diff --git a/packages/legend-graph/src/helpers/StoreFlatData_Helper.ts b/packages/legend-graph/src/helpers/StoreFlatData_Helper.ts new file mode 100644 index 00000000000..4f8c673e259 --- /dev/null +++ b/packages/legend-graph/src/helpers/StoreFlatData_Helper.ts @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2020-present, Goldman Sachs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { guaranteeNonNullable } from '@finos/legend-shared'; +import type { FlatData } from '../models/metamodels/pure/packageableElements/store/flatData/model/FlatData'; +import type { RootFlatDataRecordType } from '../models/metamodels/pure/packageableElements/store/flatData/model/FlatDataDataType'; +import type { FlatDataSection } from '../models/metamodels/pure/packageableElements/store/flatData/model/FlatDataSection'; + +export const getRootRecordType = ( + section: FlatDataSection, +): RootFlatDataRecordType => + guaranteeNonNullable( + section.recordType, + `No record type defined in section '${section.name}' of flat-data store '${section._OWNER.path}'`, + ); + +export const getSection = (flatData: FlatData, name: string): FlatDataSection => + guaranteeNonNullable( + flatData.sections.find((section) => section.name === name), + `Can't find section '${name}' in flat-data store '${flatData.path}'`, + ); + +export const getAllRecordTypes = ( + flatData: FlatData, +): RootFlatDataRecordType[] => + flatData.sections.flatMap((section) => + section.recordType ? [section.recordType] : [], + ); diff --git a/packages/legend-graph/src/helpers/StoreRelational_Helper.ts b/packages/legend-graph/src/helpers/StoreRelational_Helper.ts new file mode 100644 index 00000000000..293d1cdbcb3 --- /dev/null +++ b/packages/legend-graph/src/helpers/StoreRelational_Helper.ts @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2020-present, Goldman Sachs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + filterByType, + guaranteeNonNullable, + guaranteeType, + UnsupportedOperationError, +} from '@finos/legend-shared'; +import { RelationalInputType } from '../models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInputData'; +import { Column } from '../models/metamodels/pure/packageableElements/store/relational/model/Column'; +import { Database } from '../models/metamodels/pure/packageableElements/store/relational/model/Database'; +import type { Filter } from '../models/metamodels/pure/packageableElements/store/relational/model/Filter'; +import type { Join } from '../models/metamodels/pure/packageableElements/store/relational/model/Join'; +import { + JoinType, + type Relation, +} from '../models/metamodels/pure/packageableElements/store/relational/model/RelationalOperationElement'; +import type { Schema } from '../models/metamodels/pure/packageableElements/store/relational/model/Schema'; +import type { Table } from '../models/metamodels/pure/packageableElements/store/relational/model/Table'; +import type { View } from '../models/metamodels/pure/packageableElements/store/relational/model/View'; + +const collectIncludedDatabases = ( + results: Set, + databases: Database[], +): void => { + databases.forEach((i) => { + const includedDb = guaranteeType(i, Database); + if (!results.has(includedDb)) { + results.add(includedDb); + collectIncludedDatabases( + results, + includedDb.includes.map((s) => guaranteeType(s.value, Database)), + ); + } + }); +}; + +export const getAllIncludedDatabases = (db: Database): Set => { + const includes = db.includes; + const results = new Set(); + results.add(db); + if (!includes.length) { + return results; + } + collectIncludedDatabases( + results, + db.includes.map((includedStore) => + guaranteeType(includedStore.value, Database), + ), + ); + return results; +}; + +export const getJoinType = (type: string): JoinType => { + switch (type) { + case JoinType.INNER: + return JoinType.INNER; + case JoinType.LEFT_OUTER: + return JoinType.LEFT_OUTER; + case JoinType.RIGHT_OUTER: + return JoinType.RIGHT_OUTER; + default: + throw new UnsupportedOperationError( + `Encountered unsupported join type '${type}'`, + ); + } +}; + +export const getRelationalInputType = (type: string): RelationalInputType => { + switch (type) { + case RelationalInputType.SQL: + return RelationalInputType.SQL; + case RelationalInputType.CSV: + return RelationalInputType.CSV; + default: + throw new UnsupportedOperationError( + `Encountered unsupported relational input type '${type}'`, + ); + } +}; + +export const getNullableSchema = ( + database: Database, + name: string, +): Schema | undefined => + database.schemas.find((schema) => schema.name === name); + +export const getNullableFilter = ( + database: Database, + name: string, +): Filter | undefined => + database.filters.find((filter) => filter.name === name); + +export const getSchema = (database: Database, name: string): Schema => + guaranteeNonNullable( + getNullableSchema(database, name), + `Can't find schema '${name}' in database '${database.path}'`, + ); + +export const getJoin = (database: Database, name: string): Join => + guaranteeNonNullable( + Array.from(getAllIncludedDatabases(database)) + .flatMap((includedDB) => includedDB.joins) + .find((join) => join.name === name), + `Can't find join '${name}' in database '${database.path}'`, + ); + +export const getFilter = (database: Database, name: string): Filter => + guaranteeNonNullable( + getNullableFilter(database, name), + `Can't find filter '${name}' in database '${database.path}'`, + ); + +export const getNullableTable = ( + schema: Schema, + name: string, +): Table | undefined => schema.tables.find((table) => table.name === name); + +export const getTable = (schema: Schema, name: string): Table => + guaranteeNonNullable( + getNullableTable(schema, name), + `Can't find table '${name}' in schema '${schema.name}' of database '${schema._OWNER.path}'`, + ); + +export const getView = (schema: Schema, name: string): View => + guaranteeNonNullable( + schema.views.find((view) => view.name === name), + `Can't find view '${name}' in schema '${schema.name}' of database '${schema._OWNER.path}'`, + ); + +export const getRelation = (schema: Schema, name: string): Relation => { + const relations: (Table | View)[] = schema.tables; + return guaranteeNonNullable( + relations.concat(schema.views).find((relation) => relation.name === name), + `Can't find relation '${name}' in schema '${schema.name}' of database '${schema._OWNER.path}'`, + ); +}; + +export const getColumn = (relation: Table | View, name: string): Column => + guaranteeNonNullable( + relation.columns + .filter(filterByType(Column)) + .find((column) => column.name === name), + `Can't find column '${name}' in table '${relation.name}'`, + ); diff --git a/packages/legend-graph/src/helpers/Stubable.ts b/packages/legend-graph/src/helpers/Stubable.ts deleted file mode 100644 index 27c71af40b9..00000000000 --- a/packages/legend-graph/src/helpers/Stubable.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) 2020-present, Goldman Sachs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * TODO: we plan to deprecate this as it is unecessary and makes metamodel more heavy, while it's purely an UI state - * @deprecated - * The UI has the need to create stub elements for example Class needs to be able to create empty Constraint - * or Class Mapping needs blank Property Mapping. In these cases, we want to be able to discern these stubs - * and omit them from let's say transformer or hash computation - */ -export interface Stubable { - isStub: boolean; -} - -/** - * TODO: we plan to deprecate the whole Stubable mechanism - * @deprecated - */ -export const isStubArray = (arr: Stubable[]): boolean => - !arr.filter((p) => !p.isStub).length; diff --git a/packages/legend-graph/src/helpers/Testable_Helper.ts b/packages/legend-graph/src/helpers/Testable_Helper.ts new file mode 100644 index 00000000000..78f0e0eb7e2 --- /dev/null +++ b/packages/legend-graph/src/helpers/Testable_Helper.ts @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2020-present, Goldman Sachs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { isNonNullable } from '@finos/legend-shared'; +import type { PureModel } from '../graph/PureModel'; +import type { PureGraphManagerPlugin } from '../graphManager/PureGraphManagerPlugin'; +import { PackageableElement } from '../models/metamodels/pure/packageableElements/PackageableElement'; +import type { Testable } from '../models/metamodels/pure/test/Testable'; + +export const getNullableTestable = ( + id: string, + graph: PureModel, + plugins: PureGraphManagerPlugin[], +): Testable | undefined => + graph.allOwnTestables.find( + (e) => e instanceof PackageableElement && e.path === id, + ) ?? + plugins + .flatMap((plugin) => plugin.getExtraTestableFinders?.() ?? []) + .map((getter) => getter(id, graph)) + .filter(isNonNullable)[0]; + +export const getNullableIDFromTestable = ( + testable: Testable, + graph: PureModel, + plugins: PureGraphManagerPlugin[], +): string | undefined => { + if (testable instanceof PackageableElement) { + return testable.path; + } + return plugins + .flatMap((plugin) => plugin.getExtraTestableIDBuilders?.() ?? []) + .map((getter) => getter(testable, graph)) + .filter(isNonNullable)[0]; +}; diff --git a/packages/legend-graph/src/index.ts b/packages/legend-graph/src/index.ts index 6045e0cdee4..142e85fca70 100644 --- a/packages/legend-graph/src/index.ts +++ b/packages/legend-graph/src/index.ts @@ -157,12 +157,15 @@ export { TDSResultType } from './models/metamodels/pure/executionPlan/result/TDS export * from './MetaModelUtils'; export * from './MetaModelConst'; -export * from './helpers/ServiceHelper'; -export * from './helpers/DatabaseHelper'; -export * from './helpers/MappingHelper'; -export * from './helpers/ValidationHelper'; -export * from './helpers/Stubable'; // TODO: to be removed export * from './helpers/DomainHelper'; +export * from './helpers/Testable_Helper'; +export * from './helpers/DSLMapping_Helper'; +export * from './helpers/StoreRelational_Helper'; +export * from './helpers/StoreFlatData_Helper'; +export * from './helpers/DSLService_Helper'; +export * from './helpers/DSLGeneration_Helper'; + +export * from './helpers/ValidationHelper'; export * from './helpers/PureLanguageHelper'; // --------------------------------------------- GRAPH -------------------------------------------------- @@ -307,6 +310,13 @@ export * from './graphManager/action/changeDetection/DSLGenerationSpecification_ export * from './graphManager/action/changeDetection/EngineObserverHelper'; +// --------------------------------------------- CREATOR -------------------------------------------------- + +export * from './graphManager/action/creation/DomainModelCreatorHelper'; +export * from './graphManager/action/creation/DSLMapping_ModelCreatorHelper'; +export * from './graphManager/action/creation/RawValueSpecificationCreatorHelper'; +export * from './graphManager/action/creation/StoreRelational_ModelCreatorHelper'; + // --------------------------------------------- TO BE MODULARIZED -------------------------------------------------- export * from './DSLMapping_Exports'; diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/PackageableElement.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/PackageableElement.ts index c1be49f74e8..170b1c9ae2a 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/PackageableElement.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/PackageableElement.ts @@ -17,7 +17,6 @@ import { type Hashable, hashArray, - hashString, IllegalStateError, uuid, } from '@finos/legend-shared'; @@ -26,7 +25,6 @@ import { ELEMENT_PATH_DELIMITER, } from '../../../../MetaModelConst'; import type { Package } from './domain/Package'; -import type { Stubable } from '../../../../helpers/Stubable'; import type { Profile } from './domain/Profile'; import type { Enumeration } from './domain/Enumeration'; import type { Class } from './domain/Class'; @@ -68,7 +66,7 @@ export interface PackageableElementVisitor { visit_DataElement(element: DataElement): T; } -export abstract class PackageableElement implements Hashable, Stubable { +export abstract class PackageableElement implements Hashable { readonly _UUID = uuid(); protected _isDeleted = false; protected _isDisposed = false; @@ -80,30 +78,53 @@ export abstract class PackageableElement implements Hashable, Stubable { this.name = name; } + /** + * This logic is specific to the codebase and this is not part of the native metamodel. + * If needed, we can probably move this out as an utility or do type declaration merge + * and define this externally using `Object.defineProperty`. + * + * @internal model logic + */ get isDeleted(): boolean { return this._isDeleted; } + /** + * This logic is specific to the codebase and this is not part of the native metamodel. + * If needed, we can probably move this out as an utility or do type declaration merge + * and define this externally using `Object.defineProperty`. + * + * @internal model logic + */ setIsDeleted(value: boolean): void { this._isDeleted = value; } + /** + * This logic is specific to the codebase and this is not part of the native metamodel. + * If needed, we can probably move this out as an utility or do type declaration merge + * and define this externally using `Object.defineProperty`. + * + * @internal model logic + */ get path(): string { if (!this.package) { return this.name; } - const parentPackageName = this.package.fullPath; - return !parentPackageName + const parentPackagePath = this.package.path; + return !parentPackagePath ? this.name - : `${parentPackageName}${ELEMENT_PATH_DELIMITER}${this.name}`; - } - - get isStub(): boolean { - return !this.name && !this.package; + : `${parentPackagePath}${ELEMENT_PATH_DELIMITER}${this.name}`; } /** - * Dispose the element and its references to avoid memory leaks + * Dispose the element and its references to avoid memory leaks. + * + * This logic is specific to the codebase and this is not part of the native metamodel. + * If needed, we can probably move this out as an utility or do type declaration merge + * and define this externally using `Object.defineProperty`. + * + * @internal model logic */ dispose(): void { this._isDisposed = true; @@ -140,11 +161,3 @@ export abstract class PackageableElement implements Hashable, Stubable { visitor: PackageableElementVisitor, ): T; } - -export const getElementPointerHashCode = ( - pointerType: string, - path: string, -): string => - [CORE_HASH_STRUCTURE.PACKAGEABLE_ELEMENT_POINTER, pointerType, path] - .map(hashString) - .join(','); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/AbstractProperty.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/AbstractProperty.ts index 43a17067022..3cdcdc926e7 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/AbstractProperty.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/AbstractProperty.ts @@ -17,16 +17,16 @@ import type { Hashable } from '@finos/legend-shared'; import type { GenericTypeReference } from './GenericTypeReference'; import type { Multiplicity } from './Multiplicity'; -import type { Stubable } from '../../../../../helpers/Stubable'; import type { Class } from './Class'; import type { Association } from './Association'; // NOTE: In PURE we have `Class` and `Association` extends `PropertyOwner`, which extends `PackageableElement` export type PropertyOwner = Class | Association; -export interface AbstractProperty extends Hashable, Stubable { - name: string; +export interface AbstractProperty extends Hashable { _OWNER: PropertyOwner; + + name: string; genericType: GenericTypeReference; multiplicity: Multiplicity; } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Association.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Association.ts index ba0ee4f4dc7..bc2bfa7ac4c 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Association.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Association.ts @@ -14,28 +14,22 @@ * limitations under the License. */ -import { - type Hashable, - type Writable, - guaranteeNonNullable, - guaranteeType, - assertTrue, - UnsupportedOperationError, - hashArray, -} from '@finos/legend-shared'; +import { type Hashable, type Writable, hashArray } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import { type PackageableElementVisitor, PackageableElement, } from '../PackageableElement'; -import { Property } from './Property'; -import { type Stubable, isStubArray } from '../../../../../helpers/Stubable'; -import { Class } from './Class'; +import type { Property } from './Property'; import type { AnnotatedElement } from './AnnotatedElement'; import type { TaggedValue } from './TaggedValue'; import type { StereotypeReference } from './StereotypeReference'; -import { DerivedProperty } from './DerivedProperty'; +import type { DerivedProperty } from './DerivedProperty'; import type { AbstractProperty } from './AbstractProperty'; +import { + stub_Class, + stub_Property, +} from '../../../../../graphManager/action/creation/DomainModelCreatorHelper'; /** * Assocation needs exactly 2 properties (for 2 classes, not enumeration, not primitive), e.g. @@ -50,16 +44,19 @@ import type { AbstractProperty } from './AbstractProperty'; * or project dependencies. As such, in the app, we have to make it very clear that we prohibits this. * * TODO: We probably should change backend to do compilation check whether association refers - * to a class from a different project. Here, while building the graph, we can make use of the + * to a class from a different projects. Here, while building the graph, we can make use of the * root package to verify this in the UI and make this a validation error in a way. + * See https://github.com/finos/legend-studio/issues/282 */ export class Association extends PackageableElement - implements AnnotatedElement, Hashable, Stubable + implements AnnotatedElement, Hashable { /** * To store the abstract properties generated while processing the milestoning properties. The properties * generated are `allVersions`, `allVersionsInRange` and derived property with date parameter. + * + * TODO: process new property added while editing the graph */ _generatedMilestonedProperties: AbstractProperty[] = []; @@ -73,52 +70,14 @@ export class Association // NOTE: we might want to revisit this decision to initialize to association properties to stubs const properties: [Property, Property] = [ - Property.createStub(Class.createStub(), Class.createStub()), - Property.createStub(Class.createStub(), Class.createStub()), + stub_Property(stub_Class(), stub_Class()), + stub_Property(stub_Class(), stub_Class()), ]; (properties[0] as Writable)._OWNER = this; (properties[1] as Writable)._OWNER = this; this.properties = properties; } - getFirstProperty = (): Property => guaranteeNonNullable(this.properties[0]); - getSecondProperty = (): Property => guaranteeNonNullable(this.properties[1]); - getOtherProperty = (property: Property): Property => { - const idx = this.properties.findIndex((p) => p === property); - assertTrue( - idx !== -1, - `Can't find property '${property.name}' in association '${this.path}'`, - ); - return guaranteeNonNullable(this.properties[(idx + 1) % 2]); - }; - getPropertyAssociatedClass = (property: AbstractProperty): Class => { - if (property instanceof Property) { - return guaranteeType( - this.getOtherProperty(property).genericType.ownerReference.value, - Class, - `Association property '${property.name}' must be of type 'class'`, - ); - } else if (property instanceof DerivedProperty) { - throw new UnsupportedOperationError( - `Derived property is not currently supported in association`, - ); - } - throw new UnsupportedOperationError( - `Can't get associated class of property`, - property, - ); - }; - - getProperty = (name: string): Property => - guaranteeNonNullable( - this.properties.find((p) => p.name === name), - `Can't find property '${name}' in class '${this.path}'`, - ); - - override get isStub(): boolean { - return super.isStub && isStubArray(this.properties); - } - protected override get _elementHashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.ASSOCIATION, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Class.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Class.ts index 82ec612bda5..57e5c187b6d 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Class.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Class.ts @@ -14,34 +14,19 @@ * limitations under the License. */ -import { - type Hashable, - hashArray, - uniqBy, - IllegalStateError, - guaranteeNonNullable, -} from '@finos/legend-shared'; -import { - CORE_HASH_STRUCTURE, - CORE_PURE_PATH, -} from '../../../../../MetaModelConst'; +import { type Hashable, hashArray } from '@finos/legend-shared'; +import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import { Type } from './Type'; import type { Property } from './Property'; import type { Constraint } from './Constraint'; import type { DerivedProperty } from './DerivedProperty'; import type { AbstractProperty } from './AbstractProperty'; -import { type Stubable, isStubArray } from '../../../../../helpers/Stubable'; import type { PackageableElementVisitor } from '../PackageableElement'; import type { StereotypeReference } from './StereotypeReference'; import type { TaggedValue } from './TaggedValue'; import type { GenericTypeReference } from './GenericTypeReference'; -export class Class extends Type implements Hashable, Stubable { - properties: Property[] = []; - // derivedPropertiesFromAssociations: DerivedProperty[] = []; - propertiesFromAssociations: Property[] = []; - derivedProperties: DerivedProperty[] = []; - generalizations: GenericTypeReference[] = []; +export class Class extends Type implements Hashable { /** * We can also call this `specifications` (i.e. vs. `generalizations`) * @@ -50,164 +35,47 @@ export class Class extends Type implements Hashable, Stubable { * * @risk memory-leak */ - subclasses: Class[] = []; - constraints: Constraint[] = []; - stereotypes: StereotypeReference[] = []; - taggedValues: TaggedValue[] = []; - + _subclasses: Class[] = []; /** * To store the abstract properties generated while processing the milestoning properties. The properties * generated are `allVersions`, `allVersionsInRange` and derived property with date parameter. + * + * TODO: process new property added while editing the graph */ _generatedMilestonedProperties: AbstractProperty[] = []; - /** - * Get class and its supertypes' properties recursively, duplications and loops are handled (Which should be caught by compiler) - */ - getAllProperties = (): Property[] => - uniqBy( - this.allSuperclasses - .concat(this) - .map((_class) => - _class.propertiesFromAssociations.concat(_class.properties), - ) - .flat(), - (p) => p.name, - ); - - getProperty = (name: string): Property => - guaranteeNonNullable( - this.getAllProperties().find((p) => p.name === name), - `Can't find property '${name}' in class '${this.path}'`, - ); - - getAllDerivedProperties = (): DerivedProperty[] => - uniqBy( - this.allSuperclasses - .concat(this) - .map((_class) => _class.derivedProperties) - .flat(), - (p) => p.name, - ); - - getAllOwnedProperties = (): AbstractProperty[] => - this.properties - .concat(this.propertiesFromAssociations) - .concat(this.derivedProperties); - - getOwnedProperty = (name: string): AbstractProperty => - guaranteeNonNullable( - this.getAllOwnedProperties().find((p) => p.name === name), - `Can't find property '${name}' in class '${this.path}'`, - ); - - // Perhaps we don't need to care about deduping constraints here like for properties - getAllConstraints = (): Constraint[] => - this.allSuperclasses - .concat(this) - .map((_class) => _class.constraints) - .flat(); - - isSuperType(type: Type): boolean { - return ( - type.path === CORE_PURE_PATH.ANY || - (type instanceof Class && type.allSuperclasses.includes(this)) - ); - } - - isSubType(type: Type): boolean { - return ( - this.path === CORE_PURE_PATH.ANY || - (type instanceof Class && type.allSubclasses.includes(this)) - ); - } - - /** - * Get all super types of a class, accounted for loop and duplication (which should be caught by compiler) - * NOTE: we intentionally leave out `Any` - */ - get allSuperclasses(): Class[] { - const visitedClasses = new Set(); - visitedClasses.add(this); - const resolveSuperTypes = (_class: Class): void => { - _class.generalizations.forEach((gen) => { - const superType = gen.value.getRawType(Class); - if (!visitedClasses.has(superType)) { - visitedClasses.add(superType); - resolveSuperTypes(superType); - } - }); - }; - resolveSuperTypes(this); - visitedClasses.delete(this); - return Array.from(visitedClasses); - } - - /** - * Get all subclasses of a class, accounted for loop and duplication (which should be caught by compiler) - * NOTE: we intentionally leave out `Any` - * - * When this is an immutable class such as project dependency or system we need to remember to remove the classes from the sub-types array. - * And rerun this computation to avoid potenial memory leak - * - * @risk memory-leak - */ - get allSubclasses(): Class[] { - if (this._isDisposed) { - throw new IllegalStateError(`Element '${this.path}' is already disposed`); - } - const visitedClasses = new Set(); - visitedClasses.add(this); - const resolveSubclasses = (_class: Class): void => { - if (_class._isDisposed) { - return; - } - _class.subclasses.forEach((subclass) => { - if (!visitedClasses.has(subclass)) { - visitedClasses.add(subclass); - resolveSubclasses(subclass); - } - }); - }; - resolveSubclasses(this); - visitedClasses.delete(this); - return Array.from(visitedClasses); - } + properties: Property[] = []; + propertiesFromAssociations: Property[] = []; + derivedProperties: DerivedProperty[] = []; + // derivedPropertiesFromAssociations: DerivedProperty[] = []; + generalizations: GenericTypeReference[] = []; + constraints: Constraint[] = []; + stereotypes: StereotypeReference[] = []; + taggedValues: TaggedValue[] = []; /** * Make sure to remove the disposed class from being referenced in other elements * e.g. subclass analytics is great, but it causes the class being referred to by classes * coming from system or dependencies + * + * This logic is specific to the codebase and this is not part of the native metamodel. + * If needed, we can probably move this out as an utility or do type declaration merge + * and define this externally using `Object.defineProperty`. + * + * @internal model logic */ override dispose(): void { super.dispose(); - this.subclasses = []; // call this before setting `disposed` flag to avoid triggering errors if something is using this during disposal + this._subclasses = []; // cleanup subclasses analytics on superclasses - this.allSuperclasses.forEach((superclass) => { + this.generalizations.forEach((genericType) => { + const superclass = genericType.value.rawType as Class; if (!superclass._isDisposed) { - superclass.subclasses = superclass.subclasses.filter( + superclass._subclasses = superclass._subclasses.filter( (subclass) => !subclass._isDisposed, ); } }); - try { - this.allSubclasses; - } catch { - /* do nothing */ - } // trigger recomputation on `allSubclasses` so it removes itself from all observables it previously observed - } - - static createStub = (): Class => new Class(''); - override get isStub(): boolean { - return ( - super.isStub && - isStubArray(this.properties) && - isStubArray(this.derivedProperties) && - isStubArray(this.constraints) && - isStubArray(this.generalizations) && - isStubArray(this.stereotypes) && - isStubArray(this.taggedValues) - ); } protected override get _elementHashCode(): string { diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/ConcreteFunctionDefinition.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/ConcreteFunctionDefinition.ts index 13f312186e9..6e522857b03 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/ConcreteFunctionDefinition.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/ConcreteFunctionDefinition.ts @@ -21,7 +21,6 @@ import type { PackageableElementVisitor } from '../PackageableElement'; import type { RawVariableExpression } from '../../rawValueSpecification/RawVariableExpression'; import type { Type } from './Type'; import type { Multiplicity } from './Multiplicity'; -import type { Stubable } from '../../../../../helpers/Stubable'; import type { StereotypeReference } from './StereotypeReference'; import type { TaggedValue } from './TaggedValue'; import type { PackageableElementReference } from '../PackageableElementReference'; @@ -29,7 +28,7 @@ import { FunctionDefinition } from './Function'; export class ConcreteFunctionDefinition extends FunctionDefinition - implements Hashable, Stubable + implements Hashable { returnType: PackageableElementReference; returnMultiplicity: Multiplicity; diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Constraint.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Constraint.ts index 0ab7d7c92eb..69ef4b96a9a 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Constraint.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Constraint.ts @@ -16,11 +16,10 @@ import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import { hashArray, uuid, type Hashable } from '@finos/legend-shared'; -import { RawLambda } from '../../rawValueSpecification/RawLambda'; +import type { RawLambda } from '../../rawValueSpecification/RawLambda'; import type { Class } from './Class'; -import type { Stubable } from '../../../../../helpers/Stubable'; -export class Constraint implements Hashable, Stubable { +export class Constraint implements Hashable { readonly _UUID = uuid(); readonly _OWNER: Class; @@ -46,14 +45,6 @@ export class Constraint implements Hashable, Stubable { this.functionDefinition = functionDefinition; } - static createStub = (_class: Class): Constraint => - new Constraint('', _class, RawLambda.createStub()); - // the constraint is considered stub if it doesn't have a body in the function definition lambda because - // without the function definition, it is not even parsable and so we should not transform this - get isStub(): boolean { - return !this.functionDefinition.body; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.CONSTRAINT, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/DerivedProperty.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/DerivedProperty.ts index a08e4f865cd..58c1c3e696b 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/DerivedProperty.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/DerivedProperty.ts @@ -17,22 +17,15 @@ import { type Hashable, hashArray, uuid } from '@finos/legend-shared'; import { hashLambda } from '../../../../../MetaModelUtils'; import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; -import { Multiplicity } from './Multiplicity'; +import type { Multiplicity } from './Multiplicity'; import type { TaggedValue } from './TaggedValue'; import type { AbstractProperty, PropertyOwner } from './AbstractProperty'; import type { AnnotatedElement } from './AnnotatedElement'; -import { GenericType } from './GenericType'; -import type { Class } from './Class'; -import type { Type } from './Type'; -import type { Stubable } from '../../../../../helpers/Stubable'; import type { StereotypeReference } from './StereotypeReference'; -import { - type GenericTypeReference, - GenericTypeExplicitReference, -} from './GenericTypeReference'; +import type { GenericTypeReference } from './GenericTypeReference'; export class DerivedProperty - implements AbstractProperty, AnnotatedElement, Hashable, Stubable + implements AbstractProperty, AnnotatedElement, Hashable { readonly _UUID = uuid(); readonly _OWNER: PropertyOwner; @@ -66,17 +59,6 @@ export class DerivedProperty this.genericType = genericType; this._OWNER = owner; } - static createStub = (type: Type, _class: Class): DerivedProperty => - new DerivedProperty( - '', - new Multiplicity(1, 1), - GenericTypeExplicitReference.create(new GenericType(type)), - _class, - ); - // the derived property is considered stub if it doesn't have a body in the lambda because without a body, it is not parsable, and should be discarded in transformer - get isStub(): boolean { - return !this.body; - } get hashCode(): string { return hashArray([ diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Enum.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Enum.ts index 5d595eb55cb..eca7187e7dc 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Enum.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Enum.ts @@ -19,10 +19,9 @@ import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import type { Enumeration } from './Enumeration'; import type { TaggedValue } from './TaggedValue'; import type { AnnotatedElement } from './AnnotatedElement'; -import type { Stubable } from '../../../../../helpers/Stubable'; import type { StereotypeReference } from './StereotypeReference'; -export class Enum implements AnnotatedElement, Hashable, Stubable { +export class Enum implements AnnotatedElement, Hashable { readonly _UUID = uuid(); readonly _OWNER: Enumeration; @@ -35,12 +34,6 @@ export class Enum implements AnnotatedElement, Hashable, Stubable { this._OWNER = owner; } - static createStub = (parentEnumeration: Enumeration): Enum => - new Enum('', parentEnumeration); - get isStub(): boolean { - return !this.name; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.ENUM_VALUE, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/EnumValueReference.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/EnumValueReference.ts index e092e07a4e6..632c7d50bd1 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/EnumValueReference.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/EnumValueReference.ts @@ -21,13 +21,9 @@ import { } from '../PackageableElementReference'; import type { Enumeration } from './Enumeration'; import type { Enum } from './Enum'; -import type { Stubable } from '../../../../../helpers/Stubable'; import { ReferenceWithOwner } from '../../Reference'; -export abstract class EnumValueReference - extends ReferenceWithOwner - implements Stubable -{ +export abstract class EnumValueReference extends ReferenceWithOwner { override readonly ownerReference: PackageableElementReference; value: Enum; @@ -39,10 +35,6 @@ export abstract class EnumValueReference this.ownerReference = ownerReference; this.value = value; } - - get isStub(): boolean { - return !this.value.isStub; - } } export class EnumValueExplicitReference extends EnumValueReference { diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Enumeration.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Enumeration.ts index 4632ae60e33..c0479bf6eba 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Enumeration.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Enumeration.ts @@ -14,46 +14,19 @@ * limitations under the License. */ -import { - type Hashable, - hashArray, - guaranteeNonNullable, -} from '@finos/legend-shared'; +import { type Hashable, hashArray } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import { DataType } from './DataType'; import type { Enum } from './Enum'; -import { type Stubable, isStubArray } from '../../../../../helpers/Stubable'; import type { PackageableElementVisitor } from '../PackageableElement'; -import type { Type } from './Type'; import type { StereotypeReference } from './StereotypeReference'; import type { TaggedValue } from './TaggedValue'; -export class Enumeration extends DataType implements Hashable, Stubable { +export class Enumeration extends DataType implements Hashable { values: Enum[] = []; stereotypes: StereotypeReference[] = []; taggedValues: TaggedValue[] = []; - getValueNames = (): string[] => - this.values.map((value) => value.name).filter(Boolean); - getValue = (name: string): Enum => - guaranteeNonNullable( - this.values.find((value) => value.name === name), - `Can't find enum value '${name}' in enumeration '${this.path}'`, - ); - static createStub = (): Enumeration => new Enumeration(''); - - override get isStub(): boolean { - return super.isStub && isStubArray(this.values); - } - - isSuperType(type: Type): boolean { - return false; - } - - isSubType(type: Type): boolean { - return false; - } - protected override get _elementHashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.ENUMERATION, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/GenericType.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/GenericType.ts index 46933736ccd..784bfd345a6 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/GenericType.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/GenericType.ts @@ -14,11 +14,10 @@ * limitations under the License. */ -import { type Clazz, guaranteeType, uuid } from '@finos/legend-shared'; +import { uuid } from '@finos/legend-shared'; import type { Type } from './Type'; -import type { Stubable } from '../../../../../helpers/Stubable'; -export class GenericType implements Stubable { +export class GenericType { readonly _UUID = uuid(); rawType: Type; @@ -26,13 +25,4 @@ export class GenericType implements Stubable { constructor(rawType: Type) { this.rawType = rawType; } - - getRawType = (clazz: Clazz): T => - guaranteeType(this.rawType, clazz); - - // NOTE: we don't have a `createStub` for GenericType because it all depends on the type passed in - // so might as well use constructor - get isStub(): boolean { - return this.rawType.isStub; - } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/GenericTypeReference.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/GenericTypeReference.ts index eb5f4f47005..07c6bbd2743 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/GenericTypeReference.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/GenericTypeReference.ts @@ -19,15 +19,11 @@ import { type PackageableElementReference, type PackageableElementImplicitReference, } from '../PackageableElementReference'; -import type { Stubable } from '../../../../../helpers/Stubable'; import { ReferenceWithOwner } from '../../Reference'; import type { GenericType } from './GenericType'; import type { Type } from './Type'; -export abstract class GenericTypeReference - extends ReferenceWithOwner - implements Stubable -{ +export abstract class GenericTypeReference extends ReferenceWithOwner { override readonly ownerReference: PackageableElementReference; value: GenericType; @@ -40,10 +36,6 @@ export abstract class GenericTypeReference this.ownerReference = ownerReference; this.value = value; } - - get isStub(): boolean { - return !this.value.isStub; - } } export class GenericTypeExplicitReference extends GenericTypeReference { diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Measure.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Measure.ts index b084d5856a8..292a6fefffa 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Measure.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Measure.ts @@ -45,13 +45,6 @@ export class Unit extends DataType implements Hashable { this.conversionFunction = conversionFunction; } - isSuperType(type: Type): boolean { - return false; - } - isSubType(type: Type): boolean { - return this.measure === type; - } - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.UNIT, @@ -71,14 +64,6 @@ export class Measure extends Type implements Hashable { canonicalUnit?: Unit | undefined; nonCanonicalUnits: Unit[] = []; - isSubType(type: Type): boolean { - return false; - } - - isSuperType(type: Type): boolean { - return type instanceof Unit && type.measure === this; - } - protected override get _elementHashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.MEASURE, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Multiplicity.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Multiplicity.ts index 9100840cdd9..65106cf9fb8 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Multiplicity.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Multiplicity.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - CORE_HASH_STRUCTURE, - MULTIPLICITY_INFINITE, -} from '../../../../../MetaModelConst'; +import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import { hashArray, type Hashable } from '@finos/legend-shared'; export class Multiplicity implements Hashable { @@ -29,16 +26,11 @@ export class Multiplicity implements Hashable { this.upperBound = upperBound; } - get str(): string { - if (this.lowerBound === this.upperBound) { - return this.lowerBound.toString(); - } else if (this.lowerBound === 0 && this.upperBound === undefined) { - return MULTIPLICITY_INFINITE; - } - return `${this.lowerBound}..${this.upperBound ?? MULTIPLICITY_INFINITE}`; - } - get hashCode(): string { - return hashArray([CORE_HASH_STRUCTURE.MULTIPLICITY, this.str]); + return hashArray([ + CORE_HASH_STRUCTURE.MULTIPLICITY, + this.lowerBound.toString(), + this.upperBound?.toString() ?? '', + ]); } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Package.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Package.ts index 6ad175dce13..f8f1a517762 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Package.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Package.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - CORE_HASH_STRUCTURE, - ELEMENT_PATH_DELIMITER, -} from '../../../../../MetaModelConst'; -import { type Hashable, hashArray } from '@finos/legend-shared'; +import type { Hashable } from '@finos/legend-shared'; import { type PackageableElementVisitor, PackageableElement, @@ -27,22 +23,19 @@ import { export class Package extends PackageableElement implements Hashable { children: PackageableElement[] = []; - get fullPath(): string { - if (!this.package) { - return ''; - } - const parentPackageName = this.package.fullPath; - return !parentPackageName - ? this.name - : `${parentPackageName}${ELEMENT_PATH_DELIMITER}${this.name}`; + /** + * This logic is specific to the codebase and this is not part of the native metamodel. + * If needed, we can probably move this out as an utility or do type declaration merge + * and define this externally using `Object.defineProperty`. + * + * @internal model logic + */ + override get path(): string { + return !this.package ? '' : super.path; } override get hashCode(): string { - return hashArray([ - CORE_HASH_STRUCTURE.PACKAGE, - this.path, - hashArray(this.children.map((child) => child.path)), - ]); + return ''; } accept_PackageableElementVisitor( diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/PrimitiveType.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/PrimitiveType.ts index 57a92662af5..7fd89320234 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/PrimitiveType.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/PrimitiveType.ts @@ -14,54 +14,10 @@ * limitations under the License. */ -import { PRIMITIVE_TYPE } from '../../../../../MetaModelConst'; import { DataType } from './DataType'; import type { PackageableElementVisitor } from '../PackageableElement'; -import type { Type } from './Type'; export class PrimitiveType extends DataType { - isSuperType(type: Type): boolean { - if (!(type instanceof PrimitiveType)) { - return false; - } - if (this.name === PRIMITIVE_TYPE.NUMBER) { - return ( - type.name === PRIMITIVE_TYPE.INTEGER || - type.name === PRIMITIVE_TYPE.FLOAT || - type.name === PRIMITIVE_TYPE.DECIMAL - ); - } - if (this.name === PRIMITIVE_TYPE.DATE) { - return ( - type.name === PRIMITIVE_TYPE.STRICTDATE || - type.name === PRIMITIVE_TYPE.DATETIME || - type.name === PRIMITIVE_TYPE.LATESTDATE - ); - } - return false; - } - - isSubType(type: Type): boolean { - if (!(type instanceof PrimitiveType)) { - return false; - } - if (type.name === PRIMITIVE_TYPE.NUMBER) { - return ( - this.name === PRIMITIVE_TYPE.INTEGER || - this.name === PRIMITIVE_TYPE.FLOAT || - this.name === PRIMITIVE_TYPE.DECIMAL - ); - } - if (type.name === PRIMITIVE_TYPE.DATE) { - return ( - this.name === PRIMITIVE_TYPE.STRICTDATE || - this.name === PRIMITIVE_TYPE.DATETIME || - this.name === PRIMITIVE_TYPE.LATESTDATE - ); - } - return false; - } - accept_PackageableElementVisitor( visitor: PackageableElementVisitor, ): T { diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Profile.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Profile.ts index 113b0e36801..fdeab32fd8f 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Profile.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Profile.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - type Hashable, - guaranteeNonNullable, - hashArray, -} from '@finos/legend-shared'; +import { type Hashable, hashArray } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import { type PackageableElementVisitor, @@ -26,31 +22,11 @@ import { } from '../PackageableElement'; import type { Stereotype } from './Stereotype'; import type { Tag } from './Tag'; -import { type Stubable, isStubArray } from '../../../../../helpers/Stubable'; -export class Profile extends PackageableElement implements Hashable, Stubable { +export class Profile extends PackageableElement implements Hashable { stereotypes: Stereotype[] = []; tags: Tag[] = []; - getTag = (value: string): Tag => - guaranteeNonNullable( - this.tags.find((tag) => tag.value === value), - `Can't find tag '${value}' in profile '${this.path}'`, - ); - - getStereotype = (value: string): Stereotype => - guaranteeNonNullable( - this.stereotypes.find((stereotype) => stereotype.value === value), - `Can't find stereotype '${value}' in profile '${this.path}'`, - ); - - static createStub = (): Profile => new Profile(''); - override get isStub(): boolean { - return ( - super.isStub && isStubArray(this.stereotypes) && isStubArray(this.tags) - ); - } - protected override get _elementHashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.PROFILE, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Property.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Property.ts index 10f0c882111..e659ad8c21a 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Property.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Property.ts @@ -16,23 +16,14 @@ import { type Hashable, hashArray, uuid } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; -import { - type GenericTypeReference, - GenericTypeExplicitReference, -} from './GenericTypeReference'; -import { Multiplicity } from './Multiplicity'; -import { GenericType } from './GenericType'; -import type { Class } from './Class'; +import type { GenericTypeReference } from './GenericTypeReference'; +import type { Multiplicity } from './Multiplicity'; import type { AbstractProperty, PropertyOwner } from './AbstractProperty'; import type { AnnotatedElement } from './AnnotatedElement'; import type { TaggedValue } from './TaggedValue'; -import { type Stubable, isStubArray } from '../../../../../helpers/Stubable'; -import type { Type } from './Type'; import type { StereotypeReference } from './StereotypeReference'; -export class Property - implements AbstractProperty, AnnotatedElement, Hashable, Stubable -{ +export class Property implements AbstractProperty, AnnotatedElement, Hashable { readonly _UUID = uuid(); readonly _OWNER: PropertyOwner; @@ -54,22 +45,6 @@ export class Property this._OWNER = owner; } - static createStub = (type: Type, _class: Class): Property => - new Property( - '', - new Multiplicity(1, 1), - GenericTypeExplicitReference.create(new GenericType(type)), - _class, - ); - get isStub(): boolean { - return ( - !this.name && - this.genericType.isStub && - isStubArray(this.stereotypes) && - isStubArray(this.taggedValues) - ); - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.PROPERTY, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/PropertyReference.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/PropertyReference.ts index c910923d1c1..1ef746ae445 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/PropertyReference.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/PropertyReference.ts @@ -21,16 +21,13 @@ import { type PackageableElementReference, type PackageableElementImplicitReference, } from '../PackageableElementReference'; -import type { Stubable } from '../../../../../helpers/Stubable'; import { ReferenceWithOwner } from '../../Reference'; import type { AbstractProperty } from './AbstractProperty'; import type { Class } from './Class'; import { Association } from './Association'; +import { getAssociatedPropertyClass } from '../../../../../helpers/DomainHelper'; -export abstract class PropertyReference - extends ReferenceWithOwner - implements Stubable -{ +export abstract class PropertyReference extends ReferenceWithOwner { override readonly ownerReference: PackageableElementReference< Class | Association >; @@ -45,10 +42,6 @@ export abstract class PropertyReference this.value = value; } - get isStub(): boolean { - return !this.value.isStub; - } - get pointerHashCode(): string { return [ CORE_HASH_STRUCTURE.PROPERTY_POINTER, @@ -66,7 +59,7 @@ export class PropertyExplicitReference extends PropertyReference { private constructor(value: AbstractProperty) { const ownerReference = PackageableElementExplicitReference.create( value._OWNER instanceof Association - ? value._OWNER.getPropertyAssociatedClass(value) + ? getAssociatedPropertyClass(value._OWNER, value) : value._OWNER, ); super(ownerReference, value); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Stereotype.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Stereotype.ts index e75c78ee8b5..3634112c022 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Stereotype.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Stereotype.ts @@ -16,9 +16,8 @@ import { uuid } from '@finos/legend-shared'; import type { Profile } from './Profile'; -import type { Stubable } from '../../../../../helpers/Stubable'; -export class Stereotype implements Stubable { +export class Stereotype { readonly _UUID = uuid(); readonly _OWNER: Profile; @@ -28,10 +27,4 @@ export class Stereotype implements Stubable { this._OWNER = owner; this.value = value; } - - static createStub = (profile: Profile): Stereotype => - new Stereotype(profile, ''); - get isStub(): boolean { - return !this.value; - } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/StereotypeReference.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/StereotypeReference.ts index 9b22e5fde79..5d6755fa2b2 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/StereotypeReference.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/StereotypeReference.ts @@ -22,14 +22,10 @@ import { type PackageableElementImplicitReference, } from '../PackageableElementReference'; import type { Profile } from './Profile'; -import type { Stubable } from '../../../../../helpers/Stubable'; import { ReferenceWithOwner } from '../../Reference'; import type { Stereotype } from './Stereotype'; -export abstract class StereotypeReference - extends ReferenceWithOwner - implements Stubable -{ +export abstract class StereotypeReference extends ReferenceWithOwner { override readonly ownerReference: PackageableElementReference; value: Stereotype; @@ -42,10 +38,6 @@ export abstract class StereotypeReference this.value = value; } - get isStub(): boolean { - return !this.value.isStub; - } - get pointerHashCode(): string { return [ CORE_HASH_STRUCTURE.STEREOTYPE_POINTER, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Tag.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Tag.ts index dfc35e7be53..a0a5df6beba 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Tag.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Tag.ts @@ -16,9 +16,8 @@ import { uuid } from '@finos/legend-shared'; import type { Profile } from './Profile'; -import type { Stubable } from '../../../../../helpers/Stubable'; -export class Tag implements Stubable { +export class Tag { readonly _UUID = uuid(); readonly _OWNER: Profile; @@ -28,9 +27,4 @@ export class Tag implements Stubable { this._OWNER = owner; this.value = value; } - - static createStub = (profile: Profile): Tag => new Tag(profile, ''); - get isStub(): boolean { - return !this.value; - } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/TagReference.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/TagReference.ts index 5f84504b9f6..f21e3fd8a7f 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/TagReference.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/TagReference.ts @@ -23,13 +23,9 @@ import { } from '../PackageableElementReference'; import type { Profile } from './Profile'; import type { Tag } from './Tag'; -import type { Stubable } from '../../../../../helpers/Stubable'; import { ReferenceWithOwner } from '../../Reference'; -export abstract class TagReference - extends ReferenceWithOwner - implements Stubable -{ +export abstract class TagReference extends ReferenceWithOwner { override readonly ownerReference: PackageableElementReference; value: Tag; @@ -42,10 +38,6 @@ export abstract class TagReference this.value = value; } - get isStub(): boolean { - return !this.value.isStub; - } - get pointerHashCode(): string { return [ CORE_HASH_STRUCTURE.TAG_POINTER, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/TaggedValue.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/TaggedValue.ts index 1ff8672f545..4cd8bc5ef23 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/TaggedValue.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/TaggedValue.ts @@ -16,11 +16,9 @@ import { hashArray, uuid, type Hashable } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; -import type { Tag } from './Tag'; -import type { Stubable } from '../../../../../helpers/Stubable'; -import { type TagReference, TagExplicitReference } from './TagReference'; +import type { TagReference } from './TagReference'; -export class TaggedValue implements Hashable, Stubable { +export class TaggedValue implements Hashable { readonly _UUID = uuid(); tag: TagReference; @@ -31,12 +29,6 @@ export class TaggedValue implements Hashable, Stubable { this.value = value; } - static createStub = (tag: Tag): TaggedValue => - new TaggedValue(TagExplicitReference.create(tag), ''); - get isStub(): boolean { - return !this.value && this.tag.isStub; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.TAGGED_VALUE, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Type.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Type.ts index 6651a5a1969..d6c0c8c669b 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Type.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/domain/Type.ts @@ -16,10 +16,4 @@ import { PackageableElement } from '../PackageableElement'; -export abstract class Type extends PackageableElement { - // Use these for contravariant and covariant check - // See https://www.originate.com/cheat-codes-for-contravariance-and-covariance/ - // See https://en.wikipedia.org/wiki/Covariance_and_contravariance_of_vectors - abstract isSubType(type: Type): boolean; - abstract isSuperType(type: Type): boolean; -} +export abstract class Type extends PackageableElement {} diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/fileGeneration/FileGenerationSpecification.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/fileGeneration/FileGenerationSpecification.ts index c9d2c3587c3..7128a5869f4 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/fileGeneration/FileGenerationSpecification.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/fileGeneration/FileGenerationSpecification.ts @@ -34,16 +34,6 @@ export class FileGenerationSpecification []; configurationProperties: ConfigurationProperty[] = []; - getConfigValue(name: string): unknown | undefined { - return this.getConfig(name)?.value; - } - - getConfig(name: string): ConfigurationProperty | undefined { - return this.configurationProperties.find( - (property) => name === property.name, - ); - } - protected override get _elementHashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.FILE_GENERATION, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/generationSpecification/GenerationSpecification.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/generationSpecification/GenerationSpecification.ts index f21957eaf35..60c76538006 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/generationSpecification/GenerationSpecification.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/generationSpecification/GenerationSpecification.ts @@ -22,10 +22,10 @@ import { type Hashable, hashArray } from '@finos/legend-shared'; import { type PackageableElementVisitor, PackageableElement, - getElementPointerHashCode, } from '../PackageableElement'; import type { PackageableElementReference } from '../PackageableElementReference'; import type { FileGenerationSpecification } from '../fileGeneration/FileGenerationSpecification'; +import { hashElementPointer } from '../../../../../MetaModelUtils'; // NOTE: As of now the tree only supports a linear order of generation. This is because the only use case is linear, // but the shape has been left as a tree to support 'branching' off in the future. @@ -70,7 +70,7 @@ export class GenerationSpecification hashArray(this.generationNodes), hashArray( this.fileGenerations.map((fileGeneration) => - getElementPointerHashCode( + hashElementPointer( PackageableElementPointerType.FILE_GENERATION, fileGeneration.hashValue, ), diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/AssociationImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/AssociationImplementation.ts index 0163b4551ff..b0d1d540d07 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/AssociationImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/AssociationImplementation.ts @@ -47,10 +47,6 @@ export abstract class AssociationImplementation this.association = association; } - get isStub(): boolean { - return !this.id.value; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.ASSOCIATION_IMPLEMENTATION, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/EnumValueMapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/EnumValueMapping.ts index 22941a21464..d26f064c3cc 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/EnumValueMapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/EnumValueMapping.ts @@ -14,13 +14,18 @@ * limitations under the License. */ -import { type Hashable, uuid, isNumber, hashArray } from '@finos/legend-shared'; +import { + type Hashable, + uuid, + isNumber, + hashArray, + isNonNullable, +} from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import { Enum } from '../domain/Enum'; -import type { Stubable } from '../../../../../helpers/Stubable'; import type { EnumValueReference } from '../domain/EnumValueReference'; -export class SourceValue implements Stubable { +export class SourceValue { readonly _UUID = uuid(); value: Enum | string | number | undefined; @@ -28,13 +33,9 @@ export class SourceValue implements Stubable { constructor(value: Enum | string | number | undefined) { this.value = value; } - - get isStub(): boolean { - return this.value === undefined; - } } -export class EnumValueMapping implements Hashable, Stubable { +export class EnumValueMapping implements Hashable { enum: EnumValueReference; sourceValues: SourceValue[] = []; @@ -42,25 +43,19 @@ export class EnumValueMapping implements Hashable, Stubable { this.enum = enumValue; } - get isStub(): boolean { - return !this.sourceValues.filter((value) => !value.isStub).length; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.ENUM_VALUE_MAPPING, this.enum.value.name, hashArray( - this.sourceValues - .filter((value) => !value.isStub) - .map((sourceValue) => { - const value = sourceValue.value; - return isNumber(value) - ? value.toString() - : value instanceof Enum - ? `${value._OWNER.path}.${value.name}` - : value ?? ''; - }), + this.sourceValues.filter(isNonNullable).map((sourceValue) => { + const value = sourceValue.value; + return isNumber(value) + ? value.toString() + : value instanceof Enum + ? `${value._OWNER.path}.${value.name}` + : value ?? ''; + }), ), ]); } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/EnumerationMapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/EnumerationMapping.ts index 0bba0496e36..8c686760711 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/EnumerationMapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/EnumerationMapping.ts @@ -14,25 +14,19 @@ * limitations under the License. */ -import { hashArray, type Hashable } from '@finos/legend-shared'; +import { hashArray, isNonNullable, type Hashable } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; -import { - type PackageableElementReference, - type OptionalPackageableElementReference, - PackageableElementExplicitReference, - OptionalPackageableElementExplicitReference, +import type { + PackageableElementReference, + OptionalPackageableElementReference, } from '../PackageableElementReference'; import type { Mapping } from './Mapping'; import type { Enumeration } from '../domain/Enumeration'; import type { EnumValueMapping } from './EnumValueMapping'; import type { Type } from '../domain/Type'; -import { type Stubable, isStubArray } from '../../../../../helpers/Stubable'; -import { - type InferableMappingElementIdValue, - InferableMappingElementIdExplicitValue, -} from './InferableMappingElementId'; +import type { InferableMappingElementIdValue } from './InferableMappingElementId'; -export class EnumerationMapping implements Hashable, Stubable { +export class EnumerationMapping implements Hashable { readonly _PARENT: Mapping; enumeration: PackageableElementReference; @@ -52,20 +46,6 @@ export class EnumerationMapping implements Hashable, Stubable { this.sourceType = sourceType; } - static createStub = ( - enumeration: Enumeration, - mapping: Mapping, - ): EnumerationMapping => - new EnumerationMapping( - InferableMappingElementIdExplicitValue.create('', enumeration.path), - PackageableElementExplicitReference.create(enumeration), - mapping, - OptionalPackageableElementExplicitReference.create(undefined), - ); - get isStub(): boolean { - return !this.id.value && isStubArray(this.enumValueMappings); - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.ENUMERATION_MAPPING, @@ -73,13 +53,17 @@ export class EnumerationMapping implements Hashable, Stubable { this.enumeration.hashValue, // If there are no enum value mapping, source type means nothing since it's not in the protocol anyway this.enumValueMappings.filter( - (enumValueMapping) => !enumValueMapping.isStub, + // TODO: use `isStubbed_EnumValueMapping` when we refactor hashing + (enumValueMapping) => + enumValueMapping.sourceValues.filter(isNonNullable).length, ).length ? this.sourceType.valueForSerialization ?? '' : '', // default source value when there is no element hashArray( this.enumValueMappings.filter( - (enumValueMapping) => !enumValueMapping.isStub, + // TODO: use `isStubbed_EnumValueMapping` when we refactor hashing + (enumValueMapping) => + enumValueMapping.sourceValues.filter(isNonNullable).length, ), ), ]); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/InstanceSetImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/InstanceSetImplementation.ts index e16d673f52b..e332bd9b21d 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/InstanceSetImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/InstanceSetImplementation.ts @@ -27,10 +27,4 @@ export abstract class InstanceSetImplementation mappingClass?: MappingClass | undefined; propertyMappings: PropertyMapping[] = []; // aggregateSpecification: AggregateSpecification[0..1]; - - abstract getEmbeddedSetImplmentations(): InstanceSetImplementation[]; - abstract findPropertyMapping( - propertyName: string, - targetId: string | undefined, - ): PropertyMapping | undefined; } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/Mapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/Mapping.ts index fb959069cab..764245924d1 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/Mapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/Mapping.ts @@ -23,56 +23,16 @@ import { type PackageableElementVisitor, PackageableElement, } from '../PackageableElement'; -import { type Stubable, isStubArray } from '../../../../../helpers/Stubable'; import type { MappingTest } from './MappingTest'; import type { MappingInclude } from './MappingInclude'; -export class Mapping extends PackageableElement implements Hashable, Stubable { +export class Mapping extends PackageableElement implements Hashable { includes: MappingInclude[] = []; classMappings: SetImplementation[] = []; enumerationMappings: EnumerationMapping[] = []; associationMappings: AssociationImplementation[] = []; tests: MappingTest[] = []; - get allOwnClassMappings(): SetImplementation[] { - return this.classMappings; - } - - get allOwnEnumerationMappings(): EnumerationMapping[] { - return this.enumerationMappings; - } - - /** - * Get all included mappings, accounted for loop and duplication (which should be caught by compiler) - */ - get allIncludedMappings(): Mapping[] { - const visited = new Set(); - visited.add(this); - const resolveIncludes = (_mapping: Mapping): void => { - _mapping.includes.forEach((incMapping) => { - if (!visited.has(incMapping.included.value)) { - visited.add(incMapping.included.value); - resolveIncludes(incMapping.included.value); - } - }); - }; - resolveIncludes(this); - visited.delete(this); - return Array.from(visited); - } - - static createStub = (): Mapping => new Mapping(''); - - override get isStub(): boolean { - return ( - super.isStub && - // && isStubArray(this.includes) - isStubArray(this.associationMappings) && - isStubArray(this.classMappings) && - isStubArray(this.enumerationMappings) - ); - } - protected override get _elementHashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.MAPPING, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/MappingTest.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/MappingTest.ts index b8968cbbe8c..1391d731a3d 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/MappingTest.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/MappingTest.ts @@ -52,7 +52,8 @@ export class MappingTest implements Hashable { get validationResult(): ValidationIssue[] | undefined { let problems: ValidationIssue[] = []; // query - if (this.query.isStub) { + // TODO: use `isStubbed_RawLambda` when we refactor validation + if (!this.query.parameters && !this.query.body) { problems.push( createValidationError(['Mapping test query cannot be empty']), ); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/MergeOperationSetImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/MergeOperationSetImplementation.ts index 111073f48cf..1bd3d9e0bfb 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/MergeOperationSetImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/MergeOperationSetImplementation.ts @@ -25,14 +25,13 @@ import { type OperationType, OperationSetImplementation, } from './OperationSetImplementation'; -import type { Stubable } from '../../../../../helpers/Stubable'; import type { RawLambda } from '../../rawValueSpecification/RawLambda'; import type { SetImplementationVisitor } from './SetImplementation'; import { hashLambda } from '../../../../../MetaModelUtils'; export class MergeOperationSetImplementation extends OperationSetImplementation - implements Hashable, Stubable + implements Hashable { validationFunction: RawLambda; @@ -53,6 +52,7 @@ export class MergeOperationSetImplementation CORE_HASH_STRUCTURE.OPERATION_SET_IMPLEMENTATION, this.operation, hashArray( + // TODO: use `isStubbed_SetImplementationContainer` when we refactor hashing this.parameters.map((param) => param.setImplementation.value.id.value), ), hashLambda( diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/OperationSetImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/OperationSetImplementation.ts index 3f2b3103a0d..ef303136a11 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/OperationSetImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/OperationSetImplementation.ts @@ -24,7 +24,6 @@ import { import type { SetImplementationContainer } from './SetImplementationContainer'; import type { Mapping } from './Mapping'; import type { Class } from '../domain/Class'; -import { type Stubable, isStubArray } from '../../../../../helpers/Stubable'; import type { InferableMappingElementIdValue } from './InferableMappingElementId'; import type { InferableMappingElementRoot } from './InferableMappingElementRoot'; @@ -37,7 +36,7 @@ export enum OperationType { export class OperationSetImplementation extends SetImplementation - implements Hashable, Stubable + implements Hashable { parameters: SetImplementationContainer[] = []; operation: OperationType; @@ -53,49 +52,12 @@ export class OperationSetImplementation this.operation = operation; } - /** - * Get all leaf impls of an operation Set Implementation. Accounts for loops and duplication (which should be caught by compiler). - */ - get leafSetImplementations(): SetImplementation[] { - return this.childSetImplementations.filter( - (si) => !(si instanceof OperationSetImplementation), - ); - } - - get childSetImplementations(): SetImplementation[] { - const visitedOperations = new Set(); - visitedOperations.add(this); - const _leaves = new Set(); - const resolveleafSetImps = ( - _opSetImpl: OperationSetImplementation, - ): void => { - _opSetImpl.parameters.forEach((p) => { - const setImp = p.setImplementation.value; - if ( - setImp instanceof OperationSetImplementation && - !visitedOperations.has(setImp) - ) { - visitedOperations.add(setImp); - resolveleafSetImps(setImp); - } else { - _leaves.add(setImp); - } - }); - }; - resolveleafSetImps(this); - visitedOperations.delete(this); - return Array.from(_leaves).concat(Array.from(visitedOperations)); - } - - override get isStub(): boolean { - return super.isStub && isStubArray(this.parameters); - } - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.OPERATION_SET_IMPLEMENTATION, this.operation, hashArray( + // TODO: use `isStubbed_SetImplementationContainer` when we refactor hashing this.parameters.map((param) => param.setImplementation.value.id.value), ), ]); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/PropertyMapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/PropertyMapping.ts index 2fcf8a73947..d9e83512f60 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/PropertyMapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/PropertyMapping.ts @@ -14,16 +14,11 @@ * limitations under the License. */ -import { - UnsupportedOperationError, - hashArray, - type Hashable, -} from '@finos/legend-shared'; +import { hashArray, type Hashable } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import type { PropertyReference } from '../domain/PropertyReference'; import type { PropertyMappingsImplementation } from './PropertyMappingsImplementation'; import type { SetImplementation } from './SetImplementation'; -import type { Stubable } from '../../../../../helpers/Stubable'; import type { PurePropertyMapping } from '../store/modelToModel/mapping/PurePropertyMapping'; import type { FlatDataPropertyMapping } from '../store/flatData/mapping/FlatDataPropertyMapping'; import type { EmbeddedFlatDataPropertyMapping } from '../store/flatData/mapping/EmbeddedFlatDataPropertyMapping'; @@ -60,7 +55,7 @@ export interface PropertyMappingVisitor { visit_XStorePropertyMapping(propertyMapping: XStorePropertyMapping): T; } -export abstract class PropertyMapping implements Hashable, Stubable { +export abstract class PropertyMapping implements Hashable { /** * the immediate parent instance set implementation that holds the property mappings */ @@ -99,10 +94,6 @@ export abstract class PropertyMapping implements Hashable, Stubable { this.property = property; } - get isStub(): boolean { - throw new UnsupportedOperationError(); - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.PROPERTY_MAPPING, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/SetImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/SetImplementation.ts index 735ad2a21e2..f8591fb1867 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/SetImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/SetImplementation.ts @@ -19,7 +19,6 @@ import { CORE_HASH_STRUCTURE } from '../../../../../MetaModelConst'; import type { PackageableElementReference } from '../PackageableElementReference'; import type { PropertyOwnerImplementation } from './PropertyOwnerImplementation'; import type { Mapping } from './Mapping'; -import type { Stubable } from '../../../../../helpers/Stubable'; import type { OperationSetImplementation } from './OperationSetImplementation'; import type { PureInstanceSetImplementation } from '../store/modelToModel/mapping/PureInstanceSetImplementation'; import type { FlatDataInstanceSetImplementation } from '../store/flatData/mapping/FlatDataInstanceSetImplementation'; @@ -67,7 +66,7 @@ export interface SetImplementationVisitor { } export abstract class SetImplementation - implements PropertyOwnerImplementation, Hashable, Stubable + implements PropertyOwnerImplementation, Hashable { readonly _PARENT: Mapping; readonly _isEmbedded: boolean = false; @@ -88,10 +87,6 @@ export abstract class SetImplementation this.root = root; } - get isStub(): boolean { - return !this.id.value; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.SET_IMPLEMENTATION, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/SetImplementationContainer.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/SetImplementationContainer.ts index fc4caf83b4a..15627009985 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/SetImplementationContainer.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/SetImplementationContainer.ts @@ -16,9 +16,8 @@ import { uuid } from '@finos/legend-shared'; import type { SetImplementationReference } from './SetImplementationReference'; -import type { Stubable } from '../../../../../helpers/Stubable'; -export class SetImplementationContainer implements Stubable { +export class SetImplementationContainer { readonly _UUID = uuid(); setImplementation: SetImplementationReference; @@ -26,8 +25,4 @@ export class SetImplementationContainer implements Stubable { constructor(setImplementation: SetImplementationReference) { this.setImplementation = setImplementation; } - - get isStub(): boolean { - return !this.setImplementation.value.id; - } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/aggregationAware/AggregationAwarePropertyMapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/aggregationAware/AggregationAwarePropertyMapping.ts index 5e1139061d6..0be755abc2e 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/aggregationAware/AggregationAwarePropertyMapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/aggregationAware/AggregationAwarePropertyMapping.ts @@ -23,9 +23,4 @@ export class AggregationAwarePropertyMapping extends PropertyMapping { accept_PropertyMappingVisitor(visitor: PropertyMappingVisitor): T { return visitor.visit_AggregationAwarePropertyMapping(this); } - - override get isStub(): boolean { - // TODO figure out isStub conditions - return false; - } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/aggregationAware/AggregationAwareSetImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/aggregationAware/AggregationAwareSetImplementation.ts index 79df22d70a4..9b9d9be7f9a 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/aggregationAware/AggregationAwareSetImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/aggregationAware/AggregationAwareSetImplementation.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import type { PropertyMapping } from '../PropertyMapping'; import { InstanceSetImplementation } from '../InstanceSetImplementation'; import type { SetImplementationVisitor } from '../SetImplementation'; import type { InferableMappingElementIdValue } from '../InferableMappingElementId'; @@ -41,30 +40,6 @@ export class AggregationAwareSetImplementation extends InstanceSetImplementation this.mainSetImplementation = mainSetImplementation; } - getEmbeddedSetImplmentations(): InstanceSetImplementation[] { - return []; - } - findPropertyMapping( - propertyName: string, - targetId: string | undefined, - ): PropertyMapping | undefined { - let properties = undefined; - properties = this.propertyMappings.filter( - (propertyMapping) => propertyMapping.property.value.name === propertyName, - ); - if (targetId === undefined || properties.length === 1) { - return properties[0]; - } - return properties.find( - (propertyMapping) => - propertyMapping.targetSetImplementation && - propertyMapping.targetSetImplementation.id.value === targetId, - ); - } - accept_SetImplementationVisitor(visitor: SetImplementationVisitor): T { - return visitor.visit_AggregationAwareSetImplementation(this); - } - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.AGGREGATION_AWARE_MAPPING, @@ -74,4 +49,8 @@ export class AggregationAwareSetImplementation extends InstanceSetImplementation hashArray(this.propertyMappings), ]); } + + accept_SetImplementationVisitor(visitor: SetImplementationVisitor): T { + return visitor.visit_AggregationAwareSetImplementation(this); + } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/xStore/XStorePropertyMapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/xStore/XStorePropertyMapping.ts index e17f4b56695..43b645b7fbf 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/xStore/XStorePropertyMapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/mapping/xStore/XStorePropertyMapping.ts @@ -17,16 +17,12 @@ import { hashArray, type Hashable } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../../MetaModelConst'; import type { RawLambda } from '../../../rawValueSpecification/RawLambda'; -import type { Stubable } from '../../../../../../helpers/Stubable'; import { type PropertyMappingVisitor, PropertyMapping, } from '../PropertyMapping'; -export class XStorePropertyMapping - extends PropertyMapping - implements Hashable, Stubable -{ +export class XStorePropertyMapping extends PropertyMapping implements Hashable { /** * Studio does not process value specification, they are left in raw JSON form * @@ -42,11 +38,6 @@ export class XStorePropertyMapping ]); } - override get isStub(): boolean { - // TODO figure out isStub conditions - return false; - } - accept_PropertyMappingVisitor(visitor: PropertyMappingVisitor): T { return visitor.visit_XStorePropertyMapping(this); } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/runtime/Runtime.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/runtime/Runtime.ts index e6bab9ef6ce..7f652001e48 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/runtime/Runtime.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/runtime/Runtime.ts @@ -14,13 +14,7 @@ * limitations under the License. */ -import { - type Hashable, - hashArray, - generateEnumerableNameFromToken, - assertTrue, - uuid, -} from '@finos/legend-shared'; +import { type Hashable, hashArray, uuid } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE, PackageableElementPointerType, @@ -29,8 +23,8 @@ import type { Connection } from '../connection/Connection'; import type { PackageableRuntime } from './PackageableRuntime'; import type { Mapping } from '../mapping/Mapping'; import type { Store } from '../store/Store'; -import { getElementPointerHashCode } from '../PackageableElement'; import type { PackageableElementReference } from '../PackageableElementReference'; +import { hashElementPointer } from '../../../../../MetaModelUtils'; export class IdentifiedConnection implements Hashable { readonly _UUID = uuid(); @@ -60,14 +54,10 @@ export class StoreConnections implements Hashable { this.store = store; } - get isStub(): boolean { - return !this.storeConnections.length; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.STORE_CONNECTIONS, - getElementPointerHashCode( + hashElementPointer( PackageableElementPointerType.STORE, this.store.hashValue, ), @@ -84,40 +74,23 @@ export class EngineRuntime extends Runtime implements Hashable { mappings: PackageableElementReference[] = []; connections: StoreConnections[] = []; - get allIdentifiedConnections(): IdentifiedConnection[] { - return this.connections.flatMap( - (storeConnections) => storeConnections.storeConnections, - ); - } - - generateIdentifiedConnectionId(): string { - const generatedId = generateEnumerableNameFromToken( - this.allIdentifiedConnections.map( - (identifiedConnection) => identifiedConnection.id, - ), - 'connection', - ); - assertTrue( - !this.allIdentifiedConnections.find( - (identifiedConnection) => identifiedConnection.id === generatedId, - ), - `Can't auto-generate connection ID with value '${generatedId}'`, - ); - return generatedId; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.ENGINE_RUNTIME, hashArray( this.mappings.map((mapping) => - getElementPointerHashCode( + hashElementPointer( PackageableElementPointerType.MAPPING, mapping.hashValue, ), ), ), - hashArray(this.connections.filter((connection) => !connection.isStub)), + hashArray( + this.connections.filter( + // TODO: use `isStubbed_StoreConnections` when we refactor hashing + (connection) => connection.storeConnections.length, + ), + ), ]); } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/service/ServiceExecution.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/service/ServiceExecution.ts index de3062f28e0..92488443d1b 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/service/ServiceExecution.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/service/ServiceExecution.ts @@ -47,7 +47,8 @@ export class PureExecution extends ServiceExecution implements Hashable { } get queryValidationResult(): ValidationIssue | undefined { - if (this.func.isStub) { + // TODO: use `isStubbed_RawLambda` when we refactor validation + if (!this.func.parameters && !this.func.body) { return createValidationError([ 'Service execution function cannot be empty', ]); @@ -80,7 +81,8 @@ export class PureSingleExecution extends PureExecution implements Hashable { } get mappingValidationResult(): ValidationIssue | undefined { - return this.mapping.value.isStub + // TODO: use `isStubbed_PackageableElement` when we refactor validation + return !this.mapping.value.package && !this.mapping.value.name ? createValidationError(['Service execution mapping cannot be empty']) : undefined; } @@ -113,7 +115,8 @@ export class KeyedExecutionParameter implements Hashable { } get mappingValidationResult(): ValidationIssue | undefined { - return this.mapping.value.isStub + // TODO: use `isStubbed_PackageableElement` when we refactor validation + return !this.mapping.value.package && !this.mapping.value.name ? createValidationError(['Service execution mapping cannot be empty']) : undefined; } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/EmbeddedFlatDataPropertyMapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/EmbeddedFlatDataPropertyMapping.ts index 8a36b418c0e..a686b926af2 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/EmbeddedFlatDataPropertyMapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/EmbeddedFlatDataPropertyMapping.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { filterByType, hashArray, type Hashable } from '@finos/legend-shared'; +import { hashArray, type Hashable } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; import type { Mapping } from '../../../mapping/Mapping'; import { AbstractFlatDataPropertyMapping } from './AbstractFlatDataPropertyMapping'; @@ -34,6 +34,7 @@ import type { InferableMappingElementIdValue } from '../../../mapping/InferableM import type { PackageableElementReference } from '../../../PackageableElementReference'; import { InferableMappingElementRootExplicitValue } from '../../../mapping/InferableMappingElementRoot'; import type { MappingClass } from '../../../mapping/MappingClass'; +import { FlatDataPropertyMapping } from './FlatDataPropertyMapping'; /** * We can think of embedded property mappings as a 'gateway' from one set of property mappings to another. They are in a sense @@ -76,11 +77,6 @@ export class EmbeddedFlatDataPropertyMapping this._PARENT = rootInstanceSetImplementation._PARENT; } - // As of now, there is no stub cases of Embedded Flat Property Mapping since they are created with an existing property mapping - override get isStub(): boolean { - return false; - } - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.EMBEDDED_FLAT_DATA_PROPERTY_MAPPING, @@ -90,7 +86,18 @@ export class EmbeddedFlatDataPropertyMapping // skip `root` since we disregard it in embedded property mappings hashArray( this.propertyMappings.filter( - (propertyMapping) => !propertyMapping.isStub, + // TODO: we should also handle of other property mapping types + // using some form of extension mechanism + (propertyMapping) => { + if (propertyMapping instanceof FlatDataPropertyMapping) { + // TODO: use `isStubbed_RawLambda` when we move this out of the metamodel + return ( + Boolean(propertyMapping.transform.parameters) || + Boolean(propertyMapping.transform.body) + ); + } + return true; + }, ), ), ]); @@ -103,34 +110,4 @@ export class EmbeddedFlatDataPropertyMapping accept_PropertyMappingVisitor(visitor: PropertyMappingVisitor): T { return visitor.visit_EmbeddedFlatDataPropertyMapping(this); } - - getEmbeddedSetImplmentations(): InstanceSetImplementation[] { - const embeddedPropertyMappings = this.propertyMappings.filter( - filterByType(EmbeddedFlatDataPropertyMapping), - ); - return embeddedPropertyMappings - .map((embeddedPropertyMapping) => - embeddedPropertyMapping.getEmbeddedSetImplmentations(), - ) - .flat() - .concat(embeddedPropertyMappings); - } - - findPropertyMapping( - propertyName: string, - targetId: string | undefined, - ): AbstractFlatDataPropertyMapping | undefined { - let properties = undefined; - properties = this.propertyMappings.filter( - (propertyMapping) => propertyMapping.property.value.name === propertyName, - ); - if (targetId === undefined || properties.length === 1) { - return properties[0]; - } - return properties.find( - (propertyMapping) => - propertyMapping.targetSetImplementation && - propertyMapping.targetSetImplementation.id.value === targetId, - ); - } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInputData.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInputData.ts index 98a386f0272..d89d130ab4d 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInputData.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInputData.ts @@ -22,11 +22,11 @@ import { import { InputData } from '../../../mapping/InputData'; import type { FlatData } from '../model/FlatData'; import type { PackageableElementReference } from '../../../PackageableElementReference'; -import { getElementPointerHashCode } from '../../../PackageableElement'; import { type ValidationIssue, createValidationError, } from '../../../../../../../helpers/ValidationHelper'; +import { hashElementPointer } from '../../../../../../../MetaModelUtils'; export class FlatDataInputData extends InputData implements Hashable { sourceFlatData: PackageableElementReference; @@ -42,7 +42,8 @@ export class FlatDataInputData extends InputData implements Hashable { } get validationResult(): ValidationIssue | undefined { - if (this.sourceFlatData.value.isStub) { + // TODO: use `isStubbed_PackageableElement` when we refactor validation + if (!this.sourceFlatData.value.package && !this.sourceFlatData.value.name) { return createValidationError([ 'Flat-data input data source flat-data store is missing', ]); @@ -53,7 +54,7 @@ export class FlatDataInputData extends InputData implements Hashable { get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.FLAT_DATA_INPUT_DATA, - getElementPointerHashCode( + hashElementPointer( PackageableElementPointerType.STORE, this.sourceFlatData.hashValue, ), diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInstanceSetImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInstanceSetImplementation.ts index d1666e9be4a..c3e7476158c 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInstanceSetImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInstanceSetImplementation.ts @@ -14,19 +14,19 @@ * limitations under the License. */ -import { filterByType, hashArray, type Hashable } from '@finos/legend-shared'; +import { hashArray, type Hashable } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; import { InstanceSetImplementation } from '../../../mapping/InstanceSetImplementation'; import type { AbstractFlatDataPropertyMapping } from './AbstractFlatDataPropertyMapping'; import type { Class } from '../../../domain/Class'; import type { Mapping } from '../../../mapping/Mapping'; import type { SetImplementationVisitor } from '../../../mapping/SetImplementation'; -import { EmbeddedFlatDataPropertyMapping } from './EmbeddedFlatDataPropertyMapping'; import type { InferableMappingElementIdValue } from '../../../mapping/InferableMappingElementId'; import type { RawLambda } from '../../../../rawValueSpecification/RawLambda'; import type { PackageableElementReference } from '../../../PackageableElementReference'; import type { RootFlatDataRecordTypeReference } from '../model/RootFlatDataRecordTypeReference'; import type { InferableMappingElementRoot } from '../../../mapping/InferableMappingElementRoot'; +import { FlatDataPropertyMapping } from './FlatDataPropertyMapping'; export class FlatDataInstanceSetImplementation extends InstanceSetImplementation @@ -52,34 +52,6 @@ export class FlatDataInstanceSetImplementation this.sourceRootRecordType = sourceRootRecordType; } - findPropertyMapping( - propertyName: string, - targetId: string | undefined, - ): AbstractFlatDataPropertyMapping | undefined { - let properties = undefined; - properties = this.propertyMappings.filter( - (propertyMapping) => propertyMapping.property.value.name === propertyName, - ); - if (targetId === undefined || properties.length === 1) { - return properties[0]; - } - return properties.find( - (propertyMapping) => - propertyMapping.targetSetImplementation && - propertyMapping.targetSetImplementation.id.value === targetId, - ); - } - - getEmbeddedSetImplmentations(): InstanceSetImplementation[] { - const embeddedPropertyMappings = this.propertyMappings.filter( - filterByType(EmbeddedFlatDataPropertyMapping), - ); - return embeddedPropertyMappings - .map((propertyMapping) => propertyMapping.getEmbeddedSetImplmentations()) - .flat() - .concat(embeddedPropertyMappings); - } - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.FLAT_DATA_INSTANCE_SET_IMPLEMENTATION, @@ -89,7 +61,18 @@ export class FlatDataInstanceSetImplementation this.filter ?? '', hashArray( this.propertyMappings.filter( - (propertyMapping) => !propertyMapping.isStub, + // TODO: we should also handle of other property mapping types + // using some form of extension mechanism + (propertyMapping) => { + if (propertyMapping instanceof FlatDataPropertyMapping) { + // TODO: use `isStubbed_RawLambda` when we move this out of the metamodel + return ( + Boolean(propertyMapping.transform.parameters) || + Boolean(propertyMapping.transform.body) + ); + } + return true; + }, ), ), ]); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataPropertyMapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataPropertyMapping.ts index 6d9202735eb..c63ae582018 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataPropertyMapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/mapping/FlatDataPropertyMapping.ts @@ -48,10 +48,6 @@ export class FlatDataPropertyMapping this.transform = transform; } - override get isStub(): boolean { - return this.transform.isStub; - } - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.FLAT_DATA_PROPERTY_MAPPING, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/model/FlatData.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/model/FlatData.ts index e302e94327f..1a501574f55 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/model/FlatData.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/model/FlatData.ts @@ -14,34 +14,15 @@ * limitations under the License. */ -import { - type Hashable, - guaranteeNonNullable, - hashArray, -} from '@finos/legend-shared'; +import { type Hashable, hashArray } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; import type { FlatDataSection } from './FlatDataSection'; import { Store } from '../../Store'; import type { PackageableElementVisitor } from '../../../PackageableElement'; -import type { RootFlatDataRecordType } from './FlatDataDataType'; export class FlatData extends Store implements Hashable { sections: FlatDataSection[] = []; - findSection = (sectionName: string): FlatDataSection => - guaranteeNonNullable( - this.sections.find((section) => section.name === sectionName), - `Can't find section '${sectionName}' in flat-data store '${this.path}'`, - ); - - get recordTypes(): RootFlatDataRecordType[] { - return this.sections.flatMap((section) => - section.recordType ? [section.recordType] : [], - ); - } - - static createStub = (): FlatData => new FlatData(''); - protected override get _elementHashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.FLAT_DATA, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/model/FlatDataSection.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/model/FlatDataSection.ts index b13a865f38b..0bc3e3e9c05 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/model/FlatDataSection.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/flatData/model/FlatDataSection.ts @@ -15,11 +15,7 @@ */ import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; -import { - type Hashable, - hashArray, - guaranteeNonNullable, -} from '@finos/legend-shared'; +import { type Hashable, hashArray } from '@finos/legend-shared'; import type { FlatData } from './FlatData'; import type { FlatDataProperty } from './FlatDataProperty'; import type { RootFlatDataRecordType } from './FlatDataDataType'; @@ -38,12 +34,6 @@ export class FlatDataSection implements Hashable { this._OWNER = owner; } - getRecordType = (): RootFlatDataRecordType => - guaranteeNonNullable( - this.recordType, - `No record type defined in section '${this.name}' of flat-data store '${this._OWNER.path}'`, - ); - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.FLAT_DATA_SECTION, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/ObjectInputData.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/ObjectInputData.ts index 65bb3440ace..3dd75d15307 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/ObjectInputData.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/ObjectInputData.ts @@ -17,7 +17,6 @@ import { type Hashable, hashArray, - UnsupportedOperationError, isValidJSONString, tryToMinifyLosslessJSONString, } from '@finos/legend-shared'; @@ -35,19 +34,6 @@ export enum ObjectInputType { XML = 'XML', } -export const getObjectInputType = (type: string): ObjectInputType => { - switch (type) { - case ObjectInputType.JSON: - return ObjectInputType.JSON; - case ObjectInputType.XML: - return ObjectInputType.XML; - default: - throw new UnsupportedOperationError( - `Encountered unsupported object input type '${type}'`, - ); - } -}; - export class ObjectInputData extends InputData implements Hashable { sourceClass: PackageableElementReference; inputType: ObjectInputType; @@ -71,7 +57,8 @@ export class ObjectInputData extends InputData implements Hashable { } get validationResult(): ValidationIssue | undefined { - if (this.sourceClass.value.isStub) { + // TODO: use `isStubbed_PackageableElement` when we refactor validation + if (!this.sourceClass.value.package && !this.sourceClass.value.name) { return createValidationError([ 'Object input data source class is missing', ]); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/PureInstanceSetImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/PureInstanceSetImplementation.ts index 576561ce5d4..c5c2cbd1d10 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/PureInstanceSetImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/PureInstanceSetImplementation.ts @@ -20,10 +20,6 @@ import type { Class } from '../../../domain/Class'; import { InstanceSetImplementation } from '../../../mapping/InstanceSetImplementation'; import type { PurePropertyMapping } from './PurePropertyMapping'; import type { SetImplementationVisitor } from '../../../mapping/SetImplementation'; -import { - type Stubable, - isStubArray, -} from '../../../../../../../helpers/Stubable'; import type { RawLambda } from '../../../../rawValueSpecification/RawLambda'; import type { PackageableElementReference, @@ -35,7 +31,7 @@ import type { InferableMappingElementRoot } from '../../../mapping/InferableMapp export class PureInstanceSetImplementation extends InstanceSetImplementation - implements Hashable, Stubable + implements Hashable { declare propertyMappings: PurePropertyMapping[]; srcClass: OptionalPackageableElementReference; @@ -57,28 +53,6 @@ export class PureInstanceSetImplementation this.srcClass = srcClass; } - findPropertyMapping( - propertyName: string, - targetId: string | undefined, - ): PurePropertyMapping | undefined { - let properties = undefined; - properties = this.propertyMappings.filter( - (propertyMapping) => propertyMapping.property.value.name === propertyName, - ); - if (targetId === undefined || properties.length === 1) { - return properties[0]; - } - return properties.find( - (propertyMapping) => - propertyMapping.targetSetImplementation && - propertyMapping.targetSetImplementation.id.value === targetId, - ); - } - - override get isStub(): boolean { - return super.isStub && isStubArray(this.propertyMappings); - } - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.PURE_INSTANCE_SET_IMPLEMENTATION, @@ -87,7 +61,12 @@ export class PureInstanceSetImplementation this.filter ?? '', hashArray( this.propertyMappings.filter( - (propertyMapping) => !propertyMapping.isStub, + // TODO: we should also handle of other property mapping types + // using some form of extension mechanism + (propertyMapping) => + // TODO: use `isStubbed_RawLambda` when we move this out of the metamodel + Boolean(propertyMapping.transform.parameters) || + Boolean(propertyMapping.transform.body), ), ), ]); @@ -96,8 +75,4 @@ export class PureInstanceSetImplementation accept_SetImplementationVisitor(visitor: SetImplementationVisitor): T { return visitor.visit_PureInstanceSetImplementation(this); } - - getEmbeddedSetImplmentations(): InstanceSetImplementation[] { - return []; - } } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/PurePropertyMapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/PurePropertyMapping.ts index 5ab60506473..a055020c76f 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/PurePropertyMapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/modelToModel/mapping/PurePropertyMapping.ts @@ -25,12 +25,8 @@ import type { PropertyReference } from '../../../domain/PropertyReference'; import type { SetImplementation } from '../../../mapping/SetImplementation'; import type { PropertyMappingsImplementation } from '../../../mapping/PropertyMappingsImplementation'; import type { RawLambda } from '../../../../rawValueSpecification/RawLambda'; -import type { Stubable } from '../../../../../../../helpers/Stubable'; -export class PurePropertyMapping - extends PropertyMapping - implements Hashable, Stubable -{ +export class PurePropertyMapping extends PropertyMapping implements Hashable { // TODO: convert to reference transformer?: EnumerationMapping | undefined; /** @@ -54,10 +50,6 @@ export class PurePropertyMapping this.explodeProperty = explodeProperty; } - override get isStub(): boolean { - return this.transform.isStub; - } - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.PURE_PROPERTY_MAPPING, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/EmbeddedRelationalInstanceSetImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/EmbeddedRelationalInstanceSetImplementation.ts index 0230737c91c..61959d9d979 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/EmbeddedRelationalInstanceSetImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/EmbeddedRelationalInstanceSetImplementation.ts @@ -18,6 +18,7 @@ import { UnsupportedOperationError, hashArray, type Hashable, + isEmpty, } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; import type { RelationalOperationElement } from '../model/RelationalOperationElement'; @@ -33,7 +34,6 @@ import { type PropertyMappingVisitor, PropertyMapping, } from '../../../mapping/PropertyMapping'; -import type { InstanceSetImplementation } from '../../../mapping/InstanceSetImplementation'; import type { RootRelationalInstanceSetImplementation } from './RootRelationalInstanceSetImplementation'; import type { InferableMappingElementIdValue } from '../../../mapping/InferableMappingElementId'; import type { PackageableElementReference } from '../../../PackageableElementReference'; @@ -41,6 +41,7 @@ import type { PropertyReference } from '../../../domain/PropertyReference'; import type { RelationalInstanceSetImplementation } from './RelationalInstanceSetImplementation'; import { InferableMappingElementRootExplicitValue } from '../../../mapping/InferableMappingElementRoot'; import type { MappingClass } from '../../../mapping/MappingClass'; +import { RelationalPropertyMapping } from './RelationalPropertyMapping'; export class EmbeddedRelationalInstanceSetImplementation extends PropertyMapping @@ -76,32 +77,6 @@ export class EmbeddedRelationalInstanceSetImplementation this._PARENT = rootInstanceSetImplementation._PARENT; } - getEmbeddedSetImplmentations(): InstanceSetImplementation[] { - throw new UnsupportedOperationError(); - } - - findPropertyMapping( - propertyName: string, - targetId: string | undefined, - ): PropertyMapping | undefined { - let properties = undefined; - properties = this.propertyMappings.filter( - (propertyMapping) => propertyMapping.property.value.name === propertyName, - ); - if (targetId === undefined || properties.length === 1) { - return properties[0]; - } - return properties.find( - (propertyMapping) => - propertyMapping.targetSetImplementation && - propertyMapping.targetSetImplementation.id.value === targetId, - ); - } - - override get isStub(): boolean { - return false; - } - accept_PropertyMappingVisitor(visitor: PropertyMappingVisitor): T { return visitor.visit_EmbeddedRelationalPropertyMapping(this); } @@ -116,11 +91,17 @@ export class EmbeddedRelationalInstanceSetImplementation super.hashCode, this.class.hashValue, hashArray(this.primaryKey), - //skip `root` since we disregard it in embedded property mappings + // skip `root` since we disregard it in embedded property mappings hashArray( - this.propertyMappings.filter( - (propertyMapping) => !propertyMapping.isStub, - ), + this.propertyMappings.filter((propertyMapping) => { + // TODO: we should also handle of other property mapping types + // using some form of extension mechanism + if (propertyMapping instanceof RelationalPropertyMapping) { + // TODO: use `isStubbed_RawRelationalOperationElement` when we move this out of the metamodel + return !isEmpty(propertyMapping.relationalOperation); + } + return true; + }), ), ]); } diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInputData.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInputData.ts index 1cde373763a..748bb430171 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInputData.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInputData.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - hashArray, - UnsupportedOperationError, - type Hashable, -} from '@finos/legend-shared'; +import { hashArray, type Hashable } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; import { InputData } from '../../../mapping/InputData'; import { @@ -33,19 +29,6 @@ export enum RelationalInputType { CSV = 'CSV', } -export const getRelationalInputType = (type: string): RelationalInputType => { - switch (type) { - case RelationalInputType.SQL: - return RelationalInputType.SQL; - case RelationalInputType.CSV: - return RelationalInputType.CSV; - default: - throw new UnsupportedOperationError( - `Encountered unsupported relational input type '${type}'`, - ); - } -}; - export class RelationalInputData extends InputData implements Hashable { database: PackageableElementReference; data: string; @@ -63,7 +46,8 @@ export class RelationalInputData extends InputData implements Hashable { } get validationResult(): ValidationIssue | undefined { - if (this.database.value.isStub) { + // TODO: use `isStubbed_PackageableElement` when we refactor validation + if (!this.database.value.package && !this.database.value.name) { return createValidationError([ 'Relational input data source database store is missing', ]); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInstanceSetImplementation.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInstanceSetImplementation.ts index 664612f3a44..f1fdd4904eb 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInstanceSetImplementation.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalInstanceSetImplementation.ts @@ -14,13 +14,12 @@ * limitations under the License. */ -import { type Hashable, hashArray, filterByType } from '@finos/legend-shared'; +import { type Hashable, hashArray, isEmpty } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; import { InstanceSetImplementation } from '../../../mapping/InstanceSetImplementation'; import type { SetImplementationVisitor } from '../../../mapping/SetImplementation'; import type { RelationalOperationElement } from '../model/RelationalOperationElement'; -import type { PropertyMapping } from '../../../mapping/PropertyMapping'; -import { EmbeddedRelationalInstanceSetImplementation } from './EmbeddedRelationalInstanceSetImplementation'; +import { RelationalPropertyMapping } from './RelationalPropertyMapping'; export class RelationalInstanceSetImplementation extends InstanceSetImplementation @@ -28,34 +27,6 @@ export class RelationalInstanceSetImplementation { primaryKey: RelationalOperationElement[] = []; - getEmbeddedSetImplmentations(): InstanceSetImplementation[] { - const embeddedPropertyMappings = this.propertyMappings.filter( - filterByType(EmbeddedRelationalInstanceSetImplementation), - ); - return embeddedPropertyMappings - .map((propertyMapping) => propertyMapping.getEmbeddedSetImplmentations()) - .flat() - .concat(embeddedPropertyMappings); - } - - findPropertyMapping( - propertyName: string, - targetId: string | undefined, - ): PropertyMapping | undefined { - let properties = undefined; - properties = this.propertyMappings.filter( - (propertyMapping) => propertyMapping.property.value.name === propertyName, - ); - if (targetId === undefined || properties.length === 1) { - return properties[0]; - } - return properties.find( - (propertyMapping) => - propertyMapping.targetSetImplementation && - propertyMapping.targetSetImplementation.id.value === targetId, - ); - } - accept_SetImplementationVisitor(visitor: SetImplementationVisitor): T { return visitor.visit_RelationalInstanceSetImplementation(this); } @@ -67,7 +38,15 @@ export class RelationalInstanceSetImplementation hashArray(this.primaryKey), hashArray( this.propertyMappings.filter( - (propertyMapping) => !propertyMapping.isStub, + // TODO: we should also handle of other property mapping types + // using some form of extension mechanism + (propertyMapping) => { + if (propertyMapping instanceof RelationalPropertyMapping) { + // TODO: use `isStubbed_RawRelationalOperationElement` when we move this out of the metamodel + return !isEmpty(propertyMapping.relationalOperation); + } + return true; + }, ), ), ]); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping.ts index e5834f361f6..44df63c9624 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping.ts @@ -22,10 +22,7 @@ import { PropertyMapping, } from '../../../mapping/PropertyMapping'; import { hashObjectWithoutSourceInformation } from '../../../../../../../MetaModelUtils'; -import { - isStubRelationalOperationElement, - type RawRelationalOperationElement, -} from '../model/RawRelationalOperationElement'; +import type { RawRelationalOperationElement } from '../model/RawRelationalOperationElement'; import type { BindingTransformer } from '../../../externalFormat/store/DSLExternalFormat_BindingTransformer'; export class RelationalPropertyMapping @@ -46,10 +43,6 @@ export class RelationalPropertyMapping return visitor.visit_RelationalPropertyMapping(this); } - override get isStub(): boolean { - return isStubRelationalOperationElement(this.relationalOperation); - } - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.REALTIONAL_PROPERTY_MAPPING, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/ColumnReference.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/ColumnReference.ts index b2e9fb17698..8aa229f0723 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/ColumnReference.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/ColumnReference.ts @@ -22,7 +22,21 @@ import { import { ReferenceWithOwner } from '../../../../Reference'; import type { Database } from './Database'; import type { Column } from './Column'; -import { getSchemaFromRelation } from './RelationReference'; +import type { Relation } from './RelationalOperationElement'; +import type { Schema } from './Schema'; +import { View } from './View'; +import { Table } from './Table'; +import { UnsupportedOperationError } from '@finos/legend-shared'; + +const getSchemaFromRelation = (value: Relation): Schema => { + if (value instanceof Table || value instanceof View) { + return value.schema; + } + throw new UnsupportedOperationError( + `Can't derive schema for relation`, + value, + ); +}; export abstract class ColumnReference extends ReferenceWithOwner { override readonly ownerReference: PackageableElementReference; diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Database.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Database.ts index 13d3d121c01..fb39db9ca81 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Database.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Database.ts @@ -14,46 +14,19 @@ * limitations under the License. */ -import { - hashArray, - guaranteeNonNullable, - type Hashable, -} from '@finos/legend-shared'; +import { hashArray, type Hashable } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; import { Store } from '../../Store'; import type { PackageableElementVisitor } from '../../../PackageableElement'; import type { Schema } from './Schema'; import type { Join } from './Join'; import type { Filter } from './Filter'; -import { getAllIncludedDbs } from '../../../../../../../helpers/DatabaseHelper'; export class Database extends Store implements Hashable { schemas: Schema[] = []; joins: Join[] = []; filters: Filter[] = []; - static createStub = (): Database => new Database(''); - - getSchema = (name: string): Schema => - guaranteeNonNullable( - this.schemas.find((schema) => schema.name === name), - `Can't find schema '${name}' in database '${this.path}'`, - ); - - getJoin = (name: string): Join => - guaranteeNonNullable( - Array.from(getAllIncludedDbs(this)) - .flatMap((db) => db.joins) - .find((join) => join.name === name), - `Can't find join '${name}' in database '${this.path}'`, - ); - - getFilter = (name: string): Filter => - guaranteeNonNullable( - this.filters.find((filter) => filter.name === name), - `Can't find filter '${name}' in database '${this.path}'`, - ); - protected override get _elementHashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.DATABASE, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RawRelationalOperationElement.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RawRelationalOperationElement.ts index ab50e6e8de2..85495339888 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RawRelationalOperationElement.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RawRelationalOperationElement.ts @@ -14,18 +14,9 @@ * limitations under the License. */ -import { isEmpty } from '@finos/legend-shared'; - /** * Studio does not process value specification, they are left in raw JSON form * * @discrepancy model */ export type RawRelationalOperationElement = object; - -export const createStubRelationalOperationElement = - (): RawRelationalOperationElement => ({}); - -export const isStubRelationalOperationElement = ( - operation: RawRelationalOperationElement, -): boolean => isEmpty(operation); diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RelationReference.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RelationReference.ts index e3148dbd925..308b9fefe28 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RelationReference.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RelationReference.ts @@ -21,22 +21,11 @@ import { Table } from './Table'; import type { Relation } from './RelationalOperationElement'; import { ViewExplicitReference, ViewImplicitReference } from './ViewReference'; import { View } from './View'; -import type { Schema } from './Schema'; import { TableExplicitReference, TableImplicitReference, } from './TableReference'; -export const getSchemaFromRelation = (value: Relation): Schema => { - if (value instanceof Table || value instanceof View) { - return value.schema; - } - throw new UnsupportedOperationError( - `Can't derive schema for relation`, - value, - ); -}; - export const createExplicitRelationReference = ( value: Relation, ): TableExplicitReference | ViewExplicitReference => { diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RelationalOperationElement.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RelationalOperationElement.ts index 057b36b18f8..d27bc62d5e6 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RelationalOperationElement.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/RelationalOperationElement.ts @@ -85,21 +85,6 @@ export enum JoinType { RIGHT_OUTER = 'RIGHT_OUTER', } -export const getJoinType = (type: string): JoinType => { - switch (type) { - case JoinType.INNER: - return JoinType.INNER; - case JoinType.LEFT_OUTER: - return JoinType.LEFT_OUTER; - case JoinType.RIGHT_OUTER: - return JoinType.RIGHT_OUTER; - default: - throw new UnsupportedOperationError( - `Encountered unsupported join type '${type}'`, - ); - } -}; - // TODO: create RelationalTreeNode like in PURE? export class JoinTreeNode { alias?: TableAlias | undefined; // required in PURE diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Schema.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Schema.ts index dcc82eb8540..571825cba27 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Schema.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Schema.ts @@ -15,15 +15,10 @@ */ import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; -import { - type Hashable, - hashArray, - guaranteeNonNullable, -} from '@finos/legend-shared'; +import { type Hashable, hashArray } from '@finos/legend-shared'; import type { Database } from './Database'; import type { Table } from './Table'; import type { View } from './View'; -import type { Relation } from './RelationalOperationElement'; export class Schema implements Hashable { readonly _OWNER: Database; @@ -37,24 +32,6 @@ export class Schema implements Hashable { this._OWNER = owner; } - getTable = (name: string): Table => - guaranteeNonNullable( - this.tables.find((table) => table.name === name), - `Can't find table '${name}' in schema '${this.name}' of database '${this._OWNER.path}'`, - ); - getView = (name: string): View => - guaranteeNonNullable( - this.views.find((view) => view.name === name), - `Can't find view '${name}' in schema '${this.name}' of database '${this._OWNER.path}'`, - ); - getRelation = (name: string): Relation => { - const relations: (Table | View)[] = this.tables; - return guaranteeNonNullable( - relations.concat(this.views).find((relation) => relation.name === name), - `Can't find relation '${name}' in schema '${this.name}' of database '${this._OWNER.path}'`, - ); - }; - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.DATABASE_SCHEMA, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Table.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Table.ts index ea55355e108..ea0dd62868e 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Table.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/Table.ts @@ -15,15 +15,10 @@ */ import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; -import { - type Hashable, - hashArray, - guaranteeNonNullable, - filterByType, -} from '@finos/legend-shared'; +import { type Hashable, hashArray } from '@finos/legend-shared'; import { NamedRelation } from './RelationalOperationElement'; import type { Schema } from './Schema'; -import { Column } from './Column'; +import type { Column } from './Column'; import type { Milestoning } from './milestoning/Milestoning'; export class Table extends NamedRelation implements Hashable { @@ -37,14 +32,6 @@ export class Table extends NamedRelation implements Hashable { this.schema = schema; } - getColumn = (name: string): Column => - guaranteeNonNullable( - this.columns - .filter(filterByType(Column)) - .find((column) => column.name === name), - `Can't find column '${name}' in table '${this.name}'`, - ); - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.DATABASE_SCHEMA_TABLE, diff --git a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/View.ts b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/View.ts index e5b183e7ce1..06097079252 100644 --- a/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/View.ts +++ b/packages/legend-graph/src/models/metamodels/pure/packageableElements/store/relational/model/View.ts @@ -14,16 +14,11 @@ * limitations under the License. */ -import { - type Hashable, - hashArray, - guaranteeNonNullable, - filterByType, -} from '@finos/legend-shared'; +import { type Hashable, hashArray } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; import type { ColumnMapping } from './ColumnMapping'; import type { Schema } from './Schema'; -import { Column } from './Column'; +import type { Column } from './Column'; import { type RelationalMappingSpecification, NamedRelation, @@ -47,14 +42,6 @@ export class View this.schema = schema; } - getColumn = (name: string): Column => - guaranteeNonNullable( - this.columns - .filter(filterByType(Column)) - .find((column) => column.name === name), - `Can't find column '${name}' in table '${this.name}'`, - ); - override get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.DATBASE_VIEW, diff --git a/packages/legend-graph/src/models/metamodels/pure/rawValueSpecification/RawLambda.ts b/packages/legend-graph/src/models/metamodels/pure/rawValueSpecification/RawLambda.ts index 9cca76967ab..c417ab23f66 100644 --- a/packages/legend-graph/src/models/metamodels/pure/rawValueSpecification/RawLambda.ts +++ b/packages/legend-graph/src/models/metamodels/pure/rawValueSpecification/RawLambda.ts @@ -21,12 +21,8 @@ import { type RawValueSpecificationVisitor, RawValueSpecification, } from './RawValueSpecification'; -import type { Stubable } from '../../../../helpers/Stubable'; -export class RawLambda - extends RawValueSpecification - implements Hashable, Stubable -{ +export class RawLambda extends RawValueSpecification implements Hashable { body?: object | undefined; parameters?: object | undefined; @@ -36,11 +32,6 @@ export class RawLambda this.body = body; } - static createStub = (): RawLambda => new RawLambda(undefined, undefined); - get isStub(): boolean { - return !this.body && !this.parameters; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.RAW_LAMBDA, diff --git a/packages/legend-graph/src/models/metamodels/pure/rawValueSpecification/RawVariableExpression.ts b/packages/legend-graph/src/models/metamodels/pure/rawValueSpecification/RawVariableExpression.ts index afc4884482d..dee85c42253 100644 --- a/packages/legend-graph/src/models/metamodels/pure/rawValueSpecification/RawVariableExpression.ts +++ b/packages/legend-graph/src/models/metamodels/pure/rawValueSpecification/RawVariableExpression.ts @@ -17,12 +17,8 @@ import { hashArray, uuid, type Hashable } from '@finos/legend-shared'; import { CORE_HASH_STRUCTURE } from '../../../../MetaModelConst'; import type { Type } from '../packageableElements/domain/Type'; -import { Multiplicity } from '../packageableElements/domain/Multiplicity'; -import type { Stubable } from '../../../../helpers/Stubable'; -import { - type PackageableElementReference, - PackageableElementExplicitReference, -} from '../packageableElements/PackageableElementReference'; +import type { Multiplicity } from '../packageableElements/domain/Multiplicity'; +import type { PackageableElementReference } from '../packageableElements/PackageableElementReference'; import { type RawValueSpecificationVisitor, RawValueSpecification, @@ -30,7 +26,7 @@ import { export class RawVariableExpression extends RawValueSpecification - implements Hashable, Stubable + implements Hashable { readonly _UUID = uuid(); @@ -49,16 +45,6 @@ export class RawVariableExpression this.type = type; } - static createStub = (type: Type): RawVariableExpression => - new RawVariableExpression( - '', - new Multiplicity(1, 1), - PackageableElementExplicitReference.create(type), - ); - get isStub(): boolean { - return !this.name; - } - get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.RAW_VARIABLE, diff --git a/packages/legend-graph/src/models/metamodels/pure/test/Testable.ts b/packages/legend-graph/src/models/metamodels/pure/test/Testable.ts index 8f719c6301f..63efc05475b 100644 --- a/packages/legend-graph/src/models/metamodels/pure/test/Testable.ts +++ b/packages/legend-graph/src/models/metamodels/pure/test/Testable.ts @@ -14,51 +14,8 @@ * limitations under the License. */ -import { isNonNullable } from '@finos/legend-shared'; -import type { PureModel } from '../../../../graph/PureModel'; -import type { PureGraphManagerPlugin } from '../../../../graphManager/PureGraphManagerPlugin'; -import { PackageableElement } from '../packageableElements/PackageableElement'; import type { Test } from './Test'; export interface Testable { tests: Test[]; } - -export type TestableIDBuilder = ( - testable: Testable, - graph: PureModel, -) => string | undefined; - -export type TestableFinder = ( - id: string, - graph: PureModel, -) => Testable | undefined; - -export type TestablesCollector = (graph: PureModel) => Testable[]; - -export const getNullableTestable = ( - id: string, - graph: PureModel, - pureGraphManagerPlugins: PureGraphManagerPlugin[], -): Testable | undefined => - graph.allOwnTestables.find( - (e) => e instanceof PackageableElement && e.path === id, - ) ?? - pureGraphManagerPlugins - .flatMap((plugin) => plugin.getExtraTestableFinders?.() ?? []) - .map((getter) => getter(id, graph)) - .filter(isNonNullable)[0]; - -export const getNullableIdFromTestable = ( - testable: Testable, - graph: PureModel, - pureGraphManagerPlugins: PureGraphManagerPlugin[], -): string | undefined => { - if (testable instanceof PackageableElement) { - return testable.path; - } - return pureGraphManagerPlugins - .flatMap((plugin) => plugin.getExtraTestableIDBuilders?.() ?? []) - .map((getter) => getter(testable, graph)) - .filter(isNonNullable)[0]; -}; diff --git a/packages/legend-graph/src/models/protocols/pure/DSLExternalFormat_PureProtocolProcessorPlugin.ts b/packages/legend-graph/src/models/protocols/pure/DSLExternalFormat_PureProtocolProcessorPlugin.ts index 1390472ba6c..0551f1dd497 100644 --- a/packages/legend-graph/src/models/protocols/pure/DSLExternalFormat_PureProtocolProcessorPlugin.ts +++ b/packages/legend-graph/src/models/protocols/pure/DSLExternalFormat_PureProtocolProcessorPlugin.ts @@ -261,7 +261,7 @@ export class DSLExternalFormat_PureProtocolProcessorPlugin const protocol = new V1_Binding(); V1_initPackageableElement(protocol, metamodel); protocol.name = metamodel.name; - protocol.package = metamodel.package?.fullPath ?? ''; + protocol.package = metamodel.package?.path ?? ''; protocol.schemaId = metamodel.schemaId; protocol.schemaSet = metamodel.schemaSet.valueForSerialization; protocol.contentType = metamodel.contentType; @@ -285,7 +285,7 @@ export class DSLExternalFormat_PureProtocolProcessorPlugin const protocol = new V1_SchemaSet(); V1_initPackageableElement(protocol, metamodel); protocol.name = metamodel.name; - protocol.package = metamodel.package?.fullPath ?? ''; + protocol.package = metamodel.package?.path ?? ''; protocol.format = metamodel.format; protocol.schemas = metamodel.schemas.map((schema) => { const schemaProtocol = new V1_Schema(); diff --git a/packages/legend-graph/src/models/protocols/pure/v1/V1_PureGraphManager.ts b/packages/legend-graph/src/models/protocols/pure/v1/V1_PureGraphManager.ts index 49ce3722706..e5792dc5da9 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/V1_PureGraphManager.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/V1_PureGraphManager.ts @@ -26,6 +26,7 @@ import { type Log, type PlainObject, type ServerClientConfig, + type ActionState, TracerService, LogEvent, getClass, @@ -35,11 +36,10 @@ import { assertTrue, assertErrorThrown, promisify, - type ActionState, StopWatch, - assertNonEmptyString, filterByType, isNonNullable, + guaranteeNonEmptyString, } from '@finos/legend-shared'; import type { TEMPORARY__AbstractEngineConfig } from '../../../../graphManager/action/TEMPORARY__AbstractEngineConfig'; import { @@ -248,12 +248,13 @@ import type { RunTestsTestableInput } from '../../../metamodels/pure/test/result import { V1_buildTestsResult } from './engine/test/V1_RunTestsResult'; import type { TestResult } from '../../../metamodels/pure/test/result/TestResult'; import type { Service } from '../../../../DSLService_Exports'; +import type { Testable } from '../../../metamodels/pure/test/Testable'; +import { stub_RawLambda } from '../../../../graphManager/action/creation/RawValueSpecificationCreatorHelper'; import { - type Testable, - getNullableIdFromTestable, + getNullableIDFromTestable, getNullableTestable, -} from '../../../metamodels/pure/test/Testable'; -import type { PureGraphManagerPlugin } from '../../../../graphManager/PureGraphManagerPlugin'; +} from '../../../../helpers/Testable_Helper'; +import { V1_getIncludedMappingPath } from './helper/V1_DSLMapping_Helper'; const V1_FUNCTION_SUFFIX_MULTIPLICITY_INFINITE = 'MANY'; @@ -1628,19 +1629,18 @@ export class V1_PureGraphManager extends AbstractPureGraphManager { // ------------------------------------------- Test ------------------------------------------- async runTests( + inputs: RunTestsTestableInput[], graph: PureModel, - pureGraphManagerPlugins: PureGraphManagerPlugin[], - testableInputs: RunTestsTestableInput[], ): Promise { const runTestsInput = new V1_RunTestsInput(); runTestsInput.model = this.getFullGraphModelData(graph); - runTestsInput.testables = testableInputs + runTestsInput.testables = inputs .map((input) => { const testable = guaranteeNonNullable( - getNullableIdFromTestable( + getNullableIDFromTestable( input.testable, graph, - pureGraphManagerPlugins, + this.pluginManager.getPureGraphManagerPlugins(), ), ); if (!testable) { @@ -1657,10 +1657,16 @@ export class V1_PureGraphManager extends AbstractPureGraphManager { return runTestableInput; }) .filter(isNonNullable); - const testableFromIdGetter = (id: string): Testable | undefined => - getNullableTestable(id, graph, pureGraphManagerPlugins); const runTestsResult = await this.engine.runTests(runTestsInput); - const result = V1_buildTestsResult(runTestsResult, testableFromIdGetter); + const result = V1_buildTestsResult( + runTestsResult, + (id: string): Testable | undefined => + getNullableTestable( + id, + graph, + this.pluginManager.getPureGraphManagerPlugins(), + ), + ); return result; } @@ -2253,16 +2259,18 @@ export class V1_PureGraphManager extends AbstractPureGraphManager { v1Mappings.forEach((element) => { const mapping = mappings.find((e) => e.path === element.path); if (mapping) { - mapping.includes = element.includedMappings.map((i) => { - assertNonEmptyString( - i.includedMappingPath, - `Mapping include 'includedMappingPath' field is missing or empty`, - ); - return new MappingInclude( - mapping, - context.resolveMapping(i.includedMappingPath), - ); - }); + mapping.includes = element.includedMappings.map( + (i) => + new MappingInclude( + mapping, + context.resolveMapping( + guaranteeNonEmptyString( + V1_getIncludedMappingPath(i), + `Mapping include path is missing or empty`, + ), + ), + ), + ); } }); // handle runtimes @@ -2327,7 +2335,7 @@ export class V1_PureGraphManager extends AbstractPureGraphManager { if (serviceExecution instanceof V1_PureMultiExecution) { const execution = new PureMultiExecution( serviceExecution.executionKey, - RawLambda.createStub(), + stub_RawLambda(), service, ); execution.executionParameters = @@ -2342,7 +2350,7 @@ export class V1_PureGraphManager extends AbstractPureGraphManager { service.execution = execution; } else if (serviceExecution instanceof V1_PureSingleExecution) { service.execution = new PureSingleExecution( - RawLambda.createStub(), + stub_RawLambda(), service, PackageableElementExplicitReference.create(new Mapping('')), new EngineRuntime(), diff --git a/packages/legend-graph/src/helpers/ValueSpecificationHelper.ts b/packages/legend-graph/src/models/protocols/pure/v1/helper/V1_DSLMapping_Helper.ts similarity index 57% rename from packages/legend-graph/src/helpers/ValueSpecificationHelper.ts rename to packages/legend-graph/src/models/protocols/pure/v1/helper/V1_DSLMapping_Helper.ts index b304156242b..008bb992e46 100644 --- a/packages/legend-graph/src/helpers/ValueSpecificationHelper.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/helper/V1_DSLMapping_Helper.ts @@ -14,7 +14,12 @@ * limitations under the License. */ -import { RawLambda } from '../models/metamodels/pure/rawValueSpecification/RawLambda'; +import { ELEMENT_PATH_DELIMITER } from '../../../../../MetaModelConst'; +import type { V1_MappingInclude } from '../model/packageableElements/mapping/V1_MappingInclude'; -export const createStubRawLambda = (): RawLambda => - new RawLambda(undefined, undefined); +export const V1_getIncludedMappingPath = ( + mappingInclude: V1_MappingInclude, +): string => + mappingInclude.includedMapping + ? mappingInclude.includedMapping + : `${mappingInclude.includedMappingPackage}${ELEMENT_PATH_DELIMITER}${mappingInclude.includedMappingName}`; diff --git a/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/V1_PackageableElement.ts b/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/V1_PackageableElement.ts index 3bc039f0c6f..fe07356174d 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/V1_PackageableElement.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/V1_PackageableElement.ts @@ -61,6 +61,13 @@ export abstract class V1_PackageableElement implements Hashable { package!: string; name!: string; + /** + * This logic is specific to the codebase and this is not part of the native metamodel. + * If needed, we can probably move this out as an utility or do type declaration merge + * and define this externally using `Object.defineProperty`. + * + * @internal model logic + */ get path(): string { return `${this.package}${ELEMENT_PATH_DELIMITER}${this.name}`; } diff --git a/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/domain/V1_Multiplicity.ts b/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/domain/V1_Multiplicity.ts index 8847aa01233..9128efa15a2 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/domain/V1_Multiplicity.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/domain/V1_Multiplicity.ts @@ -14,26 +14,18 @@ * limitations under the License. */ -import { - CORE_HASH_STRUCTURE, - MULTIPLICITY_INFINITE, -} from '../../../../../../../MetaModelConst'; +import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; import { hashArray, type Hashable } from '@finos/legend-shared'; export class V1_Multiplicity implements Hashable { lowerBound = 0; upperBound?: number | undefined; - get str(): string { - if (this.lowerBound === this.upperBound) { - return this.lowerBound.toString(); - } else if (this.lowerBound === 0 && this.upperBound === undefined) { - return MULTIPLICITY_INFINITE; - } - return `${this.lowerBound}..${this.upperBound ?? MULTIPLICITY_INFINITE}`; - } - get hashCode(): string { - return hashArray([CORE_HASH_STRUCTURE.MULTIPLICITY, this.str]); + return hashArray([ + CORE_HASH_STRUCTURE.MULTIPLICITY, + this.lowerBound.toString(), + this.upperBound?.toString() ?? '', + ]); } } diff --git a/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/mapping/V1_MappingInclude.ts b/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/mapping/V1_MappingInclude.ts index 233f7356fca..9f1263ebcf5 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/mapping/V1_MappingInclude.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/model/packageableElements/mapping/V1_MappingInclude.ts @@ -15,7 +15,10 @@ */ import { type Hashable, hashArray } from '@finos/legend-shared'; -import { CORE_HASH_STRUCTURE } from '../../../../../../../MetaModelConst'; +import { + CORE_HASH_STRUCTURE, + ELEMENT_PATH_DELIMITER, +} from '../../../../../../../MetaModelConst'; export class V1_MappingInclude implements Hashable { includedMapping?: string | undefined; @@ -28,15 +31,11 @@ export class V1_MappingInclude implements Hashable { get hashCode(): string { return hashArray([ CORE_HASH_STRUCTURE.MAPPING_INCLUDE, - this.includedMappingPath, + this.includedMapping + ? this.includedMapping + : `${this.includedMappingPackage}${ELEMENT_PATH_DELIMITER}${this.includedMappingName}`, this.sourceDatabasePath ?? '', this.targetDatabasePath ?? '', ]); } - - get includedMappingPath(): string { - return this.includedMapping - ? this.includedMapping - : `${this.includedMappingPackage}::${this.includedMappingName}`; - } } diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_CoreTransformerHelper.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_CoreTransformerHelper.ts index bd6136b8220..b0768ac86bd 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_CoreTransformerHelper.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_CoreTransformerHelper.ts @@ -52,7 +52,7 @@ export const V1_initPackageableElement = ( element: PackageableElement, ): void => { protocolElement.name = element.name; - protocolElement.package = element.package?.fullPath ?? ''; + protocolElement.package = element.package?.path ?? ''; }; export const V1_transformMultiplicity = ( diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_DomainTransformer.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_DomainTransformer.ts index 084f06a3e5e..a127f20d268 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_DomainTransformer.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_DomainTransformer.ts @@ -54,6 +54,7 @@ import { V1_Property } from '../../../model/packageableElements/domain/V1_Proper import { V1_DerivedProperty } from '../../../model/packageableElements/domain/V1_DerivedProperty'; import type { V1_RawVariable } from '../../../model/rawValueSpecification/V1_RawVariable'; import type { V1_GraphTransformerContext } from './V1_GraphTransformerContext'; +import { isStubbed_RawLambda } from '../../../../../../../graphManager/action/creation/RawValueSpecificationCreatorHelper'; export const V1_transformProfile = (element: Profile): V1_Profile => { const profile = new V1_Profile(); @@ -145,7 +146,10 @@ const transformConstraint = ( constraint.name = element.name; constraint.externalId = element.externalId; constraint.enforcementLevel = element.enforcementLevel; - if (element.messageFunction && !element.messageFunction.isStub) { + if ( + element.messageFunction && + !isStubbed_RawLambda(element.messageFunction) + ) { constraint.messageFunction = element.messageFunction.accept_RawValueSpecificationVisitor( new V1_RawValueSpecificationTransformer(context), diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_MappingTransformer.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_MappingTransformer.ts index 8a37189ad0f..cf1b47e556a 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_MappingTransformer.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/from/V1_MappingTransformer.ts @@ -30,7 +30,7 @@ import type { PropertyMappingVisitor, PropertyMapping, } from '../../../../../../metamodels/pure/packageableElements/mapping/PropertyMapping'; -import type { PurePropertyMapping } from '../../../../../../metamodels/pure/packageableElements/store/modelToModel/mapping/PurePropertyMapping'; +import { PurePropertyMapping } from '../../../../../../metamodels/pure/packageableElements/store/modelToModel/mapping/PurePropertyMapping'; import { Enum } from '../../../../../../metamodels/pure/packageableElements/domain/Enum'; import type { EnumValueMapping } from '../../../../../../metamodels/pure/packageableElements/mapping/EnumValueMapping'; import type { EnumerationMapping } from '../../../../../../metamodels/pure/packageableElements/mapping/EnumerationMapping'; @@ -43,7 +43,7 @@ import { import { FlatDataInputData } from '../../../../../../metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInputData'; import { ExpectedOutputMappingTestAssert } from '../../../../../../metamodels/pure/packageableElements/mapping/ExpectedOutputMappingTestAssert'; import { extractLine } from '../../../../../../metamodels/pure/packageableElements/store/relational/model/RelationalOperationElement'; -import type { FlatDataPropertyMapping } from '../../../../../../metamodels/pure/packageableElements/store/flatData/mapping/FlatDataPropertyMapping'; +import { FlatDataPropertyMapping } from '../../../../../../metamodels/pure/packageableElements/store/flatData/mapping/FlatDataPropertyMapping'; import type { EmbeddedFlatDataPropertyMapping } from '../../../../../../metamodels/pure/packageableElements/store/flatData/mapping/EmbeddedFlatDataPropertyMapping'; import type { PureInstanceSetImplementation } from '../../../../../../metamodels/pure/packageableElements/store/modelToModel/mapping/PureInstanceSetImplementation'; import { @@ -53,7 +53,7 @@ import { import type { FlatDataInstanceSetImplementation } from '../../../../../../metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInstanceSetImplementation'; import type { RelationalInstanceSetImplementation } from '../../../../../../metamodels/pure/packageableElements/store/relational/mapping/RelationalInstanceSetImplementation'; import type { RootRelationalInstanceSetImplementation } from '../../../../../../metamodels/pure/packageableElements/store/relational/mapping/RootRelationalInstanceSetImplementation'; -import type { RelationalPropertyMapping } from '../../../../../../metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping'; +import { RelationalPropertyMapping } from '../../../../../../metamodels/pure/packageableElements/store/relational/mapping/RelationalPropertyMapping'; import type { EmbeddedRelationalInstanceSetImplementation } from '../../../../../../metamodels/pure/packageableElements/store/relational/mapping/EmbeddedRelationalInstanceSetImplementation'; import type { InlineEmbeddedRelationalInstanceSetImplementation } from '../../../../../../metamodels/pure/packageableElements/store/relational/mapping/InlineEmbeddedRelationalInstanceSetImplementation'; import type { OtherwiseEmbeddedRelationalInstanceSetImplementation } from '../../../../../../metamodels/pure/packageableElements/store/relational/mapping/OtherwiseEmbeddedRelationalInstanceSetImplementation'; @@ -151,6 +151,9 @@ import { V1_BindingTransformer } from '../../../model/packageableElements/extern import { V1_MergeOperationClassMapping } from '../../../model/packageableElements/mapping/V1_MergeOperationClassMapping'; import { MergeOperationSetImplementation } from '../../../../../../metamodels/pure/packageableElements/mapping/MergeOperationSetImplementation'; import type { TEMPORARY__UnresolvedSetImplementation } from '../../../../../../metamodels/pure/packageableElements/mapping/TEMPORARY__UnresolvedSetImplementation'; +import { isStubbed_EnumValueMapping } from '../../../../../../../graphManager/action/creation/DSLMapping_ModelCreatorHelper'; +import { isStubbed_RawLambda } from '../../../../../../../graphManager/action/creation/RawValueSpecificationCreatorHelper'; +import { isStubbed_RawRelationalOperationElement } from '../../../../../../../graphManager/action/creation/StoreRelational_ModelCreatorHelper'; export const V1_transformPropertyReference = ( element: PropertyReference, @@ -191,7 +194,7 @@ const transformEnumValueMapping = ( const enumValueMapping = new V1_EnumValueMapping(); enumValueMapping.enumValue = element.enum.value.name; enumValueMapping.sourceValues = element.sourceValues - .filter((s) => !s.isStub) + .filter(isNonNullable) .map((value) => { if (typeof value.value === 'string') { const _string = new V1_EnumValueMappingStringSourceValue(); @@ -220,7 +223,7 @@ const transformEnumerationMapping = ( ): V1_EnumerationMapping => { const enumerationMapping = new V1_EnumerationMapping(); enumerationMapping.enumValueMappings = element.enumValueMappings - .filter((e) => !e.isStub) + .filter((e) => !isStubbed_EnumValueMapping(e)) .map(transformEnumValueMapping); enumerationMapping.enumeration = V1_transformElementReference( element.enumeration, @@ -229,7 +232,7 @@ const transformEnumerationMapping = ( return enumerationMapping; }; -// V1_Mapping Test +// Mapping Test export const V1_getObjectInputType = (type: string): V1_ObjectInputType => { switch (type) { @@ -366,7 +369,21 @@ const transformClassMappingPropertyMappings = ( isTransformingSourceId: boolean, ): V1_PropertyMapping[] => values - .filter((value) => !value.isStub) + // TODO: we should also handle of other property mapping types + // using some form of extension mechanism + .filter((value) => { + /* @MARKER: NEW CLASS MAPPING TYPE SUPPORT --- consider adding class mapping type handler here whenever support for a new one is added to the app */ + if (value instanceof PurePropertyMapping) { + return !isStubbed_RawLambda(value.transform); + } else if (value instanceof FlatDataPropertyMapping) { + return !isStubbed_RawLambda(value.transform); + } else if (value instanceof RelationalPropertyMapping) { + return !isStubbed_RawRelationalOperationElement( + value.relationalOperation, + ); + } + return true; + }) .map((value) => transformProperyMapping( value, @@ -392,7 +409,7 @@ const transformSimpleFlatDataPropertyMapping = ( flatDataPropertyMapping.target = transformPropertyMappingTarget( element.targetSetImplementation, ); - if (!element.transform.isStub) { + if (!isStubbed_RawLambda(element.transform)) { flatDataPropertyMapping.transform = element.transform.accept_RawValueSpecificationVisitor( new V1_RawValueSpecificationTransformer(context), @@ -453,7 +470,7 @@ const transformPurePropertyMapping = ( purePropertyMapping.target = transformPropertyMappingTarget( element.targetSetImplementation, ); - if (!element.transform.isStub) { + if (!isStubbed_RawLambda(element.transform)) { purePropertyMapping.transform = element.transform.accept_RawValueSpecificationVisitor( new V1_RawValueSpecificationTransformer(context), @@ -683,7 +700,7 @@ const transformXStorePropertyMapping = ( xstore.target = transformPropertyMappingTarget( element.targetSetImplementation, ); - if (!element.crossExpression.isStub) { + if (!isStubbed_RawLambda(element.crossExpression)) { xstore.crossExpression = element.crossExpression.accept_RawValueSpecificationVisitor( new V1_RawValueSpecificationTransformer(context), @@ -1000,12 +1017,12 @@ const transformAggregationFunctionSpecification = ( context: V1_GraphTransformerContext, ): V1_AggregateFunction => { const func = new V1_AggregateFunction(); - if (!element.mapFn.isStub) { + if (!isStubbed_RawLambda(element.mapFn)) { func.mapFn = element.mapFn.accept_RawValueSpecificationVisitor( new V1_RawValueSpecificationTransformer(context), ) as V1_RawLambda; } - if (!element.aggregateFn.isStub) { + if (!isStubbed_RawLambda(element.aggregateFn)) { func.aggregateFn = element.aggregateFn.accept_RawValueSpecificationVisitor( new V1_RawValueSpecificationTransformer(context), ) as V1_RawLambda; @@ -1018,7 +1035,7 @@ const transformGroupByFunctionSpec = ( context: V1_GraphTransformerContext, ): V1_GroupByFunction => { const func = new V1_GroupByFunction(); - if (!element.groupByFn.isStub) { + if (!isStubbed_RawLambda(element.groupByFn)) { func.groupByFn = element.groupByFn.accept_RawValueSpecificationVisitor( new V1_RawValueSpecificationTransformer(context), ) as V1_RawLambda; diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_GraphBuilderContext.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_GraphBuilderContext.ts index 410bba9b1ca..b7d5d7959c7 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_GraphBuilderContext.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_GraphBuilderContext.ts @@ -80,6 +80,21 @@ import type { GraphBuilderOptions } from '../../../../../../../graphManager/Abst import { DataType } from '../../../../../../metamodels/pure/packageableElements/domain/DataType'; import { GraphBuilderError } from '../../../../../../../graphManager/GraphManagerUtils'; import type { DataElement } from '../../../../../../../DSLData_Exports'; +import { + getClassProperty, + getEnumValue, + getOwnClassProperty, + getStereotype, + getTag, +} from '../../../../../../../helpers/DomainHelper'; +import { + getFilter, + getJoin, +} from '../../../../../../../helpers/StoreRelational_Helper'; +import { + getRootRecordType, + getSection, +} from '../../../../../../../helpers/StoreFlatData_Helper'; export const V1_buildFullPath = ( packagePath: string | undefined, @@ -152,7 +167,7 @@ export class V1_GraphBuilderContext { */ get enableRawLambdaAutoPathResolution(): boolean { return ( - this.graph.root.path === ROOT_PACKAGE_NAME.MAIN && + this.graph.root.name === ROOT_PACKAGE_NAME.MAIN && !this.options?.TEMPORARY__preserveSectionIndex ); } @@ -275,7 +290,7 @@ export class V1_GraphBuilderContext { `Steoreotype pointer 'value' field is missing or empty`, ); const ownerReference = this.resolveProfile(stereotypePtr.profile); - const value = ownerReference.value.getStereotype(stereotypePtr.value); + const value = getStereotype(ownerReference.value, stereotypePtr.value); return StereotypeImplicitReference.create(ownerReference, value); }; @@ -289,7 +304,7 @@ export class V1_GraphBuilderContext { `Tag pointer 'value' field is missing or empty`, ); const ownerReference = this.resolveProfile(tagPtr.profile); - const value = ownerReference.value.getTag(tagPtr.value); + const value = getTag(ownerReference.value, tagPtr.value); return TagImplicitReference.create(ownerReference, value); }; @@ -299,7 +314,7 @@ export class V1_GraphBuilderContext { return GenericTypeImplicitReference.create(ownerReference, value); }; - resolveOwnedProperty = ( + resolveOwnProperty = ( propertyPtr: V1_PropertyPointer, ): PropertyImplicitReference => { assertNonEmptyString( @@ -311,7 +326,10 @@ export class V1_GraphBuilderContext { `Property pointer 'property' field is missing or empty`, ); const ownerReference = this.resolveClass(propertyPtr.class); - const value = ownerReference.value.getOwnedProperty(propertyPtr.property); + const value = getOwnClassProperty( + ownerReference.value, + propertyPtr.property, + ); return PropertyImplicitReference.create(ownerReference, value); }; @@ -327,7 +345,7 @@ export class V1_GraphBuilderContext { `Property pointer 'property' field is missing or empty`, ); const ownerReference = this.resolveClass(propertyPtr.class); - const value = ownerReference.value.getProperty(propertyPtr.property); + const value = getClassProperty(ownerReference.value, propertyPtr.property); return PropertyImplicitReference.create(ownerReference, value); }; @@ -343,9 +361,9 @@ export class V1_GraphBuilderContext { `Flat-data class mapping 'sectionName' field is missing or empty`, ); const ownerReference = this.resolveFlatDataStore(classMapping.flatData); - const value = ownerReference.value - .findSection(classMapping.sectionName) - .getRecordType(); + const value = getRootRecordType( + getSection(ownerReference.value, classMapping.sectionName), + ); return RootFlatDataRecordTypeImplicitReference.create( ownerReference, value, @@ -386,7 +404,7 @@ export class V1_GraphBuilderContext { `Join pointer 'name' field is missing or empty`, ); const ownerReference = this.resolveDatabase(joinPtr.db); - const value = ownerReference.value.getJoin(joinPtr.name); + const value = getJoin(ownerReference.value, joinPtr.name); return JoinImplicitReference.create(ownerReference, value); }; @@ -400,7 +418,7 @@ export class V1_GraphBuilderContext { `Filter pointer 'name' field is missing or empty`, ); const ownerReference = this.resolveDatabase(filterPtr.db); - const value = ownerReference.value.getFilter(filterPtr.name); + const value = getFilter(ownerReference.value, filterPtr.name); return FilterImplicitReference.create(ownerReference, value); }; @@ -409,7 +427,7 @@ export class V1_GraphBuilderContext { enumValue: string, ): EnumValueImplicitReference => { const ownerReference = this.resolveEnumeration(enumeration); - const value = ownerReference.value.getValue(enumValue); + const value = getEnumValue(ownerReference.value, enumValue); return EnumValueImplicitReference.create(ownerReference, value); }; diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelClassMappingSecondPassBuilder.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelClassMappingSecondPassBuilder.ts index cb804353269..a03c00c8aed 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelClassMappingSecondPassBuilder.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelClassMappingSecondPassBuilder.ts @@ -64,7 +64,7 @@ import { getAllClassMappings, getAllEnumerationMappings, getOwnClassMappingById, -} from '../../../../../../../helpers/MappingHelper'; +} from '../../../../../../../helpers/DSLMapping_Helper'; import type { DSLMapping_PureProtocolProcessorPlugin_Extension } from '../../../../DSLMapping_PureProtocolProcessorPlugin_Extension'; import type { V1_MergeOperationClassMapping } from '../../../model/packageableElements/mapping/V1_MergeOperationClassMapping'; diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelGraphSecondPassBuilder.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelGraphSecondPassBuilder.ts index 9fbe7bc8714..ec9036b96dc 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelGraphSecondPassBuilder.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelGraphSecondPassBuilder.ts @@ -81,6 +81,7 @@ import type { V1_DataElement } from '../../../model/packageableElements/data/V1_ import { V1_ProtocolToMetaModelEmbeddedDataBuilder } from './helpers/V1_DataElementBuilderHelper'; import { V1_buildTestSuite } from './helpers/V1_TestBuilderHelper'; import { ServiceTestSuite } from '../../../../../../metamodels/pure/packageableElements/service/ServiceTestSuite'; +import { V1_getIncludedMappingPath } from '../../../helper/V1_DSLMapping_Helper'; export class V1_ProtocolToMetaModelGraphSecondPassBuilder implements V1_PackageableElementVisitor @@ -278,15 +279,16 @@ export class V1_ProtocolToMetaModelGraphSecondPassBuilder ); const mappingIncludesSet = new Set(); mapping.includes = element.includedMappings.map((i) => { + const includedMappingPath = V1_getIncludedMappingPath(i); assertNonEmptyString( - i.includedMappingPath, - `Mapping include 'includedMappingPath' field is missing or empty`, + includedMappingPath, + `Mapping include path is missing or empty`, ); assertTrue( - !mappingIncludesSet.has(i.includedMappingPath), - `Duplicated mapping include '${i.includedMappingPath}' in mapping '${mapping.path}'`, + !mappingIncludesSet.has(includedMappingPath), + `Duplicated mapping include '${includedMappingPath}' in mapping '${mapping.path}'`, ); - mappingIncludesSet.add(i.includedMappingPath); + mappingIncludesSet.add(includedMappingPath); return V1_buildMappingInclude(i, this.context, mapping); }); mapping.enumerationMappings = element.enumerationMappings.map( diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelGraphThirdPassBuilder.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelGraphThirdPassBuilder.ts index 58e31bdf01e..e9f04edfedf 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelGraphThirdPassBuilder.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelGraphThirdPassBuilder.ts @@ -98,7 +98,7 @@ export class V1_ProtocolToMetaModelGraphThirdPassBuilder addUniqueEntry(_class.generalizations, genricTypeReference); if (genricTypeReference.ownerReference.value instanceof Class) { addUniqueEntry( - genricTypeReference.ownerReference.value.subclasses, + genricTypeReference.ownerReference.value._subclasses, _class, ); } diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelPropertyMappingBuilder.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelPropertyMappingBuilder.ts index 661c37d60d5..dd009b4d77e 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelPropertyMappingBuilder.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/V1_ProtocolToMetaModelPropertyMappingBuilder.ts @@ -83,13 +83,18 @@ import { getAllEnumerationMappings, getClassMappingById, getClassMappingsByClass, -} from '../../../../../../../helpers/MappingHelper'; +} from '../../../../../../../helpers/DSLMapping_Helper'; import { GraphBuilderError } from '../../../../../../../graphManager/GraphManagerUtils'; import type { AbstractProperty } from '../../../../../../metamodels/pure/packageableElements/domain/AbstractProperty'; import { BindingTransformer } from '../../../../../../metamodels/pure/packageableElements/externalFormat/store/DSLExternalFormat_BindingTransformer'; import type { Mapping } from '../../../../../../metamodels/pure/packageableElements/mapping/Mapping'; import { V1_resolveBinding } from './V1_DSLExternalFormat_GraphBuilderHelper'; import { TEMPORARY__UnresolvedSetImplementation } from '../../../../../../metamodels/pure/packageableElements/mapping/TEMPORARY__UnresolvedSetImplementation'; +import { + getAssociatedPropertyClass, + getOwnProperty, + getClassProperty, +} from '../../../../../../../helpers/DomainHelper'; /** * This test is skipped because we want to temporarily relax graph building algorithm @@ -117,11 +122,14 @@ const resolveRelationalPropertyMappingSource = ( value.source, ); } - const property = immediateParent.association.value.getProperty( + const property = getOwnProperty( + immediateParent.association.value, value.property.property, ); - const _class = - immediateParent.association.value.getPropertyAssociatedClass(property); + const _class = getAssociatedPropertyClass( + immediateParent.association.value, + property, + ); const setImpls = getClassMappingsByClass(immediateParent._PARENT, _class); return setImpls.find((r) => r.root.value) ?? setImpls[0]; } @@ -303,7 +311,10 @@ export class V1_ProtocolToMetaModelPropertyMappingBuilder ); } // NOTE: mapping for derived property is not supported - const property = propertyOwnerClass.getProperty(protocol.property.property); + const property = getClassProperty( + propertyOwnerClass, + protocol.property.property, + ); const sourceSetImplementation = guaranteeNonNullable( this.immediateParent instanceof EmbeddedFlatDataPropertyMapping ? this.immediateParent @@ -381,7 +392,10 @@ export class V1_ProtocolToMetaModelPropertyMappingBuilder `Can't find property owner class for property '${protocol.property.property}'`, ); } - const property = propertyOwnerClass.getProperty(protocol.property.property); + const property = getClassProperty( + propertyOwnerClass, + protocol.property.property, + ); let _class: PackageableElementReference; if (protocol.class) { _class = this.context.resolveClass(protocol.class); @@ -497,7 +511,10 @@ export class V1_ProtocolToMetaModelPropertyMappingBuilder `Can't find property owner class for property '${protocol.property.property}'`, ); } - property = propertyOwner.getProperty(protocol.property.property); + property = + propertyOwner instanceof Class + ? getClassProperty(propertyOwner, protocol.property.property) + : getOwnProperty(propertyOwner, protocol.property.property); } // NOTE: mapping for derived property is not supported // since we are not doing embedded property mappings yet, the target must have already been added to the mapping @@ -632,7 +649,10 @@ export class V1_ProtocolToMetaModelPropertyMappingBuilder `Can't find property owner class for property '${protocol.property.property}'`, ); } - const property = propertyOwnerClass.getProperty(protocol.property.property); + const property = getClassProperty( + propertyOwnerClass, + protocol.property.property, + ); const propertyType = property.genericType.value.rawType; const complexClass = guaranteeType( propertyType, @@ -826,7 +846,7 @@ export class V1_ProtocolToMetaModelPropertyMappingBuilder `XStore property 'xStoreParent' field is missing`, ); const _association = xStoreParent.association.value; - const property = _association.getProperty(protocol.property.property); + const property = getOwnProperty(_association, protocol.property.property); const sourceSetImplementation = this.allClassMappings.find( (c) => c.id.value === protocol.source, ); diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_AssociationMappingHelper.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_AssociationMappingHelper.ts index 38e247d4914..72cd7a22880 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_AssociationMappingHelper.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_AssociationMappingHelper.ts @@ -27,7 +27,10 @@ import { V1_ProtocolToMetaModelPropertyMappingBuilder } from '../../../../transf import type { V1_AssociationMapping } from '../../../../model/packageableElements/mapping/V1_AssociationMapping'; import { V1_XStoreAssociationMapping } from '../../../../model/packageableElements/mapping/xStore/V1_XStoreAssociationMapping'; import { XStoreAssociationImplementation } from '../../../../../../../metamodels/pure/packageableElements/mapping/xStore/XStoreAssociationImplementation'; -import { getAllEnumerationMappings } from '../../../../../../../../helpers/MappingHelper'; +import { + getAllEnumerationMappings, + getAllIncludedMappings, +} from '../../../../../../../../helpers/DSLMapping_Helper'; const getInferredAssociationMappingId = ( _association: Association, @@ -44,7 +47,10 @@ const buildRelationalAssociationMapping = ( parentMapping: Mapping, context: V1_GraphBuilderContext, ): RelationalAssociationImplementation => { - const allClassMappings = [parentMapping, ...parentMapping.allIncludedMappings] + const allClassMappings = [ + parentMapping, + ...getAllIncludedMappings(parentMapping), + ] .map((m) => m.classMappings) .flat(); const association = context.resolveAssociation(element.association); @@ -78,7 +84,10 @@ const buildXStoreAssociationMapping = ( parentMapping: Mapping, context: V1_GraphBuilderContext, ): XStoreAssociationImplementation => { - const allClassMappings = [parentMapping, ...parentMapping.allIncludedMappings] + const allClassMappings = [ + parentMapping, + ...getAllIncludedMappings(parentMapping), + ] .map((m) => m.classMappings) .flat(); const association = context.resolveAssociation(element.association); diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_DatabaseBuilderHelper.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_DatabaseBuilderHelper.ts index d134290aa15..8204bdd2893 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_DatabaseBuilderHelper.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_DatabaseBuilderHelper.ts @@ -25,9 +25,13 @@ import { } from '@finos/legend-shared'; import { Database } from '../../../../../../../metamodels/pure/packageableElements/store/relational/model/Database'; import { - getAllIncludedDbs, - getDatabaseNullableFilter, -} from '../../../../../../../../helpers/DatabaseHelper'; + getAllIncludedDatabases, + getColumn, + getJoinType, + getNullableFilter, + getSchema, + getView, +} from '../../../../../../../../helpers/StoreRelational_Helper'; import { Schema } from '../../../../../../../metamodels/pure/packageableElements/store/relational/model/Schema'; import { Table } from '../../../../../../../metamodels/pure/packageableElements/store/relational/model/Table'; import { Column } from '../../../../../../../metamodels/pure/packageableElements/store/relational/model/Column'; @@ -49,7 +53,6 @@ import { TableAliasColumn, JoinTreeNode, RelationalOperationElementWithJoin, - getJoinType, } from '../../../../../../../metamodels/pure/packageableElements/store/relational/model/RelationalOperationElement'; import { type RelationalDataType, @@ -164,7 +167,7 @@ export const V1_findRelation = ( tableName: string, ): Relation | undefined => { const relations: Relation[] = []; - getAllIncludedDbs(database).forEach((db) => { + getAllIncludedDatabases(database).forEach((db) => { const schema = db.schemas.find((_schema) => _schema.name === schemaName); if (schema) { let relation: Relation | undefined = schema.tables.find( @@ -190,10 +193,10 @@ const V1_findFilter = ( filterName: string, ): Filter | undefined => { let filter: Filter | undefined; - const dbs = getAllIncludedDbs(database).values(); + const dbs = getAllIncludedDatabases(database).values(); let db = dbs.next(); while (!filter && !db.done) { - filter = getDatabaseNullableFilter(filterName, db.value); + filter = getNullableFilter(db.value, filterName); db = dbs.next(); } return filter; @@ -270,7 +273,7 @@ export const V1_buildRelationalOperationElement = ( } const columnReference = ColumnImplicitReference.create( context.resolveDatabase(operationalElement.table.database), - relation.value.getColumn(operationalElement.column), + getColumn(relation.value, operationalElement.column), ); const tableAliasColumn = new TableAliasColumn(); tableAliasColumn.alias = guaranteeNonNullable(aliasMap.get(aliasName)); @@ -509,7 +512,7 @@ const buildViewSecondPass = ( context: V1_GraphBuilderContext, schema: Schema, ): View => { - const view = schema.getView(srcView.name); + const view = getView(schema, srcView.name); const columnMappings = srcView.columnMappings.map( (columnMapping) => new ColumnMapping( @@ -552,7 +555,7 @@ export const V1_buildDatabaseSchemaViewsFirstPass = ( database: Database, context: V1_GraphBuilderContext, ): Schema => { - const schema = database.getSchema(srcSchema.name); + const schema = getSchema(database, srcSchema.name); schema.views = srcSchema.views.map((view) => buildViewFirstPass(view, schema), ); @@ -564,7 +567,7 @@ export const V1_buildDatabaseSchemaViewsSecondPass = ( context: V1_GraphBuilderContext, database: Database, ): Schema => { - const schema = database.getSchema(srcSchema.name); + const schema = getSchema(database, srcSchema.name); schema.views = srcSchema.views.map((view) => buildViewSecondPass(view, context, schema), ); diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_DomainBuilderHelper.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_DomainBuilderHelper.ts index 9c39b1f1685..2350d450d6b 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_DomainBuilderHelper.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_DomainBuilderHelper.ts @@ -51,6 +51,7 @@ import type { V1_TaggedValue } from '../../../../model/packageableElements/domai import { V1_buildRawLambdaWithResolvedPaths } from './V1_ValueSpecificationPathResolver'; import { addElementToPackage, + getAllClassProperties, getOrCreateGraphPackage, } from '../../../../../../../../helpers/DomainHelper'; @@ -269,7 +270,9 @@ export const V1_getAppliedProperty = ( name: string, ): AbstractProperty => { // TODO: C3 Linearzation - let property = parentClass.getAllProperties().find((p) => p.name === name); + let property = getAllClassProperties(parentClass).find( + (p) => p.name === name, + ); if (property) { return property; } diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_MappingBuilderHelper.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_MappingBuilderHelper.ts index d74d83d9646..4eb5ca08b83 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_MappingBuilderHelper.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_MappingBuilderHelper.ts @@ -33,10 +33,7 @@ import { SourceValue, } from '../../../../../../../metamodels/pure/packageableElements/mapping/EnumValueMapping'; import { MappingTest } from '../../../../../../../metamodels/pure/packageableElements/mapping/MappingTest'; -import { - ObjectInputData, - getObjectInputType, -} from '../../../../../../../metamodels/pure/packageableElements/store/modelToModel/mapping/ObjectInputData'; +import { ObjectInputData } from '../../../../../../../metamodels/pure/packageableElements/store/modelToModel/mapping/ObjectInputData'; import type { InputData } from '../../../../../../../metamodels/pure/packageableElements/mapping/InputData'; import { FlatDataInputData } from '../../../../../../../metamodels/pure/packageableElements/store/flatData/mapping/FlatDataInputData'; import { ExpectedOutputMappingTestAssert } from '../../../../../../../metamodels/pure/packageableElements/mapping/ExpectedOutputMappingTestAssert'; @@ -66,11 +63,14 @@ import type { V1_ClassMapping } from '../../../../model/packageableElements/mapp import type { V1_MappingInclude } from '../../../../model/packageableElements/mapping/V1_MappingInclude'; import { V1_buildRawLambdaWithResolvedPaths } from './V1_ValueSpecificationPathResolver'; import { V1_RelationalInputData } from '../../../../model/packageableElements/store/relational/mapping/V1_RelationalInputData'; +import { RelationalInputData } from '../../../../../../../metamodels/pure/packageableElements/store/relational/mapping/RelationalInputData'; import { - getRelationalInputType, - RelationalInputData, -} from '../../../../../../../metamodels/pure/packageableElements/store/relational/mapping/RelationalInputData'; -import { getAllClassMappings } from '../../../../../../../../helpers/MappingHelper'; + getAllClassMappings, + getObjectInputType, +} from '../../../../../../../../helpers/DSLMapping_Helper'; +import { getRelationalInputType } from '../../../../../../../../helpers/StoreRelational_Helper'; +import { getEnumValue } from '../../../../../../../../helpers/DomainHelper'; +import { V1_getIncludedMappingPath } from '../../../../helper/V1_DSLMapping_Helper'; export const V1_getInferredClassMappingId = ( _class: Class, @@ -94,7 +94,7 @@ const buildEnumValueMapping = ( const enumValueMapping = new EnumValueMapping( EnumValueImplicitReference.create( enumerationReference, - enumerationReference.value.getValue(srcEnumValueMapping.enumValue), + getEnumValue(enumerationReference.value, srcEnumValueMapping.enumValue), ), ); // We will support processing for enumeration mappings with and without source type @@ -186,7 +186,7 @@ export const V1_buildMappingInclude = ( ): MappingInclude => { const includedMapping = new MappingInclude( parentMapping, - context.resolveMapping(mappingInclude.includedMappingPath), + context.resolveMapping(V1_getIncludedMappingPath(mappingInclude)), ); if (mappingInclude.sourceDatabasePath && mappingInclude.targetDatabasePath) { includedMapping.storeSubstitutions.push( diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_RelationalPropertyMappingBuilder.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_RelationalPropertyMappingBuilder.ts index 17e9bebd530..660959fa4f3 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_RelationalPropertyMappingBuilder.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_RelationalPropertyMappingBuilder.ts @@ -31,6 +31,7 @@ import type { V1_GraphBuilderContext } from '../../../../transformation/pureGrap import type { V1_EmbeddedRelationalPropertyMapping } from '../../../../model/packageableElements/store/relational/mapping/V1_EmbeddedRelationalPropertyMapping'; import { V1_getInferredClassMappingId } from '../../../../transformation/pureGraph/to/helpers/V1_MappingBuilderHelper'; import { GraphBuilderError } from '../../../../../../../../graphManager/GraphManagerUtils'; +import { getClassProperty } from '../../../../../../../../helpers/DomainHelper'; export const V1_buildEmbeddedRelationalMappingProperty = ( propertyMapping: V1_EmbeddedRelationalPropertyMapping, @@ -59,7 +60,8 @@ export const V1_buildEmbeddedRelationalMappingProperty = ( `Can't find property owner class for property '${propertyMapping.property.property}'`, ); } - const property = propertyOwnerClass.getProperty( + const property = getClassProperty( + propertyOwnerClass, propertyMapping.property.property, ); let _class: PackageableElementReference; diff --git a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_ValueSpecificationBuilderHelper.ts b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_ValueSpecificationBuilderHelper.ts index 458ccbc79c6..6efea68c6b3 100644 --- a/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_ValueSpecificationBuilderHelper.ts +++ b/packages/legend-graph/src/models/protocols/pure/v1/transformation/pureGraph/to/helpers/V1_ValueSpecificationBuilderHelper.ts @@ -121,6 +121,7 @@ import type { V1_HackedUnit } from '../../../../model/valueSpecification/raw/V1_ import type { V1_INTERNAL__UnknownValueSpecification } from '../../../../model/valueSpecification/V1_INTERNAL__UnknownValueSpecfication'; import { INTERNAL__UnknownValueSpecification } from '../../../../../../../metamodels/pure/valueSpecification/INTERNAL__UnknownValueSpecification'; import { GraphBuilderError } from '../../../../../../../../graphManager/GraphManagerUtils'; +import { getEnumValue } from '../../../../../../../../helpers/DomainHelper'; const LET_FUNCTION = 'letFunction'; @@ -888,7 +889,7 @@ export function V1_processProperty( context.graph.getTypicalMultiplicity(TYPICAL_MULTIPLICITY_TYPE.ONE), ); enumValueInstanceValue.values = [ - EnumValueExplicitReference.create(inferredType.getValue(property)), + EnumValueExplicitReference.create(getEnumValue(inferredType, property)), ]; return enumValueInstanceValue; } diff --git a/packages/legend-query/src/components/QueryBuilderExplorerPanel.tsx b/packages/legend-query/src/components/QueryBuilderExplorerPanel.tsx index 48144c81c12..8e9b9c11eed 100644 --- a/packages/legend-query/src/components/QueryBuilderExplorerPanel.tsx +++ b/packages/legend-query/src/components/QueryBuilderExplorerPanel.tsx @@ -72,6 +72,9 @@ import { PRIMITIVE_TYPE, Enumeration, TYPE_CAST_TOKEN, + getAllOwnClassProperties, + getAllClassProperties, + getAllClassDerivedProperties, } from '@finos/legend-graph'; import { useApplicationStore } from '@finos/legend-application'; import { getClassPropertyIcon } from './shared/ElementIconUtils'; @@ -692,10 +695,10 @@ const QueryBuilderExplorerTree = observer( node.type instanceof Class ) { (node instanceof QueryBuilderExplorerTreeSubTypeNodeData - ? node.type.getAllOwnedProperties() - : node.type - .getAllProperties() - .concat(node.type.getAllDerivedProperties()) + ? getAllOwnClassProperties(node.type) + : getAllClassProperties(node.type).concat( + getAllClassDerivedProperties(node.type), + ) ).forEach((property) => { const propertyTreeNodeData = getQueryBuilderPropertyNodeData( queryBuilderState.graphManagerState, @@ -705,7 +708,7 @@ const QueryBuilderExplorerTree = observer( ); treeData.nodes.set(propertyTreeNodeData.id, propertyTreeNodeData); }); - node.type.subclasses.forEach((subclass) => { + node.type._subclasses.forEach((subclass) => { const subTypeTreeNodeData = getQueryBuilderSubTypeNodeData( subclass, node, diff --git a/packages/legend-query/src/components/QueryBuilderFunctionsExplorerPanel.tsx b/packages/legend-query/src/components/QueryBuilderFunctionsExplorerPanel.tsx index a98646a2e7d..f03301b1cf9 100644 --- a/packages/legend-query/src/components/QueryBuilderFunctionsExplorerPanel.tsx +++ b/packages/legend-query/src/components/QueryBuilderFunctionsExplorerPanel.tsx @@ -61,7 +61,7 @@ import { getMultiplicityDescription } from './shared/QueryBuilderUtils'; const isDependencyTreeNode = ( node: QueryBuilderFunctionsExplorerTreeNodeData, ): boolean => - getElementRootPackage(node.packageableElement).path === + getElementRootPackage(node.packageableElement).name === ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT; const QueryBuilderFunctionInfoTooltip: React.FC<{ diff --git a/packages/legend-query/src/components/QueryBuilderPropertyExpressionEditor.tsx b/packages/legend-query/src/components/QueryBuilderPropertyExpressionEditor.tsx index ebd4f5a40d5..031904ab7c1 100644 --- a/packages/legend-query/src/components/QueryBuilderPropertyExpressionEditor.tsx +++ b/packages/legend-query/src/components/QueryBuilderPropertyExpressionEditor.tsx @@ -43,6 +43,7 @@ import { Enumeration, PrimitiveType, PRIMITIVE_TYPE, + isSuperType, } from '@finos/legend-graph'; import { QueryBuilderValueSpecificationEditor } from './QueryBuilderValueSpecificationEditor'; import { propertyExpression_setParametersValue } from '../stores/QueryBuilderValueSpecificationModifierHelper'; @@ -83,7 +84,7 @@ const DerivedPropertyParameterValueEditor = observer( !monitor.didDrop() && // Doing a type check, which only allows dragging and dropping parameters of the same type or of child types itemType && - (parameterType.isSuperType(itemType) || + (isSuperType(parameterType, itemType) || parameterType.name === itemType.name) ) { handleDrop(item); diff --git a/packages/legend-query/src/components/QueryBuilderValueSpecificationEditor.tsx b/packages/legend-query/src/components/QueryBuilderValueSpecificationEditor.tsx index 2515c8b5fcf..73cbfb049b5 100644 --- a/packages/legend-query/src/components/QueryBuilderValueSpecificationEditor.tsx +++ b/packages/legend-query/src/components/QueryBuilderValueSpecificationEditor.tsx @@ -54,6 +54,7 @@ import { VariableExpression, INTERNAL__PropagatedValue, SimpleFunctionExpression, + getEnumValue, } from '@finos/legend-graph'; import { getMultiplicityDescription } from './shared/QueryBuilderUtils'; import { @@ -414,7 +415,9 @@ const setCollectionValue = ( } else if (expectedType instanceof Enumeration) { result = uniq(parseData.map((item) => item.trim())) .map((item): EnumValueInstanceValue | undefined => { - const _enum = returnUndefOnError(() => expectedType.getValue(item)); + const _enum = returnUndefOnError(() => + getEnumValue(expectedType, item), + ); if (!_enum) { return undefined; } diff --git a/packages/legend-query/src/components/__tests__/QueryBuilder_FetchStructure.test.tsx b/packages/legend-query/src/components/__tests__/QueryBuilder_FetchStructure.test.tsx index b17ddcdc3a6..96d3f98167e 100644 --- a/packages/legend-query/src/components/__tests__/QueryBuilder_FetchStructure.test.tsx +++ b/packages/legend-query/src/components/__tests__/QueryBuilder_FetchStructure.test.tsx @@ -36,8 +36,10 @@ import { import { getAllByText, waitFor } from '@testing-library/dom'; import { AbstractPropertyExpression, + create_RawLambda, + getClassProperty, getRootSetImplementation, - RawLambda, + stub_RawLambda, } from '@finos/legend-graph'; import { TEST__provideMockedLegendQueryStore, @@ -54,11 +56,6 @@ import { LegendQueryPluginManager } from '../../application/LegendQueryPluginMan import { Query_GraphPreset } from '../../models/Query_GraphPreset'; import { FETCH_STRUCTURE_MODE } from '../../stores/QueryBuilderFetchStructureState'; -const getRawLambda = (jsonRawLambda: { - parameters?: object; - body?: object; -}): RawLambda => new RawLambda(jsonRawLambda.parameters, jsonRawLambda.body); - test( integrationTest( 'Query builder state is properly set after processing a projection lambda', @@ -72,7 +69,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_DATA__ComplexRelationalModel, - RawLambda.createStub(), + stub_RawLambda(), 'model::relational::tests::simpleRelationalMapping', 'model::MyRuntime', ); @@ -114,7 +111,12 @@ test( // simpleProjection act(() => { - queryBuilderState.initialize(getRawLambda(TEST_DATA__simpleProjection)); + queryBuilderState.initialize( + create_RawLambda( + TEST_DATA__simpleProjection.parameters, + TEST_DATA__simpleProjection.body, + ), + ); }); let projectionCols = await waitFor(() => renderResult.getByTestId(QUERY_BUILDER_TEST_ID.QUERY_BUILDER_PROJECTION), @@ -143,7 +145,7 @@ test( fistNameCol, QueryBuilderSimpleProjectionColumnState, ).propertyExpressionState.propertyExpression.func; - expect(firstNameProperty).toBe(_personClass.getProperty('firstName')); + expect(firstNameProperty).toBe(getClassProperty(_personClass, 'firstName')); const lastNameCol = guaranteeNonNullable( queryBuilderState.fetchStructureState.projectionState.columns.find( (e) => e.columnName === LAST_NAME_ALIAS, @@ -153,14 +155,17 @@ test( lastNameCol, QueryBuilderSimpleProjectionColumnState, ).propertyExpressionState.propertyExpression.func; - expect(lastNameProperty).toBe(_personClass.getProperty('lastName')); + expect(lastNameProperty).toBe(getClassProperty(_personClass, 'lastName')); expect(queryBuilderState.resultSetModifierState.limit).toBeUndefined(); // chainedProperty const CHAINED_PROPERTY_ALIAS = 'Firm/Legal Name'; act(() => { queryBuilderState.initialize( - getRawLambda(TEST_DATA__projectionWithChainedProperty), + create_RawLambda( + TEST_DATA__projectionWithChainedProperty.parameters, + TEST_DATA__projectionWithChainedProperty.body, + ), ); }); const projectionWithChainedPropertyCols = await waitFor(() => @@ -185,20 +190,27 @@ test( legalNameCol, QueryBuilderSimpleProjectionColumnState, ).propertyExpressionState.propertyExpression.func; - expect(legalNameColProperty).toBe(_firmClass.getProperty('legalName')); + expect(legalNameColProperty).toBe( + getClassProperty(_firmClass, 'legalName'), + ); const _firmPropertyExpression = guaranteeType( guaranteeType(legalNameCol, QueryBuilderSimpleProjectionColumnState) .propertyExpressionState.propertyExpression.parametersValues[0], AbstractPropertyExpression, ); - expect(_firmPropertyExpression.func).toBe(_personClass.getProperty('firm')); + expect(_firmPropertyExpression.func).toBe( + getClassProperty(_personClass, 'firm'), + ); expect(queryBuilderState.resultSetModifierState.limit).toBeUndefined(); // result set modifiers const RESULT_LIMIT = 500; act(() => { queryBuilderState.initialize( - getRawLambda(TEST_DATA__projectionWithResultSetModifiers), + create_RawLambda( + TEST_DATA__projectionWithResultSetModifiers.parameters, + TEST_DATA__projectionWithResultSetModifiers.body, + ), ); }); projectionCols = await waitFor(() => @@ -273,7 +285,10 @@ test( await waitFor(() => renderResult.getByText('Add a filter condition')); act(() => { queryBuilderState.initialize( - getRawLambda(TEST_DATA__getAllWithOneConditionFilter), + create_RawLambda( + TEST_DATA__getAllWithOneConditionFilter.parameters, + TEST_DATA__getAllWithOneConditionFilter.body, + ), ); }); let filterValue = 'testFirstName'; @@ -301,7 +316,10 @@ test( await waitFor(() => renderResult.getByText('Add a filter condition')); act(() => { queryBuilderState.initialize( - getRawLambda(TEST_DATA__getAllWithGroupedFilter), + create_RawLambda( + TEST_DATA__getAllWithGroupedFilter.parameters, + TEST_DATA__getAllWithGroupedFilter.body, + ), ); }); filterPanel = await waitFor(() => @@ -338,7 +356,10 @@ test( await waitFor(() => renderResult.getByText('Add a filter condition')); act(() => { queryBuilderState.initialize( - getRawLambda(TEST_DATA__projectWithDerivedProperty), + create_RawLambda( + TEST_DATA__projectWithDerivedProperty.parameters, + TEST_DATA__projectWithDerivedProperty.body, + ), ); }); projectionCols = await waitFor(() => @@ -379,7 +400,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_DATA__ComplexRelationalModel, - RawLambda.createStub(), + stub_RawLambda(), 'model::relational::tests::simpleRelationalMapping', 'model::MyRuntime', ); @@ -430,7 +451,10 @@ test( // simpleProjection with subType act(() => { queryBuilderState.initialize( - getRawLambda(TEST_DATA__simpleProjectionWithSubtype), + create_RawLambda( + TEST_DATA__simpleProjectionWithSubtype.parameters, + TEST_DATA__simpleProjectionWithSubtype.body, + ), ); }); const projectionColsWithSubType = await waitFor(() => @@ -455,7 +479,7 @@ test( nameCol, QueryBuilderSimpleProjectionColumnState, ).propertyExpressionState.propertyExpression.func; - expect(nameProperty).toBe(_personClass.getProperty('firstName')); + expect(nameProperty).toBe(getClassProperty(_personClass, 'firstName')); }, ); @@ -472,7 +496,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_DATA__ComplexM2MModel, - RawLambda.createStub(), + stub_RawLambda(), 'model::MyMapping', 'model::MyRuntime', ); @@ -496,14 +520,24 @@ test( // simple graph fetch act(() => { - queryBuilderState.initialize(getRawLambda(TEST_DATA__simpleGraphFetch)); + queryBuilderState.initialize( + create_RawLambda( + TEST_DATA__simpleGraphFetch.parameters, + TEST_DATA__simpleGraphFetch.body, + ), + ); }); expect(queryBuilderState.fetchStructureState.fetchStructureMode).toBe( FETCH_STRUCTURE_MODE.GRAPH_FETCH, ); act(() => { - queryBuilderState.initialize(getRawLambda(TEST_DATA__complexGraphFetch)); + queryBuilderState.initialize( + create_RawLambda( + TEST_DATA__complexGraphFetch.parameters, + TEST_DATA__complexGraphFetch.body, + ), + ); }); expect(queryBuilderState.fetchStructureState.fetchStructureMode).toBe( FETCH_STRUCTURE_MODE.GRAPH_FETCH, diff --git a/packages/legend-query/src/components/__tests__/QueryBuilder_Milestoning.test.tsx b/packages/legend-query/src/components/__tests__/QueryBuilder_Milestoning.test.tsx index 5562c2eb580..4594989caf8 100644 --- a/packages/legend-query/src/components/__tests__/QueryBuilder_Milestoning.test.tsx +++ b/packages/legend-query/src/components/__tests__/QueryBuilder_Milestoning.test.tsx @@ -36,7 +36,7 @@ import { guaranteeType, } from '@finos/legend-shared'; import { waitFor } from '@testing-library/dom'; -import { RawLambda } from '@finos/legend-graph'; +import { stub_RawLambda, create_RawLambda } from '@finos/legend-graph'; import { TEST__provideMockedLegendQueryStore, TEST__setUpQueryEditor, @@ -46,11 +46,6 @@ import { QueryBuilderSimpleProjectionColumnState } from '../../stores/QueryBuild import { LegendQueryPluginManager } from '../../application/LegendQueryPluginManager'; import { Query_GraphPreset } from '../../models/Query_GraphPreset'; -const getRawLambda = (jsonRawLambda: { - parameters?: object; - body?: object; -}): RawLambda => new RawLambda(jsonRawLambda.parameters, jsonRawLambda.body); - test( integrationTest( 'Query builder state is properly set after processing a lambda with Business Temporal source Processing Temporal target', @@ -64,7 +59,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -84,8 +79,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithBusinessTemporalSourceAndProcessingTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithBusinessTemporalSourceAndProcessingTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithBusinessTemporalSourceAndProcessingTemporalTarget.body, ), ); }); @@ -121,7 +117,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -141,8 +137,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithBusinessTemporalSourceAndBusinessTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithBusinessTemporalSourceAndBusinessTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithBusinessTemporalSourceAndBusinessTemporalTarget.body, ), ); }); @@ -178,7 +175,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -198,8 +195,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithBusinessTemporalSourceAndBiTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithBusinessTemporalSourceAndBiTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithBusinessTemporalSourceAndBiTemporalTarget.body, ), ); }); @@ -235,7 +233,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -255,8 +253,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithBiTemporalSourceAndBiTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithBiTemporalSourceAndBiTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithBiTemporalSourceAndBiTemporalTarget.body, ), ); }); @@ -292,7 +291,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -312,8 +311,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithBiTemporalSourceAndBusinessTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithBiTemporalSourceAndBusinessTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithBiTemporalSourceAndBusinessTemporalTarget.body, ), ); }); @@ -349,7 +349,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -369,8 +369,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithBiTemporalSourceAndProcessingTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithBiTemporalSourceAndProcessingTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithBiTemporalSourceAndProcessingTemporalTarget.body, ), ); }); @@ -406,7 +407,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -426,8 +427,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithProcessingTemporalSourceAndBiTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithProcessingTemporalSourceAndBiTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithProcessingTemporalSourceAndBiTemporalTarget.body, ), ); }); @@ -463,7 +465,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -483,8 +485,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithProcessingTemporalSourceAndBusinessTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithProcessingTemporalSourceAndBusinessTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithProcessingTemporalSourceAndBusinessTemporalTarget.body, ), ); }); @@ -520,7 +523,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -540,8 +543,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithProcessingTemporalSourceAndProcessingTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithProcessingTemporalSourceAndProcessingTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithProcessingTemporalSourceAndProcessingTemporalTarget.body, ), ); }); @@ -577,7 +581,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -597,8 +601,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithNonTemporalSourceAndProcessingTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithNonTemporalSourceAndProcessingTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithNonTemporalSourceAndProcessingTemporalTarget.body, ), ); }); @@ -634,7 +639,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -654,8 +659,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithNonTemporalSourceAndBusinessTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithNonTemporalSourceAndBusinessTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithNonTemporalSourceAndBusinessTemporalTarget.body, ), ); }); @@ -691,7 +697,7 @@ test( const renderResult = await TEST__setUpQueryEditor( mockedQueryStore, TEST_MilestoningModel, - RawLambda.createStub(), + stub_RawLambda(), 'my::map', 'my::runtime', ); @@ -711,8 +717,9 @@ test( act(() => { queryBuilderState.initialize( - getRawLambda( - TEST_DATA__simpleProjectionWithNonTemporalSourceAndBiTemporalTarget, + create_RawLambda( + TEST_DATA__simpleProjectionWithNonTemporalSourceAndBiTemporalTarget.parameters, + TEST_DATA__simpleProjectionWithNonTemporalSourceAndBiTemporalTarget.body, ), ); }); diff --git a/packages/legend-query/src/stores/QueryBuilderExplorerState.ts b/packages/legend-query/src/stores/QueryBuilderExplorerState.ts index 31e272cacdc..5a9ed416757 100644 --- a/packages/legend-query/src/stores/QueryBuilderExplorerState.ts +++ b/packages/legend-query/src/stores/QueryBuilderExplorerState.ts @@ -19,6 +19,7 @@ import { guaranteeNonNullable, addUniqueEntry, uniq, + returnUndefOnError, } from '@finos/legend-shared'; import { type AbstractProperty, @@ -49,6 +50,15 @@ import { ARROW_FUNCTION_TOKEN, Multiplicity, getAllSuperSetImplementations, + PurePropertyMapping, + isStubbed_RawLambda, + FlatDataPropertyMapping, + RelationalPropertyMapping, + isStubbed_RawRelationalOperationElement, + getAllClassProperties, + getClassProperty, + getAllOwnClassProperties, + getAllClassDerivedProperties, } from '@finos/legend-graph'; import type { QueryBuilderState } from './QueryBuilderState'; import { action, makeAutoObservable, observable } from 'mobx'; @@ -275,11 +285,11 @@ const isAutoMappedProperty = ( setImpl: SetImplementation, ): boolean => { if (setImpl instanceof PureInstanceSetImplementation) { - const sourceClass = setImpl.srcClass; + const sourceClass = setImpl.srcClass.value; return Boolean( - sourceClass.value - ?.getAllProperties() - .find((p) => p.name === property.name), + sourceClass + ? returnUndefOnError(() => getClassProperty(sourceClass, property.name)) + : undefined, ); } return false; @@ -322,7 +332,20 @@ export const getPropertyNodeMappingData = ( ) .flat(), ) - .filter((p) => !p.isStub); + .filter((p) => { + // TODO: we should also handle of other property mapping types + // using some form of extension mechanism + if (p instanceof PurePropertyMapping) { + return !isStubbed_RawLambda(p.transform); + } else if (p instanceof FlatDataPropertyMapping) { + return !isStubbed_RawLambda(p.transform); + } else if (p instanceof RelationalPropertyMapping) { + return !isStubbed_RawRelationalOperationElement( + p.relationalOperation, + ); + } + return true; + }); // NOTE: observe how we scan and prepare the list of property mappings above, // searching for the property mapping to be used takes into account // precedence, i.e. property mappings from super set implementations are of lower precedence @@ -375,12 +398,12 @@ const generateExplorerTreeClassNodeChildrenIDs = ( const currentClass = node.type as Class; const idsFromProperties = ( node instanceof QueryBuilderExplorerTreeSubTypeNodeData - ? currentClass.getAllOwnedProperties() - : currentClass - .getAllProperties() - .concat(currentClass.getAllDerivedProperties()) + ? getAllOwnClassProperties(currentClass) + : getAllClassProperties(currentClass).concat( + getAllClassDerivedProperties(currentClass), + ) ).map((p) => `${node.id}.${p.name}`); - const idsFromsubclasses = currentClass.subclasses.map( + const idsFromsubclasses = currentClass._subclasses.map( (subclass) => `${node.id}${TYPE_CAST_TOKEN}${subclass.path}`, ); return idsFromProperties.concat(idsFromsubclasses); @@ -486,9 +509,8 @@ const getQueryBuilderTreeData = ( treeRootNode.isOpen = true; nodes.set(treeRootNode.id, treeRootNode); rootIds.push(treeRootNode.id); - rootClass - .getAllProperties() - .concat(rootClass.getAllDerivedProperties()) + getAllClassProperties(rootClass) + .concat(getAllClassDerivedProperties(rootClass)) .sort((a, b) => a.name.localeCompare(b.name)) .sort( (a, b) => @@ -505,7 +527,7 @@ const getQueryBuilderTreeData = ( addUniqueEntry(treeRootNode.childrenIds, propertyTreeNodeData.id); nodes.set(propertyTreeNodeData.id, propertyTreeNodeData); }); - rootClass.subclasses.forEach((subclass) => { + rootClass._subclasses.forEach((subclass) => { const subTypeTreeNodeData = getQueryBuilderSubTypeNodeData( subclass, treeRootNode, diff --git a/packages/legend-query/src/stores/QueryBuilderLambdaBuilder.ts b/packages/legend-query/src/stores/QueryBuilderLambdaBuilder.ts index bbdecb1daf1..54441f8db06 100644 --- a/packages/legend-query/src/stores/QueryBuilderLambdaBuilder.ts +++ b/packages/legend-query/src/stores/QueryBuilderLambdaBuilder.ts @@ -74,6 +74,10 @@ import { import { getDerivedPropertyMilestoningSteoreotype } from './QueryBuilderPropertyEditorState'; /** + * Checks if the provided property expression match the criteria for default + * date propagation so we know whether we need to fill in values for the parameter + * or just propgate values from the parent's expression + * * NOTE: this takes date propgation into account. See the table below for all * the combination: * diff --git a/packages/legend-query/src/stores/QueryBuilderProjectionState.ts b/packages/legend-query/src/stores/QueryBuilderProjectionState.ts index ad79f960b6b..f12284d13f5 100644 --- a/packages/legend-query/src/stores/QueryBuilderProjectionState.ts +++ b/packages/legend-query/src/stores/QueryBuilderProjectionState.ts @@ -62,11 +62,13 @@ import { extractSourceInformationCoordinates, buildSourceInformationSourceId, ParserError, - RawLambda, TYPICAL_MULTIPLICITY_TYPE, RawVariableExpression, Enumeration, LAMBDA_PIPE, + RawLambda, + stub_RawLambda, + isStubbed_RawLambda, } from '@finos/legend-graph'; import { DEFAULT_LAMBDA_VARIABLE_NAME, @@ -220,7 +222,7 @@ class QueryBuilderDerivationProjectionLambdaState extends LambdaEditorState { } *convertLambdaGrammarStringToObject(): GeneratorFn { - const emptyLambda = RawLambda.createStub(); + const emptyLambda = stub_RawLambda(); if (this.lambdaString) { try { const lambda = @@ -405,7 +407,7 @@ export class QueryBuilderProjectionState { QueryBuilderDerivationProjectionColumnState >(); this.derivations.forEach((derivationProjectionColumnState) => { - if (!derivationProjectionColumnState.lambda.isStub) { + if (!isStubbed_RawLambda(derivationProjectionColumnState.lambda)) { lambdas.set( derivationProjectionColumnState.derivationLambdaEditorState.lambdaId, derivationProjectionColumnState.lambda, diff --git a/packages/legend-query/src/stores/QueryBuilderSetupState.ts b/packages/legend-query/src/stores/QueryBuilderSetupState.ts index fb5789bfc9b..5723e1b7b64 100644 --- a/packages/legend-query/src/stores/QueryBuilderSetupState.ts +++ b/packages/legend-query/src/stores/QueryBuilderSetupState.ts @@ -34,6 +34,7 @@ import { DEFAULT_PROCESSING_DATE_MILESTONING_PARAMETER_NAME, MILESTONING_STEREOTYPE, observe_ValueSpecification, + getAllIncludedMappings, } from '@finos/legend-graph'; export class QueryBuilderSetupState { @@ -108,7 +109,7 @@ export class QueryBuilderSetupState { ); const resolvedMappingIncludes = this.queryBuilderState.mappings.filter( (mapping) => - mapping.allIncludedMappings.some((e) => + getAllIncludedMappings(mapping).some((e) => mappingsWithClassMapped.includes(e), ), ); diff --git a/packages/legend-query/src/stores/QueryBuilderState.ts b/packages/legend-query/src/stores/QueryBuilderState.ts index 0208704f4f7..61fb6da68f2 100644 --- a/packages/legend-query/src/stores/QueryBuilderState.ts +++ b/packages/legend-query/src/stores/QueryBuilderState.ts @@ -61,6 +61,7 @@ import { VariableExpression, observe_ValueSpecification, ObserverContext, + isStubbed_RawLambda, } from '@finos/legend-graph'; import { QueryBuilderFilterOperator_Equal, @@ -369,7 +370,7 @@ export class QueryBuilderState { buildStateFromRawLambda(rawLambda: RawLambda): void { this.resetQueryBuilder(); this.resetQuerySetup(); - if (!rawLambda.isStub) { + if (!isStubbed_RawLambda(rawLambda)) { const valueSpec = observe_ValueSpecification( this.graphManagerState.graphManager.buildValueSpecification( this.graphManagerState.graphManager.serializeRawValueSpecification( diff --git a/packages/legend-query/src/stores/QueryParametersState.ts b/packages/legend-query/src/stores/QueryParametersState.ts index 7eb25937e2b..36c69e087c9 100644 --- a/packages/legend-query/src/stores/QueryParametersState.ts +++ b/packages/legend-query/src/stores/QueryParametersState.ts @@ -32,6 +32,7 @@ import { VariableExpression, observe_VariableExpression, observe_ValueSpecification, + getEnumValue, } from '@finos/legend-graph'; import { addUniqueEntry, @@ -160,7 +161,7 @@ export class QueryParameterState { const mock = createMockEnumerationProperty(varType); if (mock !== '') { enumValueInstance.values = [ - EnumValueExplicitReference.create(varType.getValue(mock)), + EnumValueExplicitReference.create(getEnumValue(varType, mock)), ]; } return enumValueInstance; diff --git a/packages/legend-query/src/stores/QuerySetupStore.ts b/packages/legend-query/src/stores/QuerySetupStore.ts index 6dfaf650434..ba6d222a623 100644 --- a/packages/legend-query/src/stores/QuerySetupStore.ts +++ b/packages/legend-query/src/stores/QuerySetupStore.ts @@ -35,6 +35,7 @@ import { type PackageableRuntime, type Service, QuerySearchSpecification, + getAllIncludedMappings, } from '@finos/legend-graph'; import type { LegendQueryStore } from './LegendQueryStore'; import { ProjectData } from '@finos/legend-server-depot'; @@ -188,7 +189,7 @@ export class CreateQuerySetupState extends QuerySetupState { runtime.value.runtimeValue.mappings .map((mappingReference) => [ mappingReference.value, - ...mappingReference.value.allIncludedMappings, + ...getAllIncludedMappings(mappingReference.value), ]) .flat() .includes(currentMapping), diff --git a/packages/legend-query/src/stores/QueryTextEditorState.ts b/packages/legend-query/src/stores/QueryTextEditorState.ts index 48471df8376..c3910a10f58 100644 --- a/packages/legend-query/src/stores/QueryTextEditorState.ts +++ b/packages/legend-query/src/stores/QueryTextEditorState.ts @@ -19,6 +19,7 @@ import { buildSourceInformationSourceId, ParserError, RawLambda, + stub_RawLambda, } from '@finos/legend-graph'; import { type GeneratorFn, @@ -76,7 +77,7 @@ export class QueryTextEditorState extends LambdaEditorState { }); this.queryBuilderState = queryBuilderState; - this.rawLambdaState = new QueryRawLambdaState(RawLambda.createStub()); + this.rawLambdaState = new QueryRawLambdaState(stub_RawLambda()); } get lambdaId(): string { @@ -96,7 +97,7 @@ export class QueryTextEditorState extends LambdaEditorState { } *convertLambdaGrammarStringToObject(): GeneratorFn { - const emptyLambda = RawLambda.createStub(); + const emptyLambda = stub_RawLambda(); if (this.lambdaString) { try { const lambda = diff --git a/packages/legend-query/src/stores/__tests__/QueryBuilder_BuildLambdaFailure.test.tsx b/packages/legend-query/src/stores/__tests__/QueryBuilder_BuildLambdaFailure.test.tsx index a953e24b9e9..ca8805d4f93 100644 --- a/packages/legend-query/src/stores/__tests__/QueryBuilder_BuildLambdaFailure.test.tsx +++ b/packages/legend-query/src/stores/__tests__/QueryBuilder_BuildLambdaFailure.test.tsx @@ -28,7 +28,7 @@ import TEST_DATA__PostFilterModel from './TEST_DATA__QueryBuilder_Model_PostFilt import { integrationTest } from '@finos/legend-shared'; import type { Entity } from '@finos/legend-model-storage'; import { - RawLambda, + create_RawLambda, TEST__buildGraphWithEntities, TEST__getTestGraphManagerState, } from '@finos/legend-graph'; @@ -41,11 +41,6 @@ import { } from '../QueryBuilderState'; import { TEST__getTestQueryConfig } from '../QueryStoreTestUtils'; -const getRawLambda = (jsonRawLambda: { - parameters?: object; - body?: object; -}): RawLambda => new RawLambda(jsonRawLambda.parameters, jsonRawLambda.body); - type TestCase = [ string, { @@ -131,7 +126,9 @@ describe( new StandardQueryBuilderMode(), ); expect(() => - queryBuilderState.buildStateFromRawLambda(getRawLambda(lambdaJson)), + queryBuilderState.buildStateFromRawLambda( + create_RawLambda(lambdaJson.parameters, lambdaJson.body), + ), ).toThrowError(errorMessage); }, ); diff --git a/packages/legend-query/src/stores/__tests__/QueryBuilder_ExplorerState.test.ts b/packages/legend-query/src/stores/__tests__/QueryBuilder_ExplorerState.test.ts index c04a497fc15..da65ed205a5 100644 --- a/packages/legend-query/src/stores/__tests__/QueryBuilder_ExplorerState.test.ts +++ b/packages/legend-query/src/stores/__tests__/QueryBuilder_ExplorerState.test.ts @@ -23,6 +23,8 @@ import { integrationTest } from '@finos/legend-shared'; import type { Entity } from '@finos/legend-model-storage'; import { Class, + getAllClassDerivedProperties, + getAllClassProperties, type AbstractProperty, type GraphManagerState, type Mapping, @@ -159,9 +161,9 @@ const buildMappingData = ( }; if (type instanceof Class) { if (depth <= max_depth) { - const properties = type - .getAllProperties() - .concat(type.getAllDerivedProperties()); + const properties = getAllClassProperties(type).concat( + getAllClassDerivedProperties(type), + ); propertyMappingData.childNodes = properties.map((p) => buildMappingData( p, @@ -184,9 +186,9 @@ const generatePropertyMappingDataTree = ( max_depth: number, ): NodePropertyMappingData[] => { const mappingData = getRootMappingData(mapping, _class); - const properties = _class - .getAllProperties() - .concat(_class.getAllDerivedProperties()); + const properties = getAllClassProperties(_class).concat( + getAllClassDerivedProperties(_class), + ); return properties.map((p) => buildMappingData(p, graphManagerState, mappingData, max_depth, mapping), ); diff --git a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_Equal.ts b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_Equal.ts index d461316c5ff..55393768405 100644 --- a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_Equal.ts +++ b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_Equal.ts @@ -31,6 +31,7 @@ import { EnumValueExplicitReference, Enumeration, PRIMITIVE_TYPE, + isSuperType, } from '@finos/legend-graph'; import { UnsupportedOperationError } from '@finos/legend-shared'; import { @@ -113,7 +114,7 @@ export class QueryBuilderFilterOperator_Equal extends QueryBuilderFilterOperator // e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is() DATE_PRIMITIVE_TYPES.includes(type.path) || type === propertyType || - propertyType.isSuperType(type)) + isSuperType(propertyType, type)) ); } diff --git a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.ts b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.ts index 31ab7f8e68f..5033fe8c23c 100644 --- a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.ts +++ b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThan.ts @@ -24,6 +24,7 @@ import { type SimpleFunctionExpression, type AbstractPropertyExpression, PRIMITIVE_TYPE, + isSuperType, } from '@finos/legend-graph'; import { UnsupportedOperationError } from '@finos/legend-shared'; import { @@ -97,7 +98,7 @@ export class QueryBuilderFilterOperator_GreaterThan extends QueryBuilderFilterOp // e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is() DATE_PRIMITIVE_TYPES.includes(type.path) || type === propertyType || - propertyType.isSuperType(type)) + isSuperType(propertyType, type)) ); } diff --git a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.ts b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.ts index a3e418bf69b..dede8c6e75e 100644 --- a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.ts +++ b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_GreaterThanEqual.ts @@ -24,6 +24,7 @@ import { type ValueSpecification, type SimpleFunctionExpression, type AbstractPropertyExpression, + isSuperType, } from '@finos/legend-graph'; import { UnsupportedOperationError } from '@finos/legend-shared'; import { @@ -97,7 +98,7 @@ export class QueryBuilderFilterOperator_GreaterThanEqual extends QueryBuilderFil // e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is() DATE_PRIMITIVE_TYPES.includes(type.path) || type === propertyType || - propertyType.isSuperType(type)) + isSuperType(propertyType, type)) ); } diff --git a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_LessThan.ts b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_LessThan.ts index fc645ef3188..6f4bf84a737 100644 --- a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_LessThan.ts +++ b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_LessThan.ts @@ -24,6 +24,7 @@ import { type ValueSpecification, type SimpleFunctionExpression, type AbstractPropertyExpression, + isSuperType, } from '@finos/legend-graph'; import { UnsupportedOperationError } from '@finos/legend-shared'; import { @@ -98,7 +99,7 @@ export class QueryBuilderFilterOperator_LessThan extends QueryBuilderFilterOpera (propertyType.path === PRIMITIVE_TYPE.DATETIME && DATE_PRIMITIVE_TYPES.includes(type.path)) || type === propertyType || - propertyType.isSuperType(type)) + isSuperType(propertyType, type)) ); } diff --git a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.ts b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.ts index ceedb5017be..1af0829fff7 100644 --- a/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.ts +++ b/packages/legend-query/src/stores/filterOperators/QueryBuilderFilterOperator_LessThanEqual.ts @@ -24,6 +24,7 @@ import { type ValueSpecification, type SimpleFunctionExpression, type AbstractPropertyExpression, + isSuperType, } from '@finos/legend-graph'; import { UnsupportedOperationError } from '@finos/legend-shared'; import { @@ -97,7 +98,7 @@ export class QueryBuilderFilterOperator_LessThanEqual extends QueryBuilderFilter // e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is() DATE_PRIMITIVE_TYPES.includes(type.path) || type === propertyType || - propertyType.isSuperType(type)) + isSuperType(propertyType, type)) ); } diff --git a/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperatorHelper.ts b/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperatorHelper.ts index 3879c9907ce..cf89fd29428 100644 --- a/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperatorHelper.ts +++ b/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperatorHelper.ts @@ -26,6 +26,7 @@ import { SimpleFunctionExpression, TYPICAL_MULTIPLICITY_TYPE, VariableExpression, + getAllClassDerivedProperties, } from '@finos/legend-graph'; import { guaranteeNonNullable, @@ -97,10 +98,9 @@ export const buildPostFilterConditionExpression = ( tdsDerivedPropertyName = getTDSColumnDerivedProperyFromType(type); } tdsPropertyExpression.func = guaranteeNonNullable( - graph - .getClass(TDS_ROW) - .getAllDerivedProperties() - .find((p) => p.name === tdsDerivedPropertyName), + getAllClassDerivedProperties(graph.getClass(TDS_ROW)).find( + (p) => p.name === tdsDerivedPropertyName, + ), ); const variableName = new VariableExpression( filterConditionState.postFilterState.lambdaParameterName, diff --git a/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.ts b/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.ts index 5bdce4f5430..6f2d022422a 100644 --- a/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.ts +++ b/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_Equal.ts @@ -28,6 +28,7 @@ import { GenericTypeExplicitReference, PRIMITIVE_TYPE, TYPICAL_MULTIPLICITY_TYPE, + isSuperType, } from '@finos/legend-graph'; import { guaranteeNonNullable, @@ -110,7 +111,7 @@ export class QueryBuilderPostFilterOperator_Equal extends QueryBuilderPostFilter // e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is() DATE_PRIMITIVE_TYPES.includes(type.path) || type === lhsType || - lhsType.isSuperType(type)) + isSuperType(lhsType, type)) ); } return false; diff --git a/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.ts b/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.ts index e32cffb2c13..2af00a88efb 100644 --- a/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.ts +++ b/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_GreaterThan.ts @@ -20,6 +20,7 @@ import { type FunctionExpression, AbstractPropertyExpression, PRIMITIVE_TYPE, + isSuperType, } from '@finos/legend-graph'; import { guaranteeNonNullable, @@ -94,7 +95,7 @@ export class QueryBuilderPostFilterOperator_GreaterThan extends QueryBuilderPost // e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is() DATE_PRIMITIVE_TYPES.includes(type.path) || type === lhsType || - lhsType.isSuperType(type)) + isSuperType(lhsType, type)) ); } diff --git a/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.ts b/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.ts index 880c4d300fd..a20d00f1493 100644 --- a/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.ts +++ b/packages/legend-query/src/stores/postFilterOperators/QueryBuilderPostFilterOperator_LessThan.ts @@ -20,6 +20,7 @@ import { AbstractPropertyExpression, type FunctionExpression, PRIMITIVE_TYPE, + isSuperType, } from '@finos/legend-graph'; import { guaranteeNonNullable, @@ -94,7 +95,7 @@ export class QueryBuilderPostFilterOperator_LessThan extends QueryBuilderPostFil // e.g. LHS(DateTime) = RHS(Date) -> we use isOnDay() instead of is() DATE_PRIMITIVE_TYPES.includes(type.path) || type === lhsType || - lhsType.isSuperType(type)) + isSuperType(lhsType, type)) ); } diff --git a/packages/legend-shared/package.json b/packages/legend-shared/package.json index eee963d6422..3aa94e95c0e 100644 --- a/packages/legend-shared/package.json +++ b/packages/legend-shared/package.json @@ -42,7 +42,7 @@ "@types/lodash-es": "4.17.6", "@types/lossless-json": "1.0.1", "@types/object-hash": "2.2.1", - "@types/pako": "1.0.3", + "@types/pako": "2.0.0", "@types/seedrandom": "3.0.2", "@types/uuid": "8.3.4", "hash.js": "1.1.7", diff --git a/packages/legend-studio-extension-query-builder/src/components/MappingExecutionQueryBuilder.tsx b/packages/legend-studio-extension-query-builder/src/components/MappingExecutionQueryBuilder.tsx index 1c9da837e32..e1ab90f6a12 100644 --- a/packages/legend-studio-extension-query-builder/src/components/MappingExecutionQueryBuilder.tsx +++ b/packages/legend-studio-extension-query-builder/src/components/MappingExecutionQueryBuilder.tsx @@ -25,6 +25,7 @@ import { useApplicationStore } from '@finos/legend-application'; import { QueryBuilderMode } from '@finos/legend-query'; import { assertErrorThrown } from '@finos/legend-shared'; import { PencilIcon } from '@finos/legend-art'; +import { isStubbed_RawLambda } from '@finos/legend-graph'; export class MappingExecutionQueryBuilderMode extends QueryBuilderMode { get isParametersDisabled(): boolean { @@ -103,7 +104,9 @@ export const MappingExecutionQueryBuilder = observer( }, }, ], - disableCompile: executionState.queryState.query.isStub, + disableCompile: isStubbed_RawLambda( + executionState.queryState.query, + ), queryBuilderMode: new MappingExecutionQueryBuilderMode(), }), ); diff --git a/packages/legend-studio-extension-query-builder/src/components/MappingTestQueryBuilder.tsx b/packages/legend-studio-extension-query-builder/src/components/MappingTestQueryBuilder.tsx index a19cb4f3c3b..fbe47eb253d 100644 --- a/packages/legend-studio-extension-query-builder/src/components/MappingTestQueryBuilder.tsx +++ b/packages/legend-studio-extension-query-builder/src/components/MappingTestQueryBuilder.tsx @@ -22,6 +22,7 @@ import { useApplicationStore } from '@finos/legend-application'; import { MappingExecutionQueryBuilderMode } from './MappingExecutionQueryBuilder'; import { assertErrorThrown } from '@finos/legend-shared'; import { PencilIcon } from '@finos/legend-art'; +import { isStubbed_RawLambda } from '@finos/legend-graph'; export const MappingTestQueryBuilder = observer( (props: { testState: MappingTestState; isReadOnly: boolean }) => { @@ -91,7 +92,7 @@ export const MappingTestQueryBuilder = observer( }, }, ], - disableCompile: testState.queryState.query.isStub, + disableCompile: isStubbed_RawLambda(testState.queryState.query), queryBuilderMode: new MappingExecutionQueryBuilderMode(), }), ); diff --git a/packages/legend-studio-extension-query-builder/src/components/ServiceQueryBuilder.tsx b/packages/legend-studio-extension-query-builder/src/components/ServiceQueryBuilder.tsx index 147791affb6..cb249ebf865 100644 --- a/packages/legend-studio-extension-query-builder/src/components/ServiceQueryBuilder.tsx +++ b/packages/legend-studio-extension-query-builder/src/components/ServiceQueryBuilder.tsx @@ -25,6 +25,10 @@ import { useApplicationStore } from '@finos/legend-application'; import { StandardQueryBuilderMode } from '@finos/legend-query'; import { assertErrorThrown } from '@finos/legend-shared'; import { PencilIcon } from '@finos/legend-art'; +import { + isStubbed_RawLambda, + isStubbed_PackageableElement, +} from '@finos/legend-graph'; export const ServiceQueryBuilder = observer( (props: { @@ -44,7 +48,7 @@ export const ServiceQueryBuilder = observer( const mapping = executionState.selectedExecutionConfiguration.mapping.value; const runtime = executionState.selectedExecutionConfiguration.runtime; - if (!mapping.isStub) { + if (!isStubbed_PackageableElement(mapping)) { queryBuilderExtension.reset(); queryBuilderExtension.queryBuilderState.querySetupState.setMapping( mapping, @@ -103,7 +107,9 @@ export const ServiceQueryBuilder = observer( }, }, ], - disableCompile: executionState.queryState.query.isStub, + disableCompile: isStubbed_RawLambda( + executionState.queryState.query, + ), queryBuilderMode: new StandardQueryBuilderMode(), }), ); diff --git a/packages/legend-studio/package.json b/packages/legend-studio/package.json index 1af026f1f08..9e5b3f08ab5 100644 --- a/packages/legend-studio/package.json +++ b/packages/legend-studio/package.json @@ -70,7 +70,7 @@ "react-router": "5.2.1", "react-router-dom": "5.3.0", "serializr": "2.0.5", - "sql-formatter": "4.0.2" + "sql-formatter": "6.1.0" }, "devDependencies": { "@finos/legend-dev-utils": "workspace:*", diff --git a/packages/legend-studio/src/components/editor/edit-panel/FunctionEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/FunctionEditor.tsx index 2ce7c3eac60..e20d65116d7 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/FunctionEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/FunctionEditor.tsx @@ -48,20 +48,23 @@ import { useEditorStore } from '../EditorStoreProvider'; import { type ConcreteFunctionDefinition, type StereotypeReference, + type TaggedValue, + type RawVariableExpression, + Profile, PRIMITIVE_TYPE, MULTIPLICITY_INFINITE, - TaggedValue, - Tag, - Profile, - Stereotype, Unit, - RawVariableExpression, Type, Multiplicity, Enumeration, Class, PrimitiveType, StereotypeExplicitReference, + stub_Tag, + stub_Profile, + stub_TaggedValue, + stub_Stereotype, + stub_RawVariableExpression, } from '@finos/legend-graph'; import { useApplicationStore } from '@finos/legend-application'; import { StudioLambdaEditor } from '../../shared/StudioLambdaEditor'; @@ -502,7 +505,7 @@ export const FunctionMainEditor = observer( const addParameter = (): void => { function_addParameter( functionElement, - RawVariableExpression.createStub(defaultType), + stub_RawVariableExpression(defaultType), ); }; const deleteParameter = @@ -515,7 +518,7 @@ export const FunctionMainEditor = observer( if (!isReadOnly && item.data.packageableElement instanceof Type) { function_addParameter( functionElement, - RawVariableExpression.createStub(item.data.packageableElement), + stub_RawVariableExpression(item.data.packageableElement), ); } }, @@ -657,14 +660,12 @@ export const FunctionEditor = observer(() => { if (selectedTab === FUNCTION_SPEC_TAB.TAGGED_VALUES) { annotatedElement_addTaggedValue( functionElement, - TaggedValue.createStub(Tag.createStub(Profile.createStub())), + stub_TaggedValue(stub_Tag(stub_Profile())), ); } else if (selectedTab === FUNCTION_SPEC_TAB.STEREOTYPES) { annotatedElement_addStereotype( functionElement, - StereotypeExplicitReference.create( - Stereotype.createStub(Profile.createStub()), - ), + StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())), ); } } @@ -674,7 +675,7 @@ export const FunctionEditor = observer(() => { if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addTaggedValue( functionElement, - TaggedValue.createStub(Tag.createStub(item.data.packageableElement)), + stub_TaggedValue(stub_Tag(item.data.packageableElement)), ); } }, @@ -696,7 +697,7 @@ export const FunctionEditor = observer(() => { annotatedElement_addStereotype( functionElement, StereotypeExplicitReference.create( - Stereotype.createStub(item.data.packageableElement), + stub_Stereotype(item.data.packageableElement), ), ); } diff --git a/packages/legend-studio/src/components/editor/edit-panel/RuntimeEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/RuntimeEditor.tsx index 3f44e1f3992..7cacb2563ee 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/RuntimeEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/RuntimeEditor.tsx @@ -92,6 +92,7 @@ import { RelationalDatabaseConnection, PackageableElementExplicitReference, ModelChainConnection, + generateIdentifiedConnectionId, } from '@finos/legend-graph'; import { useApplicationStore } from '@finos/legend-application'; import type { DSLMapping_LegendStudioPlugin_Extension } from '../../../stores/DSLMapping_LegendStudioPlugin_Extension'; @@ -386,7 +387,7 @@ const RuntimeExplorer = observer( if (element instanceof PackageableConnection) { runtimeEditorState.addIdentifiedConnection( new IdentifiedConnection( - runtimeValue.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(runtimeValue), new ConnectionPointer( PackageableElementExplicitReference.create(element), ), @@ -528,7 +529,7 @@ const IdentifiedConnectionEditor = observer( return; } const newIdentifiedConnection = new IdentifiedConnection( - runtimeValue.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(runtimeValue), customConnection, ); runtime_addIdentifiedConnection( @@ -550,7 +551,7 @@ const IdentifiedConnectionEditor = observer( PackageableElementExplicitReference.create(val.value), ); const newIdentifiedConnection = new IdentifiedConnection( - runtimeValue.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(runtimeValue), connectionPointer, ); runtime_addIdentifiedConnection( diff --git a/packages/legend-studio/src/components/editor/edit-panel/data-editor/DataElementEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/data-editor/DataElementEditor.tsx index 40b6b9c6220..e359498aa70 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/data-editor/DataElementEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/data-editor/DataElementEditor.tsx @@ -33,12 +33,14 @@ import { } from '@finos/legend-art'; import { prettyCONSTName } from '@finos/legend-shared'; import { + type TaggedValue, + type StereotypeReference, StereotypeExplicitReference, - Stereotype, Profile, - Tag, - TaggedValue, - type StereotypeReference, + stub_Stereotype, + stub_Profile, + stub_TaggedValue, + stub_Tag, } from '@finos/legend-graph'; import { annotatedElement_addStereotype, @@ -230,15 +232,13 @@ export const DataElementEditor = observer(() => { const addStereotype = (): void => { annotatedElement_addStereotype( dataElement, - StereotypeExplicitReference.create( - Stereotype.createStub(Profile.createStub()), - ), + StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())), ); }; const addTaggedValue = (): void => { annotatedElement_addTaggedValue( dataElement, - TaggedValue.createStub(Tag.createStub(Profile.createStub())), + stub_TaggedValue(stub_Tag(stub_Profile())), ); }; const deleteTaggedValue = @@ -254,7 +254,7 @@ export const DataElementEditor = observer(() => { if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addTaggedValue( dataElement, - TaggedValue.createStub(Tag.createStub(item.data.packageableElement)), + stub_TaggedValue(stub_Tag(item.data.packageableElement)), ); } }, @@ -276,7 +276,7 @@ export const DataElementEditor = observer(() => { annotatedElement_addStereotype( dataElement, StereotypeExplicitReference.create( - Stereotype.createStub(item.data.packageableElement), + stub_Stereotype(item.data.packageableElement), ), ); } diff --git a/packages/legend-studio/src/components/editor/edit-panel/element-generation-editor/FileGenerationEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/element-generation-editor/FileGenerationEditor.tsx index fbf89f62d1e..b0a44943c3a 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/element-generation-editor/FileGenerationEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/element-generation-editor/FileGenerationEditor.tsx @@ -78,6 +78,7 @@ import { PackageableElementExplicitReference, isValidFullPath, resolvePackagePathAndElementName, + getNullableFileGenerationConfig, } from '@finos/legend-graph'; import { useApplicationStore } from '@finos/legend-application'; import { StudioTextInputEditor } from '../../../shared/StudioTextInputEditor'; @@ -1347,7 +1348,7 @@ export const FileGenerationConfigurationEditor = observer( ); const getConfigValue = (name: string): unknown | undefined => - fileGeneration.getConfigValue(name); + getNullableFileGenerationConfig(fileGeneration, name)?.value; return (
diff --git a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/EnumerationMappingEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/EnumerationMappingEditor.tsx index e79d9711123..809e022b439 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/EnumerationMappingEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/EnumerationMappingEditor.tsx @@ -61,6 +61,7 @@ import { type SourceValue, type EnumerationMapping, type OptionalPackageableElementReference, + getEnumValueNames, } from '@finos/legend-graph'; import { enumMapping_updateSourceType, @@ -175,13 +176,13 @@ export const SourceValueInput = observer( // reset if not an enum value set to enum if source value not an enum if ( expectedType instanceof Enumeration && - !expectedType.getValueNames().includes(val) + !getEnumValueNames(expectedType).includes(val) ) { updateSourceValue(undefined); } else if ( expectedType instanceof Enumeration && !(sourceValue instanceof Enum) && - expectedType.getValueNames().includes(val) + getEnumValueNames(expectedType).includes(val) ) { const enumValue = expectedType.values.find((e) => e.name === val); updateSourceValue(enumValue); diff --git a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/FlatDataPropertyMappingEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/FlatDataPropertyMappingEditor.tsx index cf1146eed57..6eeb3b2d722 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/FlatDataPropertyMappingEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/FlatDataPropertyMappingEditor.tsx @@ -42,6 +42,7 @@ import { EnumerationMapping, FlatDataPropertyMapping, getEnumerationMappingsByEnumeration, + getRawGenericType, } from '@finos/legend-graph'; import { StudioLambdaEditor } from '../../../shared/StudioLambdaEditor'; import { flatDataPropertyMapping_setTransformer } from '../../../../stores/graphModifier/StoreFlatData_GraphModifierHelper'; @@ -117,8 +118,10 @@ const EnumerationPropertyMappingEditor = observer( FlatDataPropertyMapping, 'Flat-data property mapping for enumeration type property must be a simple property mapping', ); - const enumeration = - propertyMapping.property.value.genericType.value.getRawType(Enumeration); + const enumeration = getRawGenericType( + propertyMapping.property.value.genericType.value, + Enumeration, + ); const expectedType = propertyMapping.transformer ? propertyMapping.transformer.sourceType.value : enumeration; diff --git a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationEditor.tsx index 276831d26b6..f185412e970 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationEditor.tsx @@ -45,6 +45,7 @@ import { type MappingElementSource, getMappingElementSource, MappingEditorState, + getEmbeddedSetImplementations, } from '../../../../stores/editor-state/element-editor-state/mapping/MappingEditorState'; import { TypeTree } from '../../../shared/TypeTree'; import { FlatDataRecordTypeTree } from './FlatDataRecordTypeTree'; @@ -80,6 +81,8 @@ import { TableAlias, TableExplicitReference, ViewExplicitReference, + getAllRecordTypes, + getAllClassProperties, } from '@finos/legend-graph'; import { StudioLambdaEditor } from '../../../shared/StudioLambdaEditor'; import type { EditorStore } from '../../../../stores/EditorStore'; @@ -115,7 +118,7 @@ export const InstanceSetImplementationSourceExplorer = observer( const showSourceSelectorModal = (): void => { if (!isReadOnly) { const embeddedSetImpls = - setImplementation.getEmbeddedSetImplmentations(); + getEmbeddedSetImplementations(setImplementation); if (!embeddedSetImpls.length) { setSourceElementForSourceSelectorModal(null); } else { @@ -160,23 +163,22 @@ export const InstanceSetImplementationSourceExplorer = observer( ), ).catch(applicationStore.alertUnhandledError); } else if (droppedPackagableElement instanceof FlatData) { - if (droppedPackagableElement.recordTypes.length === 0) { + const allRecordTypes = getAllRecordTypes(droppedPackagableElement); + if (allRecordTypes.length === 0) { applicationStore.notifyWarning( `Source flat-data store '${droppedPackagableElement.path}' must have at least one action`, ); return; } - if (droppedPackagableElement.recordTypes.length === 1) { + if (allRecordTypes.length === 1) { flowResult( mappingEditorState.changeClassMappingSourceDriver( setImplementation, - droppedPackagableElement.recordTypes[0], + allRecordTypes[0], ), ).catch(applicationStore.alertUnhandledError); } else { - setSourceElementForSourceSelectorModal( - droppedPackagableElement.recordTypes[0], - ); + setSourceElementForSourceSelectorModal(allRecordTypes[0]); } } else if (droppedPackagableElement instanceof Database) { const relations = droppedPackagableElement.schemas.flatMap((schema) => @@ -212,7 +214,7 @@ export const InstanceSetImplementationSourceExplorer = observer( (item: MappingElementSourceDropTarget): void => { if (!setImplementation._isEmbedded && !isReadOnly) { const embeddedSetImpls = - setImplementation.getEmbeddedSetImplmentations(); + getEmbeddedSetImplementations(setImplementation); const droppedPackagableElement = item.data.packageableElement; if (!embeddedSetImpls.length) { changeClassMappingSourceDriver(droppedPackagableElement); @@ -436,8 +438,9 @@ export const InstanceSetImplementationEditor = observer( ); const handleSortChange = (): void => setSortByRequired(!sortByRequired); // Get properties of supertypes - const sortedProperties = setImplementation.class.value - .getAllProperties() + const sortedProperties = getAllClassProperties( + setImplementation.class.value, + ) // LEVEL 1: sort properties by name .sort((a, b) => a.name.localeCompare(b.name)) // LEVEL 2: sort by properties by required/type (which ever is not chosen to be the primary sort) diff --git a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationSourceSelectorModal.tsx b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationSourceSelectorModal.tsx index 2dee18d13f8..6b31ad6e13d 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationSourceSelectorModal.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/InstanceSetImplementationSourceSelectorModal.tsx @@ -37,6 +37,7 @@ import { TableAlias, TableExplicitReference, ViewExplicitReference, + getAllRecordTypes, } from '@finos/legend-graph'; import { UnsupportedOperationError } from '@finos/legend-shared'; import { flowResult } from 'mobx'; @@ -137,7 +138,7 @@ export const InstanceSetImplementationSourceSelectorModal = observer( ) .concat( editorStore.graphManagerState.graph.ownFlatDatas.flatMap( - (e) => e.recordTypes, + getAllRecordTypes, ), ) .concat( diff --git a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/MappingExecutionBuilder.tsx b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/MappingExecutionBuilder.tsx index 58cd50e3298..284261fe225 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/MappingExecutionBuilder.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/MappingExecutionBuilder.tsx @@ -69,11 +69,12 @@ import { ExecutionPlanViewer } from './execution-plan-viewer/ExecutionPlanViewer import { useEditorStore } from '../../EditorStoreProvider'; import { Class, - RawLambda, SetImplementation, OperationSetImplementation, getAllClassMappings, RelationalInputType, + stub_RawLambda, + isStubbed_RawLambda, } from '@finos/legend-graph'; import { StudioTextInputEditor } from '../../../shared/StudioTextInputEditor'; import type { DSLMapping_LegendStudioPlugin_Extension } from '../../../../stores/DSLMapping_LegendStudioPlugin_Extension'; @@ -209,7 +210,7 @@ const MappingExecutionQueryEditor = observer( Class, ), ) - : RawLambda.createStub(), + : stub_RawLambda(), ), ).catch(applicationStore.alertUnhandledError); hideClassMappingSelectorModal(); @@ -293,7 +294,7 @@ const MappingExecutionQueryEditor = observer( ); const clearQuery = applicationStore.guardUnhandledError(() => - flowResult(executionState.queryState.updateLamba(RawLambda.createStub())), + flowResult(executionState.queryState.updateLamba(stub_RawLambda())), ); return ( @@ -314,7 +315,7 @@ const MappingExecutionQueryEditor = observer(
- {!queryState.query.isStub && ( + {!isStubbed_RawLambda(queryState.query) && (
)} - {queryState.query.isStub && ( + {isStubbed_RawLambda(queryState.query) && (
{ if (mappingElement instanceof PureInstanceSetImplementation) { if (!mappingElement.filter) { - const stubLambda = RawLambda.createStub(); + const stubLambda = stub_RawLambda(); pureInstanceSetImpl_setMappingFilter(mappingElement, stubLambda); } if ( diff --git a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/MappingTestEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/MappingTestEditor.tsx index 63e8faa9a3a..6ce922c6dc8 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/MappingTestEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/MappingTestEditor.tsx @@ -74,10 +74,11 @@ import { import { useEditorStore } from '../../EditorStoreProvider'; import { Class, - RawLambda, SetImplementation, OperationSetImplementation, RelationalInputType, + stub_RawLambda, + isStubbed_RawLambda, } from '@finos/legend-graph'; import { StudioTextInputEditor } from '../../../shared/StudioTextInputEditor'; import type { DSLMapping_LegendStudioPlugin_Extension } from '../../../../stores/DSLMapping_LegendStudioPlugin_Extension'; @@ -127,7 +128,7 @@ const MappingTestQueryEditor = observer( Class, ), ) - : RawLambda.createStub(), + : stub_RawLambda(), ), ).catch(applicationStore.alertUnhandledError); hideClassMappingSelectorModal(); @@ -185,7 +186,7 @@ const MappingTestQueryEditor = observer( ); const clearQuery = applicationStore.guardUnhandledError(() => - flowResult(testState.queryState.updateLamba(RawLambda.createStub())), + flowResult(testState.queryState.updateLamba(stub_RawLambda())), ); return ( @@ -207,7 +208,7 @@ const MappingTestQueryEditor = observer(
- {!queryState.query.isStub && ( + {!isStubbed_RawLambda(queryState.query) && (
)} - {queryState.query.isStub && ( + {isStubbed_RawLambda(queryState.query) && (
({ value: si, label: si.id.value })); const filterOption = createFilter({ diff --git a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/PurePropertyMappingEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/PurePropertyMappingEditor.tsx index 2d64fa7a645..52fba8f82f7 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/PurePropertyMappingEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/PurePropertyMappingEditor.tsx @@ -41,6 +41,7 @@ import { EnumerationMapping, DerivedProperty, getEnumerationMappingsByEnumeration, + getRawGenericType, } from '@finos/legend-graph'; import { StudioLambdaEditor } from '../../../shared/StudioLambdaEditor'; import { purePropertyMapping_setTransformer } from '../../../../stores/graphModifier/DSLMapping_GraphModifierHelper'; @@ -117,8 +118,10 @@ const EnumerationPropertyMappingEditor = observer( const mappingEditorState = editorStore.getCurrentEditorState(MappingEditorState); const propertyMapping = propertyMappingState.propertyMapping; - const enumeration = - propertyMapping.property.value.genericType.value.getRawType(Enumeration); + const enumeration = getRawGenericType( + propertyMapping.property.value.genericType.value, + Enumeration, + ); const expectedType = propertyMapping.transformer ? propertyMapping.transformer.sourceType.value : enumeration; diff --git a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/relational/RelationalPropertyMappingEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/relational/RelationalPropertyMappingEditor.tsx index fe8ccde140a..9e88c38ec3d 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/relational/RelationalPropertyMappingEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/mapping-editor/relational/RelationalPropertyMappingEditor.tsx @@ -42,6 +42,7 @@ import { EnumerationMapping, RelationalPropertyMapping, getEnumerationMappingsByEnumeration, + getRawGenericType, } from '@finos/legend-graph'; import { StudioLambdaEditor } from '../../../../shared/StudioLambdaEditor'; import { relationalPropertyMapping_setTransformer } from '../../../../../stores/graphModifier/StoreRelational_GraphModifierHelper'; @@ -95,8 +96,10 @@ const EnumerationPropertyMappingEditor = observer( RelationalPropertyMapping, 'Relational property mapping for enumeration type property must be a simple property mapping', ); - const enumeration = - propertyMapping.property.value.genericType.value.getRawType(Enumeration); + const enumeration = getRawGenericType( + propertyMapping.property.value.genericType.value, + Enumeration, + ); // Enumeration Mapping Selector const options = getEnumerationMappingsByEnumeration( mappingEditorState.mapping, diff --git a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/AssociationEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/AssociationEditor.tsx index 5eb874fb85e..23c89c2ded5 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/AssociationEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/AssociationEditor.tsx @@ -54,16 +54,21 @@ import { type Association, type Property, type StereotypeReference, + type TaggedValue, MULTIPLICITY_INFINITE, - TaggedValue, - Stereotype, Profile, - Tag, Multiplicity, Class, PrimitiveType, Unit, StereotypeExplicitReference, + stub_Profile, + stub_TaggedValue, + stub_Tag, + stub_Stereotype, + getFirstAssociatedProperty, + getSecondAssociatedProperty, + getOtherAssociatedProperty, } from '@finos/legend-graph'; import { property_setName, @@ -107,7 +112,8 @@ const AssociationPropertyBasicEditor = observer( const propertyTypeOptions = editorStore.classOptions.filter( (classOption) => classOption.value !== - association.getOtherProperty(property).genericType.value.rawType, + getOtherAssociatedProperty(association, property).genericType.value + .rawType, ); const propertyType = property.genericType.value.rawType; const propertyTypeName = getClassPropertyType(propertyType); @@ -345,14 +351,12 @@ export const AssociationEditor = observer( if (selectedTab === UML_EDITOR_TAB.TAGGED_VALUES) { annotatedElement_addTaggedValue( association, - TaggedValue.createStub(Tag.createStub(Profile.createStub())), + stub_TaggedValue(stub_Tag(stub_Profile())), ); } else if (selectedTab === UML_EDITOR_TAB.STEREOTYPES) { annotatedElement_addStereotype( association, - StereotypeExplicitReference.create( - Stereotype.createStub(Profile.createStub()), - ), + StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())), ); } } @@ -374,9 +378,7 @@ export const AssociationEditor = observer( if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addTaggedValue( association, - TaggedValue.createStub( - Tag.createStub(item.data.packageableElement), - ), + stub_TaggedValue(stub_Tag(item.data.packageableElement)), ); } }, @@ -398,7 +400,7 @@ export const AssociationEditor = observer( annotatedElement_addStereotype( association, StereotypeExplicitReference.create( - Stereotype.createStub(item.data.packageableElement), + stub_Stereotype(item.data.packageableElement), ), ); } @@ -475,17 +477,17 @@ export const AssociationEditor = observer(
diff --git a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/ClassEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/ClassEditor.tsx index 393bf601af5..dea5978d027 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/ClassEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/ClassEditor.tsx @@ -54,24 +54,33 @@ import { useEditorStore } from '../../EditorStoreProvider'; import { type StereotypeReference, type GenericTypeReference, + type TaggedValue, + type Constraint, + type Property, + type DerivedProperty, PRIMITIVE_TYPE, MULTIPLICITY_INFINITE, Class, - Property, - DerivedProperty, GenericType, Profile, - Tag, - TaggedValue, - Stereotype, Multiplicity, - Constraint, Type, PrimitiveType, Unit, StereotypeExplicitReference, GenericTypeExplicitReference, Association, + stub_TaggedValue, + stub_Tag, + stub_Profile, + stub_Stereotype, + stub_Constraint, + stub_Property, + stub_DerivedProperty, + getAllClassProperties, + getAllSuperclasses, + getAllClassConstraints, + getAllClassDerivedProperties, } from '@finos/legend-graph'; import { StudioLambdaEditor } from '../../../shared/StudioLambdaEditor'; import { useApplicationStore } from '@finos/legend-application'; @@ -749,9 +758,9 @@ const SuperTypeEditor = observer( // Exclude current class classOption.value !== _class && // Exclude super types of the class - !_class.allSuperclasses.includes(classOption.value) && + !getAllSuperclasses(_class).includes(classOption.value) && // Ensure there is no loop (might be expensive) - !classOption.value.allSuperclasses.includes(_class), + !getAllSuperclasses(classOption.value).includes(_class), ); const rawType = superType.value.rawType; const filterOption = createFilter({ @@ -862,8 +871,7 @@ export const ClassFormEditor = observer( setSelectedProperty(undefined); } }; - const indirectProperties = _class - .getAllProperties() + const indirectProperties = getAllClassProperties(_class) .filter((property) => !_class.properties.includes(property)) .sort((p1, p2) => p1.name.localeCompare(p2.name)) .sort( @@ -878,9 +886,9 @@ export const ClassFormEditor = observer( class_deleteConstraint(_class, constraint); classState.deleteConstraintState(constraint); }; - const inheritedConstraints = _class - .getAllConstraints() - .filter((constraint) => !_class.constraints.includes(constraint)); + const inheritedConstraints = getAllClassConstraints(_class).filter( + (constraint) => !_class.constraints.includes(constraint), + ); // Super type const deleteSuperType = (superType: GenericTypeReference): (() => void) => @@ -896,13 +904,12 @@ export const ClassFormEditor = observer( // Exclude current class superType !== _class && // Exclude super types of the class - !_class.allSuperclasses.includes(superType) && + !getAllSuperclasses(_class).includes(superType) && // Ensure there is no loop (might be expensive) - !superType.allSuperclasses.includes(_class), + !getAllSuperclasses(superType).includes(_class), ); // Derived properties - const indirectDerivedProperties = _class - .getAllDerivedProperties() + const indirectDerivedProperties = getAllClassDerivedProperties(_class) .filter((property) => !_class.derivedProperties.includes(property)) .sort((p1, p2) => p1.name.localeCompare(p2.name)) .sort( @@ -949,13 +956,13 @@ export const ClassFormEditor = observer( const add = (): void => { if (!isReadOnly) { if (selectedTab === UML_EDITOR_TAB.PROPERTIES) { - class_addProperty(_class, Property.createStub(defaultType, _class)); + class_addProperty(_class, stub_Property(defaultType, _class)); } else if (selectedTab === UML_EDITOR_TAB.DERIVED_PROPERTIES) { - const dp = DerivedProperty.createStub(defaultType, _class); + const dp = stub_DerivedProperty(defaultType, _class); class_addDerivedProperty(_class, dp); classState.addDerivedPropertyState(dp); } else if (selectedTab === UML_EDITOR_TAB.CONSTRAINTS) { - const constraint = Constraint.createStub(_class); + const constraint = stub_Constraint(_class); class_addContraint(_class, constraint); classState.addConstraintState(constraint); } else if ( @@ -973,14 +980,12 @@ export const ClassFormEditor = observer( } else if (selectedTab === UML_EDITOR_TAB.TAGGED_VALUES) { annotatedElement_addTaggedValue( _class, - TaggedValue.createStub(Tag.createStub(Profile.createStub())), + stub_TaggedValue(stub_Tag(stub_Profile())), ); } else if (selectedTab === UML_EDITOR_TAB.STEREOTYPES) { annotatedElement_addStereotype( _class, - StereotypeExplicitReference.create( - Stereotype.createStub(Profile.createStub()), - ), + StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())), ); } } @@ -991,7 +996,7 @@ export const ClassFormEditor = observer( if (!isReadOnly && item.data.packageableElement instanceof Type) { class_addProperty( _class, - Property.createStub(item.data.packageableElement, _class), + stub_Property(item.data.packageableElement, _class), ); } }, @@ -1013,10 +1018,7 @@ export const ClassFormEditor = observer( const handleDropDerivedProperty = useCallback( (item: UMLEditorElementDropTarget): void => { if (!isReadOnly && item.data.packageableElement instanceof Type) { - const dp = DerivedProperty.createStub( - item.data.packageableElement, - _class, - ); + const dp = stub_DerivedProperty(item.data.packageableElement, _class); class_addDerivedProperty(_class, dp); classState.addDerivedPropertyState(dp); } @@ -1047,9 +1049,9 @@ export const ClassFormEditor = observer( // Must not be the same class element !== _class && // Must not be a supertype of the current class - !_class.allSuperclasses.includes(element) && + !getAllSuperclasses(_class).includes(element) && // Must not have the current class as a super type - !element.allSuperclasses.includes(_class) + !getAllSuperclasses(element).includes(_class) ) { class_addSuperType( _class, @@ -1078,9 +1080,7 @@ export const ClassFormEditor = observer( if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addTaggedValue( _class, - TaggedValue.createStub( - Tag.createStub(item.data.packageableElement), - ), + stub_TaggedValue(stub_Tag(item.data.packageableElement)), ); } }, @@ -1102,7 +1102,7 @@ export const ClassFormEditor = observer( annotatedElement_addStereotype( _class, StereotypeExplicitReference.create( - Stereotype.createStub(item.data.packageableElement), + stub_Stereotype(item.data.packageableElement), ), ); } diff --git a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/EnumerationEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/EnumerationEditor.tsx index c7b7609f25c..ec8e4650709 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/EnumerationEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/EnumerationEditor.tsx @@ -50,12 +50,15 @@ import { useEditorStore } from '../../EditorStoreProvider'; import { type Enumeration, type StereotypeReference, - Enum, + type TaggedValue, + type Enum, Profile, - Tag, - TaggedValue, - Stereotype, StereotypeExplicitReference, + stub_TaggedValue, + stub_Tag, + stub_Profile, + stub_Stereotype, + stub_Enum, } from '@finos/legend-graph'; import { enum_setName, @@ -148,14 +151,12 @@ const EnumEditor = observer( if (selectedTab === UML_EDITOR_TAB.TAGGED_VALUES) { annotatedElement_addTaggedValue( _enum, - TaggedValue.createStub(Tag.createStub(Profile.createStub())), + stub_TaggedValue(stub_Tag(stub_Profile())), ); } else if (selectedTab === UML_EDITOR_TAB.STEREOTYPES) { annotatedElement_addStereotype( _enum, - StereotypeExplicitReference.create( - Stereotype.createStub(Profile.createStub()), - ), + StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())), ); } } @@ -174,9 +175,7 @@ const EnumEditor = observer( if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addTaggedValue( _enum, - TaggedValue.createStub( - Tag.createStub(item.data.packageableElement), - ), + stub_TaggedValue(stub_Tag(item.data.packageableElement)), ); } }, @@ -198,7 +197,7 @@ const EnumEditor = observer( annotatedElement_addStereotype( _enum, StereotypeExplicitReference.create( - Stereotype.createStub(item.data.packageableElement), + stub_Stereotype(item.data.packageableElement), ), ); } @@ -357,18 +356,16 @@ export const EnumerationEditor = observer( const add = (): void => { if (!isReadOnly) { if (selectedTab === UML_EDITOR_TAB.ENUM_VALUES) { - enum_addValue(enumeration, Enum.createStub(enumeration)); + enum_addValue(enumeration, stub_Enum(enumeration)); } else if (selectedTab === UML_EDITOR_TAB.TAGGED_VALUES) { annotatedElement_addTaggedValue( enumeration, - TaggedValue.createStub(Tag.createStub(Profile.createStub())), + stub_TaggedValue(stub_Tag(stub_Profile())), ); } else if (selectedTab === UML_EDITOR_TAB.STEREOTYPES) { annotatedElement_addStereotype( enumeration, - StereotypeExplicitReference.create( - Stereotype.createStub(Profile.createStub()), - ), + StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())), ); } } @@ -395,9 +392,7 @@ export const EnumerationEditor = observer( if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addTaggedValue( enumeration, - TaggedValue.createStub( - Tag.createStub(item.data.packageableElement), - ), + stub_TaggedValue(stub_Tag(item.data.packageableElement)), ); } }, @@ -419,7 +414,7 @@ export const EnumerationEditor = observer( annotatedElement_addStereotype( enumeration, StereotypeExplicitReference.create( - Stereotype.createStub(item.data.packageableElement), + stub_Stereotype(item.data.packageableElement), ), ); } diff --git a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/ProfileEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/ProfileEditor.tsx index d8acbe68376..8b2d29c295d 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/ProfileEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/ProfileEditor.tsx @@ -29,7 +29,13 @@ import { } from '@finos/legend-art'; import { LEGEND_STUDIO_TEST_ID } from '../../../LegendStudioTestID'; import { useEditorStore } from '../../EditorStoreProvider'; -import { type Profile, Tag, Stereotype } from '@finos/legend-graph'; +import { + type Profile, + type Tag, + type Stereotype, + stub_Tag, + stub_Stereotype, +} from '@finos/legend-graph'; import { profile_addTag, profile_addStereotype, @@ -148,9 +154,9 @@ export const ProfileEditor = observer((props: { profile: Profile }) => { const addValue = (): void => { if (!isReadOnly) { if (selectedTab === UML_EDITOR_TAB.TAGS) { - profile_addTag(profile, Tag.createStub(profile)); + profile_addTag(profile, stub_Tag(profile)); } else if (selectedTab === UML_EDITOR_TAB.STEREOTYPES) { - profile_addStereotype(profile, Stereotype.createStub(profile)); + profile_addStereotype(profile, stub_Stereotype(profile)); } } }; diff --git a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/PropertyEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/PropertyEditor.tsx index 731a459a847..5aa39b1a5f3 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/PropertyEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/PropertyEditor.tsx @@ -32,11 +32,13 @@ import { type Property, type DerivedProperty, type StereotypeReference, + type TaggedValue, Profile, - Tag, - TaggedValue, - Stereotype, StereotypeExplicitReference, + stub_TaggedValue, + stub_Tag, + stub_Profile, + stub_Stereotype, } from '@finos/legend-graph'; import { annotatedElement_deleteTaggedValue, @@ -78,14 +80,12 @@ export const PropertyEditor = observer( if (selectedTab === UML_EDITOR_TAB.TAGGED_VALUES) { annotatedElement_addTaggedValue( property, - TaggedValue.createStub(Tag.createStub(Profile.createStub())), + stub_TaggedValue(stub_Tag(stub_Profile())), ); } else if (selectedTab === UML_EDITOR_TAB.STEREOTYPES) { annotatedElement_addStereotype( property, - StereotypeExplicitReference.create( - Stereotype.createStub(Profile.createStub()), - ), + StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())), ); } } @@ -104,9 +104,7 @@ export const PropertyEditor = observer( if (!isReadOnly && item.data.packageableElement instanceof Profile) { annotatedElement_addTaggedValue( property, - TaggedValue.createStub( - Tag.createStub(item.data.packageableElement), - ), + stub_TaggedValue(stub_Tag(item.data.packageableElement)), ); } }, @@ -128,7 +126,7 @@ export const PropertyEditor = observer( annotatedElement_addStereotype( property, StereotypeExplicitReference.create( - Stereotype.createStub(item.data.packageableElement), + stub_Stereotype(item.data.packageableElement), ), ); } diff --git a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/StereotypeSelector.tsx b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/StereotypeSelector.tsx index 9594733f0eb..7f1f5328dfb 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/StereotypeSelector.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/StereotypeSelector.tsx @@ -24,10 +24,11 @@ import { } from '@finos/legend-art'; import type { PackageableElementOption } from '../../../../stores/shared/PackageableElementOptionUtil'; import { useEditorStore } from '../../EditorStoreProvider'; -import type { - Profile, - StereotypeReference, - Stereotype, +import { + type Profile, + type StereotypeReference, + type Stereotype, + isStubbed_PackageableElement, } from '@finos/legend-graph'; import { stereotypeReference_setValue } from '../../../../stores/graphModifier/DomainGraphModifierHelper'; @@ -106,7 +107,7 @@ export const StereotypeSelector = observer( className={`stereotype-selector__profile__visit-btn ${ darkTheme ? 'stereotype-selector-dark-theme' : '' }`} - disabled={stereotype.value._OWNER.isStub} + disabled={isStubbed_PackageableElement(stereotype.value._OWNER)} onClick={visitProfile} tabIndex={-1} title={'Visit profile'} diff --git a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/TaggedValueEditor.tsx b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/TaggedValueEditor.tsx index b242c3e97b2..33935f7ba78 100644 --- a/packages/legend-studio/src/components/editor/edit-panel/uml-editor/TaggedValueEditor.tsx +++ b/packages/legend-studio/src/components/editor/edit-panel/uml-editor/TaggedValueEditor.tsx @@ -27,7 +27,12 @@ import { } from '@finos/legend-art'; import type { PackageableElementOption } from '../../../../stores/shared/PackageableElementOptionUtil'; import { useEditorStore } from '../../EditorStoreProvider'; -import type { TaggedValue, Tag, Profile } from '@finos/legend-graph'; +import { + type TaggedValue, + type Tag, + type Profile, + isStubbed_PackageableElement, +} from '@finos/legend-graph'; import { taggedValue_setValue, taggedValue_setTag, @@ -117,7 +122,9 @@ export const TaggedValueEditor = observer( className={`tagged-value-editor__profile__visit-btn ${ darkTheme ? 'tagged-value-editor-dark-theme' : '' }`} - disabled={taggedValue.tag.value._OWNER.isStub} + disabled={isStubbed_PackageableElement( + taggedValue.tag.value._OWNER, + )} onClick={visitProfile} tabIndex={-1} title={'Visit profile'} diff --git a/packages/legend-studio/src/components/editor/side-bar/Explorer.tsx b/packages/legend-studio/src/components/editor/side-bar/Explorer.tsx index 4d5e66ac720..cd35104e0a0 100644 --- a/packages/legend-studio/src/components/editor/side-bar/Explorer.tsx +++ b/packages/legend-studio/src/components/editor/side-bar/Explorer.tsx @@ -78,13 +78,13 @@ import type { LegendStudioConfig } from '../../../application/LegendStudioConfig import { PACKAGEABLE_ELEMENT_TYPE } from '../../../stores/shared/ModelUtil'; const isGeneratedPackageTreeNode = (node: PackageTreeNodeData): boolean => - getElementRootPackage(node.packageableElement).path === + getElementRootPackage(node.packageableElement).name === ROOT_PACKAGE_NAME.MODEL_GENERATION; const isSystemPackageTreeNode = (node: PackageTreeNodeData): boolean => - getElementRootPackage(node.packageableElement).path === + getElementRootPackage(node.packageableElement).name === ROOT_PACKAGE_NAME.SYSTEM; const isDependencyTreeNode = (node: PackageTreeNodeData): boolean => - getElementRootPackage(node.packageableElement).path === + getElementRootPackage(node.packageableElement).name === ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT; const ElementRenamer = observer(() => { diff --git a/packages/legend-studio/src/components/shared/TypeTree.tsx b/packages/legend-studio/src/components/shared/TypeTree.tsx index 0c39c96cf18..a7f5bc77791 100644 --- a/packages/legend-studio/src/components/shared/TypeTree.tsx +++ b/packages/legend-studio/src/components/shared/TypeTree.tsx @@ -43,6 +43,9 @@ import { Class, DEFAULT_SOURCE_PARAMETER_NAME, VARIABLE_REFERENCE_TOKEN, + getAllClassProperties, + getAllClassDerivedProperties, + getRawGenericType, } from '@finos/legend-graph'; import { CLASS_PROPERTY_TYPE, @@ -86,16 +89,16 @@ const getPropertyTypeTreeNodeData = ( }; switch (getClassPropertyType(property.genericType.value.rawType)) { case CLASS_PROPERTY_TYPE.CLASS: - nodeData.childrenIds = property.genericType.value - .getRawType(Class) - .getAllProperties() - .map((p) => `${nodeData.id}.${p.name}`); + nodeData.childrenIds = getAllClassProperties( + getRawGenericType(property.genericType.value, Class), + ).map((p) => `${nodeData.id}.${p.name}`); nodeData.dndType = CORE_DND_TYPE.TYPE_TREE_CLASS; break; case CLASS_PROPERTY_TYPE.ENUMERATION: - nodeData.childrenIds = property.genericType.value - .getRawType(Enumeration) - .values.map((p) => `${nodeData.id}.${p.name}`); + nodeData.childrenIds = getRawGenericType( + property.genericType.value, + Enumeration, + ).values.map((p) => `${nodeData.id}.${p.name}`); nodeData.dndType = CORE_DND_TYPE.TYPE_TREE_ENUMERATION; break; default: @@ -107,9 +110,8 @@ const getTypeTreeData = (type: Type): TreeData => { const rootIds: string[] = []; const nodes = new Map(); if (type instanceof Class) { - type - .getAllProperties() - .concat(type.getAllDerivedProperties()) + getAllClassProperties(type) + .concat(getAllClassDerivedProperties(type)) .sort((a, b) => a.name.localeCompare(b.name)) .sort( (a, b) => @@ -228,9 +230,8 @@ export const TypeTree: React.FC<{ if (node.childrenIds?.length) { node.isOpen = !node.isOpen; if (node.type instanceof Class) { - node.type - .getAllProperties() - .concat(node.type.getAllDerivedProperties()) + getAllClassProperties(node.type) + .concat(getAllClassDerivedProperties(node.type)) .forEach((property) => { const propertyTreeNodeData = getPropertyTypeTreeNodeData( property, diff --git a/packages/legend-studio/src/stores/ExplorerTreeState.ts b/packages/legend-studio/src/stores/ExplorerTreeState.ts index 5f64feebee6..1df504ac399 100644 --- a/packages/legend-studio/src/stores/ExplorerTreeState.ts +++ b/packages/legend-studio/src/stores/ExplorerTreeState.ts @@ -356,14 +356,14 @@ export class ExplorerTreeState { element, ); } - const packagePath = getElementRootPackage(element).path; + const rootPackageName = getElementRootPackage(element).name; let opened = false; - if (packagePath === ROOT_PACKAGE_NAME.MAIN && this.treeData) { + if (rootPackageName === ROOT_PACKAGE_NAME.MAIN && this.treeData) { const openingNode = openNode(this.editorStore, element, this.treeData); this.setSelectedNode(openingNode); opened = true; } else if ( - packagePath === ROOT_PACKAGE_NAME.MODEL_GENERATION && + rootPackageName === ROOT_PACKAGE_NAME.MODEL_GENERATION && this.generationTreeData ) { const openingNode = openNode( @@ -374,7 +374,7 @@ export class ExplorerTreeState { this.setSelectedNode(openingNode); opened = true; } else if ( - packagePath === ROOT_PACKAGE_NAME.SYSTEM && + rootPackageName === ROOT_PACKAGE_NAME.SYSTEM && this.systemTreeData ) { const openingNode = openNode( @@ -385,7 +385,7 @@ export class ExplorerTreeState { this.setSelectedNode(openingNode); opened = true; } else if ( - packagePath === ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT && + rootPackageName === ROOT_PACKAGE_NAME.PROJECT_DEPENDENCY_ROOT && this.dependencyTreeData ) { const openingNode = openNode( @@ -399,7 +399,7 @@ export class ExplorerTreeState { if (!opened) { this.editorStore.applicationStore.log.error( LogEvent.create(LEGEND_STUDIO_APP_EVENT.PACKAGE_TREE_BUILDER_FAILURE), - `Can't open package tree node for element '${element.path}' with package root '${packagePath}'`, + `Can't open package tree node for element '${element.path}' with root package '${rootPackageName}'`, ); } } diff --git a/packages/legend-studio/src/stores/NewElementState.ts b/packages/legend-studio/src/stores/NewElementState.ts index 7acf0c39110..3bf589500d2 100644 --- a/packages/legend-studio/src/stores/NewElementState.ts +++ b/packages/legend-studio/src/stores/NewElementState.ts @@ -60,7 +60,6 @@ import { PackageableConnection, PackageableRuntime, PureSingleExecution, - RawLambda, EngineRuntime, JsonModelConnection, FileGenerationSpecification, @@ -77,6 +76,9 @@ import { ExternalFormatData, ModelStoreData, DEPRECATED__SingleExecutionTest, + stub_Mapping, + stub_RawLambda, + stub_Database, } from '@finos/legend-graph'; import type { DSLMapping_LegendStudioPlugin_Extension } from './DSLMapping_LegendStudioPlugin_Extension'; import { @@ -262,7 +264,7 @@ export class NewRelationalDatabaseConnectionDriver extends NewConnectionValueDri selectedStore = store; } else { const dbs = this.editorStore.graphManagerState.graph.ownDatabases; - selectedStore = dbs.length ? (dbs[0] as Database) : Database.createStub(); + selectedStore = dbs.length ? (dbs[0] as Database) : stub_Database(); } return new RelationalDatabaseConnection( PackageableElementExplicitReference.create(selectedStore), @@ -744,7 +746,8 @@ export class NewElementState { break; case PACKAGEABLE_ELEMENT_TYPE.SERVICE: { const service = new Service(name); - const mapping = Mapping.createStub(); // since it does not really make sense to start with the first available mapping, we start with a stub + // since it does not really make sense to start with the first available mapping, we start with a stub + const mapping = stub_Mapping(); const runtimes = this.editorStore.graphManagerState.graph.ownRuntimes.filter( (runtime) => @@ -770,7 +773,7 @@ export class NewElementState { service_setExecution( service, new PureSingleExecution( - RawLambda.createStub(), + stub_RawLambda(), service, PackageableElementExplicitReference.create(mapping), runtimeValue, diff --git a/packages/legend-studio/src/stores/__tests__/ChangeDetection.test.ts b/packages/legend-studio/src/stores/__tests__/ChangeDetection.test.ts index aaa0a5fa517..e79081b7304 100644 --- a/packages/legend-studio/src/stores/__tests__/ChangeDetection.test.ts +++ b/packages/legend-studio/src/stores/__tests__/ChangeDetection.test.ts @@ -18,7 +18,7 @@ import { unitTest } from '@finos/legend-shared'; import { TEST__getTestEditorStore } from '../EditorStoreTestUtils'; import { flowResult } from 'mobx'; import { type EntityDiff, EntityChangeType } from '@finos/legend-server-sdlc'; -import { Class } from '@finos/legend-graph'; +import { Class, getClassProperty } from '@finos/legend-graph'; import { property_setName } from '../graphModifier/DomainGraphModifierHelper'; import { graph_addElement, @@ -73,7 +73,7 @@ test(unitTest('Change detection works properly'), async () => { const _class = editorStore.graphManagerState.graph.getClass('model::ClassA'); // modify - property_setName(_class.getProperty('prop'), 'prop1'); + property_setName(getClassProperty(_class, 'prop'), 'prop1'); await flowResult(editorStore.changeDetectionState.computeLocalChanges(true)); expect( @@ -84,7 +84,7 @@ test(unitTest('Change detection works properly'), async () => { .workspaceLocalLatestRevisionState.changes[0] as EntityDiff; expect(change.entityChangeType).toEqual(EntityChangeType.MODIFY); expect(change.oldPath).toEqual(_class.path); - property_setName(_class.getProperty('prop1'), 'prop'); // reset + property_setName(getClassProperty(_class, 'prop1'), 'prop'); // reset // add const newClass = new Class('ClassB'); diff --git a/packages/legend-studio/src/stores/editor-state/FileGenerationState.ts b/packages/legend-studio/src/stores/editor-state/FileGenerationState.ts index aad5f308c5d..4cbbee1848c 100644 --- a/packages/legend-studio/src/stores/editor-state/FileGenerationState.ts +++ b/packages/legend-studio/src/stores/editor-state/FileGenerationState.ts @@ -47,6 +47,7 @@ import { PackageableElementReference, PackageableElementExplicitReference, ELEMENT_PATH_DELIMITER, + getNullableFileGenerationConfig, } from '@finos/legend-graph'; import { configurationProperty_setValue, @@ -269,7 +270,8 @@ export class FileGenerationState { (e) => e.name !== generationProperty.name, ); } else { - const configProperty = fileGeneration.getConfig( + const configProperty = getNullableFileGenerationConfig( + fileGeneration, generationProperty.name, ); if (configProperty) { @@ -285,7 +287,10 @@ export class FileGenerationState { } } } else { - const configProperty = fileGeneration.getConfig(generationProperty.name); + const configProperty = getNullableFileGenerationConfig( + fileGeneration, + generationProperty.name, + ); let useDefaultValue = generationProperty.defaultValue === newValue; if (generationProperty.type === GenerationPropertyItemType.BOOLEAN) { useDefaultValue = diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/ClassState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/ClassState.ts index 0e337c168e5..127cf1f96fa 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/ClassState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/ClassState.ts @@ -31,6 +31,10 @@ import { ParserError, RawLambda, buildSourceInformationSourceId, + stub_RawLambda, + isStubbed_RawLambda, + getAllClassConstraints, + getAllClassDerivedProperties, } from '@finos/legend-graph'; import { LambdaEditorState } from '@finos/legend-application'; import { @@ -74,7 +78,7 @@ export class DerivedPropertyState extends LambdaEditorState { } *convertLambdaGrammarStringToObject(): GeneratorFn { - const emptyLambda = RawLambda.createStub(); + const emptyLambda = stub_RawLambda(); if (this.lambdaString) { try { const lambda = @@ -163,7 +167,7 @@ export class ConstraintState extends LambdaEditorState { } *convertLambdaGrammarStringToObject(): GeneratorFn { - const emptyFunctionDefinition = RawLambda.createStub(); + const emptyFunctionDefinition = stub_RawLambda(); if (this.lambdaString) { try { const lambda = @@ -196,7 +200,7 @@ export class ConstraintState extends LambdaEditorState { } *convertLambdaObjectToGrammarString(pretty: boolean): GeneratorFn { - if (!this.constraint.functionDefinition.isStub) { + if (!isStubbed_RawLambda(this.constraint.functionDefinition)) { try { const lambdas = new Map(); lambdas.set(this.lambdaId, this.constraint.functionDefinition); @@ -254,15 +258,13 @@ export class ClassState { this.editorStore = editorStore; this.class = _class; - this.constraintStates = _class - .getAllConstraints() - .map((constraint) => new ConstraintState(constraint, this.editorStore)); - this.derivedPropertyStates = _class - .getAllDerivedProperties() - .map( - (derivedProperty) => - new DerivedPropertyState(derivedProperty, this.editorStore), - ); + this.constraintStates = getAllClassConstraints(_class).map( + (constraint) => new ConstraintState(constraint, this.editorStore), + ); + this.derivedPropertyStates = getAllClassDerivedProperties(_class).map( + (derivedProperty) => + new DerivedPropertyState(derivedProperty, this.editorStore), + ); } getNullableConstraintState = ( @@ -332,7 +334,7 @@ export class ClassState { const lambdas = new Map(); const constraintStateMap = new Map(); this.constraintStates.forEach((constraintState) => { - if (!constraintState.constraint.functionDefinition.isStub) { + if (!isStubbed_RawLambda(constraintState.constraint.functionDefinition)) { lambdas.set( constraintState.lambdaId, constraintState.constraint.functionDefinition, @@ -373,7 +375,7 @@ export class ClassState { state.derivedProperty.parameters, state.derivedProperty.body, ); - if (!lambda.isStub) { + if (!isStubbed_RawLambda(lambda)) { lambdas.set(state.lambdaId, lambda); derivedPropertyStateMap.set(state.lambdaId, state); } @@ -404,21 +406,17 @@ export class ClassState { } decorate(): void { - this.constraintStates = this.class - .getAllConstraints() - .map( - (constraint) => - this.constraintStates.find( - (constraintState) => constraintState.constraint === constraint, - ) ?? new ConstraintState(constraint, this.editorStore), - ); - this.derivedPropertyStates = this.class - .getAllDerivedProperties() - .map( - (dp) => - this.derivedPropertyStates.find( - (state) => state.derivedProperty === dp, - ) ?? new DerivedPropertyState(dp, this.editorStore), - ); + this.constraintStates = getAllClassConstraints(this.class).map( + (constraint) => + this.constraintStates.find( + (constraintState) => constraintState.constraint === constraint, + ) ?? new ConstraintState(constraint, this.editorStore), + ); + this.derivedPropertyStates = getAllClassDerivedProperties(this.class).map( + (dp) => + this.derivedPropertyStates.find( + (state) => state.derivedProperty === dp, + ) ?? new DerivedPropertyState(dp, this.editorStore), + ); } } diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/FunctionEditorState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/FunctionEditorState.ts index 6d903adc52a..b7dcac731db 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/FunctionEditorState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/FunctionEditorState.ts @@ -33,6 +33,7 @@ import { ConcreteFunctionDefinition, RawLambda, buildSourceInformationSourceId, + isStubbed_PackageableElement, } from '@finos/legend-graph'; import { LambdaEditorState } from '@finos/legend-application'; @@ -96,7 +97,7 @@ export class FunctionBodyEditorState extends LambdaEditorState { pretty: boolean, firstLoad?: boolean, ): GeneratorFn { - if (!this.functionElement.isStub) { + if (!isStubbed_PackageableElement(this.functionElement)) { this.isConvertingFunctionBodyToString = true; try { const lambdas = new Map(); diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/RuntimeEditorState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/RuntimeEditorState.ts index 2cae1d30082..615e7425860 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/RuntimeEditorState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/RuntimeEditorState.ts @@ -62,6 +62,9 @@ import { StaticDatasourceSpecification, DefaultH2AuthenticationStrategy, ModelChainConnection, + isStubbed_StoreConnections, + getAllIdentifiedConnections, + generateIdentifiedConnectionId, } from '@finos/legend-graph'; import type { DSLMapping_LegendStudioPlugin_Extension } from '../../DSLMapping_LegendStudioPlugin_Extension'; import { packageableElementReference_setValue } from '../../graphModifier/DomainGraphModifierHelper'; @@ -161,7 +164,7 @@ export const decorateRuntimeWithNewMapping = ( runtime_addIdentifiedConnection( runtimeValue, new IdentifiedConnection( - runtimeValue.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(runtimeValue), new JsonModelConnection( PackageableElementExplicitReference.create( editorStore.graphManagerState.graph.modelStore, @@ -268,7 +271,7 @@ export const getRuntimeExplorerTreeData = ( if (store instanceof ModelStore) { // expand ModelStore to show source classes const classes = uniq( - runtimeValue.allIdentifiedConnections + getAllIdentifiedConnections(runtimeValue) .filter( (identifiedConnection) => identifiedConnection.connection.store.value instanceof @@ -394,7 +397,7 @@ export abstract class IdentifiedConnectionsEditorTabState extends RuntimeEditorT } } const newIdentifiedConnection = new IdentifiedConnection( - this.runtimeEditorState.runtimeValue.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(this.runtimeEditorState.runtimeValue), newConnection, ); runtime_addIdentifiedConnection( @@ -552,12 +555,13 @@ export class IdentifiedConnectionsPerClassEditorTabState extends IdentifiedConne } get identifiedConnections(): IdentifiedConnection[] { - return this.runtimeEditorState.runtimeValue.allIdentifiedConnections.filter( - (identifiedConnection) => - isConnectionForModelStoreWithClass( - identifiedConnection.connection, - this.class, - ), + return getAllIdentifiedConnections( + this.runtimeEditorState.runtimeValue, + ).filter((identifiedConnection) => + isConnectionForModelStoreWithClass( + identifiedConnection.connection, + this.class, + ), ); } @@ -774,7 +778,7 @@ export class RuntimeEditorState { cleanUpDecoration(): void { this.runtimeValue.connections = this.runtimeValue.connections.filter( - (storeConnections) => !storeConnections.isStub, + (storeConnections) => !isStubbed_StoreConnections(storeConnections), ); } diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/connection/ConnectionEditorState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/connection/ConnectionEditorState.ts index 486f7ab82cf..d82ac9259fd 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/connection/ConnectionEditorState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/connection/ConnectionEditorState.ts @@ -49,6 +49,7 @@ import { StaticDatasourceSpecification, RedshiftDatasourceSpecification, createValidationError, + isStubbed_PackageableElement, } from '@finos/legend-graph'; import type { DSLMapping_LegendStudioPlugin_Extension } from '../../../DSLMapping_LegendStudioPlugin_Extension'; import { @@ -116,7 +117,7 @@ export class RelationalDatabaseConnectionValueState extends ConnectionValueState } get storeValidationResult(): ValidationIssue | undefined { - return this.connection.store.value.isStub + return isStubbed_PackageableElement(this.connection.store.value) ? createValidationError(['Connection database cannot be empty']) : undefined; } diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/connection/DatabaseBuilderState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/connection/DatabaseBuilderState.ts index 409ecc866a2..aac783f26ac 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/connection/DatabaseBuilderState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/connection/DatabaseBuilderState.ts @@ -39,12 +39,15 @@ import { DatabaseBuilderInput, DatabasePattern, TargetDatabase, - getDbNullableTable, PackageableElementExplicitReference, Column, Database, isValidFullPath, resolvePackagePathAndElementName, + isStubbed_PackageableElement, + getSchema, + getNullableSchema, + getNullableTable, } from '@finos/legend-graph'; import { connection_setStore } from '../../../graphModifier/DSLMapping_GraphModifierHelper'; @@ -279,25 +282,35 @@ export class DatabaseBuilderState { const database = (yield flowResult( this.buildDatabaseFromInput(databaseBuilderInput), )) as Database; - const tables = database.getSchema(schema.name).tables; + const tables = getSchema(database, schema.name).tables; const childrenIds = schemaNode.childrenIds ?? []; schema.tables = tables; tables .slice() .sort((tableA, tableB) => tableA.name.localeCompare(tableB.name)) - .forEach((e) => { - e.schema = schema; - const tableId = `${schema.name}.${e.name}`; + .forEach((table) => { + table.schema = schema; + const tableId = `${schema.name}.${table.name}`; const tableNode = new TableDatabaseBuilderTreeNodeData( tableId, schemaNode.id, - e, + table, ); - tableNode.isChecked = Boolean( - this.currentDatabase && - getDbNullableTable(e.name, schema.name, this.currentDatabase), - ); + if (this.currentDatabase) { + const matchingSchema = getNullableSchema( + this.currentDatabase, + schema.name, + ); + tableNode.isChecked = Boolean( + matchingSchema + ? getNullableTable(matchingSchema, table.name) + : undefined, + ); + } else { + tableNode.isChecked = false; + } + treeData.nodes.set(tableId, tableNode); addUniqueEntry(childrenIds, tableId); }); @@ -601,22 +614,22 @@ export class DatabaseBuilderState { return true; }); // update existing schemas - generatedDb.schemas.forEach((s) => { - (s as Writable)._OWNER = current; + generatedDb.schemas.forEach((schema) => { + (schema as Writable)._OWNER = current; const currentSchemaIndex = current.schemas.findIndex( - (c) => c.name === s.name, + (c) => c.name === schema.name, ); if (currentSchemaIndex !== -1) { - current.schemas[currentSchemaIndex] = s; + current.schemas[currentSchemaIndex] = schema; } else { - current.schemas.push(s); + current.schemas.push(schema); } }); } get currentDatabase(): Database | undefined { const store = this.connection.store.value; - if (store instanceof Database && !store.isStub) { + if (store instanceof Database && !isStubbed_PackageableElement(store)) { return store; } return undefined; diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.ts index 60b4ed3f517..228a05c915b 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/FlatDataInstanceSetImplementationState.ts @@ -36,10 +36,10 @@ import { type AbstractFlatDataPropertyMapping, type PropertyMapping, type Property, + type RawLambda, LAMBDA_PIPE, GRAPH_MANAGER_EVENT, ParserError, - RawLambda, FlatDataPropertyMapping, EmbeddedFlatDataPropertyMapping, Class, @@ -47,6 +47,8 @@ import { PackageableElementExplicitReference, PropertyExplicitReference, buildSourceInformationSourceId, + stub_RawLambda, + isStubbed_RawLambda, } from '@finos/legend-graph'; import { MAPPING_ELEMENT_SOURCE_ID_LABEL } from './MappingEditorState'; @@ -76,7 +78,7 @@ export class FlatDataPropertyMappingState extends PropertyMappingState { } *convertLambdaGrammarStringToObject(): GeneratorFn { - const emptyLambda = RawLambda.createStub(); + const emptyLambda = stub_RawLambda(); if (this.lambdaString) { try { const lambda = @@ -108,7 +110,7 @@ export class FlatDataPropertyMappingState extends PropertyMappingState { *convertLambdaObjectToGrammarString(pretty: boolean): GeneratorFn { if (this.propertyMapping instanceof FlatDataPropertyMapping) { - if (!this.propertyMapping.transform.isStub) { + if (!isStubbed_RawLambda(this.propertyMapping.transform)) { try { const lambdas = new Map(); lambdas.set(this.lambdaId, this.propertyMapping.transform); @@ -209,7 +211,7 @@ export abstract class FlatDataInstanceSetImplementationState extends InstanceSet this.propertyMappingStates.forEach((pm) => { if ( pm.propertyMapping instanceof FlatDataPropertyMapping && - !pm.propertyMapping.transform.isStub + !isStubbed_RawLambda(pm.propertyMapping.transform) ) { lambdas.set(pm.lambdaId, pm.propertyMapping.transform); propertyMappingStates.set(pm.lambdaId, pm); diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingEditorState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingEditorState.ts index e55bfcfb71d..bf81e1dec4e 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingEditorState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingEditorState.ts @@ -64,6 +64,7 @@ import { type PackageableElement, type InputData, type Type, + type EmbeddedSetImplementation, getAllClassMappings, GRAPH_MANAGER_EVENT, PRIMITIVE_TYPE, @@ -99,6 +100,8 @@ import { AssociationImplementation, InferableMappingElementIdExplicitValue, InferableMappingElementRootExplicitValue, + stub_Class, + findPropertyMapping, } from '@finos/legend-graph'; import { LambdaEditorState } from '@finos/legend-application'; import type { @@ -391,14 +394,29 @@ export const createEnumerationMapping = ( return enumMapping; }; -// We use get `own` Class mapping as embedded set implementations can only be within the +export const getEmbeddedSetImplementations = ( + setImpl: InstanceSetImplementation, +): InstanceSetImplementation[] => { + const embeddedPropertyMappings = setImpl.propertyMappings.filter( + // NOTE: we use this convenient flag to check if something is embedded mapping or not + // however, in reality, we can check for presence of `propertyMappings`, or more overkill + // do an extension mechanism to figure this out, for example, do an extension mechanism + // to check if an instance set implementation is embedded or not + (pm) => pm._isEmbedded, + ) as EmbeddedSetImplementation[]; + return embeddedPropertyMappings + .flatMap(getEmbeddedSetImplementations) + .concat(embeddedPropertyMappings); +}; + +// We only care to get `own` class mapping as embedded set implementations can only be within the // current class mapping i.e current mapping. -const getEmbeddedSetImplmentations = ( +const getMappingEmbeddedSetImplementations = ( mapping: Mapping, ): InstanceSetImplementation[] => - mapping.allOwnClassMappings + mapping.classMappings .filter(filterByType(InstanceSetImplementation)) - .map((setImpl) => setImpl.getEmbeddedSetImplmentations()) + .map(getEmbeddedSetImplementations) .flat(); /* @MARKER: NEW CLASS MAPPING TYPE SUPPORT --- consider adding class mapping type handler here whenever support for a new one is added to the app */ @@ -413,7 +431,7 @@ const getMappingElementByTypeAndId = ( case MAPPING_ELEMENT_SOURCE_ID_LABEL.OPERATION_CLASS_MAPPING: case MAPPING_ELEMENT_SOURCE_ID_LABEL.AGGREGATION_AWARE_CLASS_MAPPING: case MAPPING_ELEMENT_SOURCE_ID_LABEL.PURE_INSTANCE_CLASS_MAPPING: - return mapping.allOwnClassMappings.find( + return mapping.classMappings.find( (classMapping) => classMapping.id.value === id, ); case MAPPING_ELEMENT_SOURCE_ID_LABEL.FLAT_DATA_CLASS_MAPPING: @@ -421,7 +439,7 @@ const getMappingElementByTypeAndId = ( getAllClassMappings(mapping).find( (classMapping) => classMapping.id.value === id, ) ?? - getEmbeddedSetImplmentations(mapping) + getMappingEmbeddedSetImplementations(mapping) .filter(filterByType(EmbeddedFlatDataPropertyMapping)) .find((me) => me.id.value === id) ); @@ -430,7 +448,7 @@ const getMappingElementByTypeAndId = ( getAllClassMappings(mapping).find( (classMapping) => classMapping.id.value === id, ) ?? - getEmbeddedSetImplmentations(mapping) + getMappingEmbeddedSetImplementations(mapping) .filter(filterByType(EmbeddedRelationalInstanceSetImplementation)) .find((me) => me.id.value === id) ); @@ -911,7 +929,7 @@ export class MappingEditorState extends ElementEditorState { } else if ( setImplementation instanceof FlatDataInstanceSetImplementation && newSource instanceof RootFlatDataRecordType && - !setImplementation.getEmbeddedSetImplmentations().length + !getEmbeddedSetImplementations(setImplementation).length ) { flatData_setSourceRootRecordType(setImplementation, newSource); } else { @@ -992,7 +1010,7 @@ export class MappingEditorState extends ElementEditorState { mappingElement, ) ) { - const embeddedChildren = mappingElement.getEmbeddedSetImplmentations(); + const embeddedChildren = getEmbeddedSetImplementations(mappingElement); mappingElementsToClose = mappingElementsToClose.concat(embeddedChildren); } const matchMappingElementState = ( @@ -1226,7 +1244,8 @@ export class MappingEditorState extends ElementEditorState { newMappingElement instanceof FlatDataInstanceSetImplementation || newMappingElement instanceof EmbeddedFlatDataPropertyMapping ) { - const propertyMapping = newMappingElement.findPropertyMapping( + const propertyMapping = findPropertyMapping( + newMappingElement, guaranteeNonNullable( propertyName, `Can't reveal compilation error: mapping property name is missing`, @@ -1447,9 +1466,7 @@ export class MappingEditorState extends ElementEditorState { let inputData: InputData; if (source === undefined || source instanceof Class) { inputData = new ObjectInputData( - PackageableElementExplicitReference.create( - source ?? Class.createStub(), - ), + PackageableElementExplicitReference.create(source ?? stub_Class()), ObjectInputType.JSON, source ? createMockDataForMappingElementSource(source, this.editorStore) diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingElementDecorator.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingElementDecorator.ts index beac2e706e5..8de118e56a4 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingElementDecorator.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingElementDecorator.ts @@ -41,7 +41,6 @@ import { EmbeddedFlatDataPropertyMapping, EnumValueMapping, PrimitiveType, - RawLambda, Enumeration, Class, FlatDataPropertyMapping, @@ -50,10 +49,18 @@ import { EnumValueExplicitReference, PropertyExplicitReference, RelationalPropertyMapping, - createStubRelationalOperationElement, EmbeddedRelationalInstanceSetImplementation, getEnumerationMappingsByEnumeration, getRootSetImplementation, + stub_RawLambda, + stub_RawRelationalOperationElement, + isStubbed_RawLambda, + isStubbed_RawRelationalOperationElement, + isStubbed_EnumValueMapping, + isStubbed_SetImplementationContainer, + getLeafSetImplementations, + getAllClassProperties, + getRawGenericType, } from '@finos/legend-graph'; import type { DSLMapping_LegendStudioPlugin_Extension } from '../../../DSLMapping_LegendStudioPlugin_Extension'; import type { EditorStore } from '../../../EditorStore'; @@ -90,7 +97,7 @@ export const getDecoratedSetImplementationPropertyMappings = < propertyMappingMap.set(pm.property.value.name, [pm]); } }); - setImp.class.value.getAllProperties().forEach((property) => { + getAllClassProperties(setImp.class.value).forEach((property) => { propertyMappingMap.set( property.name, decoratePropertyMapping(propertyMappingMap.get(property.name), property), @@ -99,7 +106,7 @@ export const getDecoratedSetImplementationPropertyMappings = < return Array.from(propertyMappingMap.values()).flat(); }; -export const getLeafSetImplementations = ( +export const getLeafSetImplementationsForClass = ( mapping: Mapping, _class: Class, ): SetImplementation[] | undefined => { @@ -108,7 +115,7 @@ export const getLeafSetImplementations = ( return undefined; } if (setImp instanceof OperationSetImplementation) { - return setImp.leafSetImplementations; + return getLeafSetImplementations(setImp); } return [setImp]; }; @@ -186,7 +193,7 @@ export class MappingElementDecorator implements SetImplementationVisitor { // before decoration, make sure to prune stubbed property mappings in case they are nolonger compatible // with the set implemenetation (this happens when we switch sources) const existingPropertyMappings = (propertyMappings ?? []).filter( - (pm) => !pm.isStub, + (pm) => !isStubbed_RawLambda(pm.transform), ); const propertyType = property.genericType.value.rawType; if ( @@ -206,7 +213,7 @@ export class MappingElementDecorator implements SetImplementationVisitor { new PurePropertyMapping( setImplementation, PropertyExplicitReference.create(property), - RawLambda.createStub(), + stub_RawLambda(), setImplementation, ), ]; @@ -223,16 +230,18 @@ export class MappingElementDecorator implements SetImplementationVisitor { new PurePropertyMapping( setImplementation, PropertyExplicitReference.create(property), - RawLambda.createStub(), + stub_RawLambda(), setImplementation, ), ]; // Find existing enumeration mappings for the property enumeration const existingEnumerationMappings = getEnumerationMappingsByEnumeration( setImplementation._PARENT, - ( - enumerationPropertyMapping[0] as PurePropertyMapping - ).property.value.genericType.value.getRawType(Enumeration), + getRawGenericType( + (enumerationPropertyMapping[0] as PurePropertyMapping).property + .value.genericType.value, + Enumeration, + ), ); enumerationPropertyMapping.forEach((epm) => { // If there are no enumeration mappings, delete the transformer of the property mapping @@ -256,9 +265,9 @@ export class MappingElementDecorator implements SetImplementationVisitor { // TODO: should we try to get leaf implementation here from the root // or should we just simply find all class mappings for the target class // as we should not try to `understand` operation class mapping union? - getLeafSetImplementations( + getLeafSetImplementationsForClass( setImplementation._PARENT, - property.genericType.value.getRawType(Class), + getRawGenericType(property.genericType.value, Class), ); // if there are no root-resolved set implementations for the class, return empty array if (!resolvedLeafSetImps) { @@ -277,7 +286,7 @@ export class MappingElementDecorator implements SetImplementationVisitor { new PurePropertyMapping( setImplementation, PropertyExplicitReference.create(property), - RawLambda.createStub(), + stub_RawLambda(), setImplementation, setImp, ), @@ -323,9 +332,12 @@ export class MappingElementDecorator implements SetImplementationVisitor { ): AbstractFlatDataPropertyMapping[] => { // before decoration, make sure to prune stubbed property mappings in case they are nolonger compatible // with the set implemenetation (this happens when we switch sources) - const existingPropertyMappings = (propertyMappings ?? []).filter( - (pm) => !pm.isStub, - ); + const existingPropertyMappings = (propertyMappings ?? []).filter((pm) => { + if (pm instanceof FlatDataPropertyMapping) { + return !isStubbed_RawLambda(pm.transform); + } + return true; + }); const propertyType = property.genericType.value.rawType; if ( propertyType instanceof PrimitiveType || @@ -344,7 +356,7 @@ export class MappingElementDecorator implements SetImplementationVisitor { new FlatDataPropertyMapping( setImplementation, PropertyExplicitReference.create(property), - RawLambda.createStub(), + stub_RawLambda(), setImplementation, ), ]; @@ -361,16 +373,18 @@ export class MappingElementDecorator implements SetImplementationVisitor { new FlatDataPropertyMapping( setImplementation, PropertyExplicitReference.create(property), - RawLambda.createStub(), + stub_RawLambda(), setImplementation, ), ]; // Find existing enumeration mappings for the property enumeration const existingEnumerationMappings = getEnumerationMappingsByEnumeration( setImplementation._PARENT, - ( - ePropertyMapping[0] as FlatDataPropertyMapping - ).property.value.genericType.value.getRawType(Enumeration), + getRawGenericType( + (ePropertyMapping[0] as FlatDataPropertyMapping).property.value + .genericType.value, + Enumeration, + ), ); ePropertyMapping.forEach((epm) => { assertType( @@ -441,9 +455,14 @@ export class MappingElementDecorator implements SetImplementationVisitor { ): PropertyMapping[] => { // before decoration, make sure to prune stubbed property mappings in case they are nolonger compatible // with the set implemenetation (this happens when we switch sources) - const existingPropertyMappings = (propertyMappings ?? []).filter( - (pm) => !pm.isStub, - ); + const existingPropertyMappings = (propertyMappings ?? []).filter((pm) => { + if (pm instanceof RelationalPropertyMapping) { + return !isStubbed_RawRelationalOperationElement( + pm.relationalOperation, + ); + } + return true; + }); const propertyType = property.genericType.value.rawType; if ( propertyType instanceof PrimitiveType || @@ -466,7 +485,7 @@ export class MappingElementDecorator implements SetImplementationVisitor { setImplementation, ); newPropertyMapping.relationalOperation = - createStubRelationalOperationElement(); + stub_RawRelationalOperationElement(); return [newPropertyMapping]; } else if (propertyType instanceof Enumeration) { // only allow one property mapping per enumeration property @@ -486,15 +505,17 @@ export class MappingElementDecorator implements SetImplementationVisitor { setImplementation, ); newPropertyMapping.relationalOperation = - createStubRelationalOperationElement(); + stub_RawRelationalOperationElement(); ePropertyMapping = [newPropertyMapping]; } // Find existing enumeration mappings for the property enumeration const existingEnumerationMappings = getEnumerationMappingsByEnumeration( setImplementation._PARENT, - ( - ePropertyMapping[0] as PropertyMapping - ).property.value.genericType.value.getRawType(Enumeration), + getRawGenericType( + (ePropertyMapping[0] as PropertyMapping).property.value.genericType + .value, + Enumeration, + ), ); ePropertyMapping.forEach((epm) => { assertType( @@ -520,9 +541,9 @@ export class MappingElementDecorator implements SetImplementationVisitor { // TODO: should we try to get leaf implementation here from the root // or should we just simply find all class mappings for the target class // as we should not try to `understand` operation class mapping union? - const resolvedLeafSetImps = getLeafSetImplementations( + const resolvedLeafSetImps = getLeafSetImplementationsForClass( setImplementation._PARENT, - property.genericType.value.getRawType(Class), + getRawGenericType(property.genericType.value, Class), ); // if there are no root-resolved set implementations for the class, return empty array if (resolvedLeafSetImps) { @@ -544,7 +565,7 @@ export class MappingElementDecorator implements SetImplementationVisitor { setImp, ); newPropertyMapping.relationalOperation = - createStubRelationalOperationElement(); + stub_RawRelationalOperationElement(); return newPropertyMapping; }) // sort these property mappings by id of their set implementations @@ -625,7 +646,7 @@ export class MappingElementDecorationCleaner // Remove the enum value mapping if all of its source values are empty const nonEmptyEnumValueMappings = enumerationMapping.enumValueMappings.filter( - (enumValueMapping) => !enumValueMapping.isStub, + (enumValueMapping) => !isStubbed_EnumValueMapping(enumValueMapping), ); // Prune the empty source values of each enum value mapping nonEmptyEnumValueMappings.forEach((enumValueMapping) => { @@ -645,7 +666,9 @@ export class MappingElementDecorationCleaner ): void { operationMapping_setParameters( setImplementation, - setImplementation.parameters.filter((param) => !param.isStub), + setImplementation.parameters.filter( + (param) => !isStubbed_SetImplementationContainer(param), + ), ); } @@ -654,7 +677,9 @@ export class MappingElementDecorationCleaner ): void { operationMapping_setParameters( setImplementation, - setImplementation.parameters.filter((param) => !param.isStub), + setImplementation.parameters.filter( + (param) => !isStubbed_SetImplementationContainer(param), + ), ); } @@ -664,7 +689,7 @@ export class MappingElementDecorationCleaner mapping_setPropertyMappings( setImplementation, setImplementation.propertyMappings.filter( - (propertyMapping) => !propertyMapping.transform.isStub, + (propertyMapping) => !isStubbed_RawLambda(propertyMapping.transform), ), this.editorStore.changeDetectionState.observerContext, ); @@ -680,7 +705,7 @@ export class MappingElementDecorationCleaner setImplementation.propertyMappings.filter( (propertyMapping) => (propertyMapping instanceof FlatDataPropertyMapping && - !propertyMapping.transform.isStub) || + !isStubbed_RawLambda(propertyMapping.transform)) || (propertyMapping instanceof EmbeddedFlatDataPropertyMapping && propertyMapping.property), ), @@ -708,7 +733,9 @@ export class MappingElementDecorationCleaner setImplementation.propertyMappings.filter( (propertyMapping) => (propertyMapping instanceof RelationalPropertyMapping && - !propertyMapping.isStub) || + !isStubbed_RawRelationalOperationElement( + propertyMapping.relationalOperation, + )) || propertyMapping instanceof EmbeddedRelationalInstanceSetImplementation, ), diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingExecutionState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingExecutionState.ts index 71d2326edef..236f2cc1d55 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingExecutionState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingExecutionState.ts @@ -59,6 +59,8 @@ import { type SetImplementation, type Table, type View, + type RawLambda, + type RawExecutionPlan, extractExecutionResultValues, LAMBDA_PIPE, GRAPH_MANAGER_EVENT, @@ -67,7 +69,6 @@ import { ObjectInputData, ObjectInputType, ExpectedOutputMappingTestAssert, - RawLambda, IdentifiedConnection, EngineRuntime, JsonModelConnection, @@ -89,7 +90,9 @@ import { buildSourceInformationSourceId, PureClientVersion, TableAlias, - type RawExecutionPlan, + stub_RawLambda, + isStubbed_RawLambda, + generateIdentifiedConnectionId, } from '@finos/legend-graph'; import { ActionAlertActionType, @@ -146,7 +149,7 @@ export class MappingExecutionQueryState extends LambdaEditorState { } *convertLambdaObjectToGrammarString(pretty?: boolean): GeneratorFn { - if (!this.query.isStub) { + if (!isStubbed_RawLambda(this.query)) { try { const lambdas = new Map(); lambdas.set(this.lambdaId, this.query); @@ -215,7 +218,7 @@ export const createRuntimeForExecution = ( runtime_addIdentifiedConnection( runtime, new IdentifiedConnection( - runtime.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(runtime), connection, ), editorStore.changeDetectionState.observerContext, @@ -472,7 +475,7 @@ export class MappingExecutionState { this.name = name; this.queryState = new MappingExecutionQueryState( editorStore, - RawLambda.createStub(), + stub_RawLambda(), ); this.inputDataState = new MappingExecutionEmptyInputDataState( editorStore, @@ -501,7 +504,7 @@ export class MappingExecutionState { reset(): void { this.queryState = new MappingExecutionQueryState( this.editorStore, - RawLambda.createStub(), + stub_RawLambda(), ); this.inputDataState = new MappingExecutionEmptyInputDataState( this.editorStore, @@ -576,7 +579,7 @@ export class MappingExecutionState { try { const query = this.queryState.query; if ( - !this.queryState.query.isStub && + !isStubbed_RawLambda(this.queryState.query) && this.inputDataState.isValid && this.inputDataState.inputData && this.executionResultText @@ -611,7 +614,7 @@ export class MappingExecutionState { try { const query = this.queryState.query; if ( - !this.queryState.query.isStub && + !isStubbed_RawLambda(this.queryState.query) && this.inputDataState.isValid && this.executionResultText ) { @@ -670,7 +673,7 @@ export class MappingExecutionState { const query = this.queryState.query; const runtime = this.inputDataState.runtime; if ( - !this.queryState.query.isStub && + !isStubbed_RawLambda(this.queryState.query) && this.inputDataState.isValid && !this.isExecuting ) { @@ -712,7 +715,7 @@ export class MappingExecutionState { const query = this.queryState.query; const runtime = this.inputDataState.runtime; if ( - !this.queryState.query.isStub && + !isStubbed_RawLambda(this.queryState.query) && this.inputDataState.isValid && !this.isGeneratingPlan ) { @@ -774,7 +777,7 @@ export class MappingExecutionState { ? this.editorStore.graphManagerState.graphManager.HACKY__createGetAllLambda( guaranteeType(getMappingElementTarget(setImplementation), Class), ) - : RawLambda.createStub(), + : stub_RawLambda(), ), ); diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingTestState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingTestState.ts index ef05cbf9ce3..509a21b1812 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingTestState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/MappingTestState.ts @@ -81,6 +81,9 @@ import { PureClientVersion, TableAlias, type RawExecutionPlan, + isStubbed_RawLambda, + stub_Class, + generateIdentifiedConnectionId, } from '@finos/legend-graph'; import { LambdaEditorState, TAB_SIZE } from '@finos/legend-application'; import { flatData_setData } from '../../../graphModifier/StoreFlatData_GraphModifierHelper'; @@ -141,7 +144,7 @@ export class MappingTestQueryState extends LambdaEditorState { } *convertLambdaObjectToGrammarString(pretty?: boolean): GeneratorFn { - if (!this.query.isStub) { + if (!isStubbed_RawLambda(this.query)) { try { const lambdas = new Map(); lambdas.set(this.lambdaId, this.query); @@ -252,7 +255,7 @@ export class MappingTestObjectInputDataState extends MappingTestInputDataState { runtime_addIdentifiedConnection( runtime, new IdentifiedConnection( - runtime.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(runtime), connection, ), this.editorStore.changeDetectionState.observerContext, @@ -285,7 +288,7 @@ export class MappingTestFlatDataInputDataState extends MappingTestInputDataState runtime_addIdentifiedConnection( runtime, new IdentifiedConnection( - runtime.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(runtime), connection, ), this.editorStore.changeDetectionState.observerContext, @@ -330,7 +333,7 @@ export class MappingTestRelationalInputDataState extends MappingTestInputDataSta runtime_addIdentifiedConnection( runtime, new IdentifiedConnection( - runtime.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(runtime), connection, ), this.editorStore.changeDetectionState.observerContext, @@ -527,9 +530,7 @@ export class MappingTestState { this.editorStore, this.mappingEditorState.mapping, new ObjectInputData( - PackageableElementExplicitReference.create( - source ?? Class.createStub(), - ), + PackageableElementExplicitReference.create(source ?? stub_Class()), ObjectInputType.JSON, tryToMinifyJSONString('{}'), ), diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.ts index 871d9e9d4ef..6554f6e18b5 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/PureInstanceSetImplementationState.ts @@ -31,11 +31,13 @@ import { MAPPING_ELEMENT_SOURCE_ID_LABEL } from './MappingEditorState'; import { type PurePropertyMapping, type PureInstanceSetImplementation, + type RawLambda, LAMBDA_PIPE, GRAPH_MANAGER_EVENT, ParserError, - RawLambda, buildSourceInformationSourceId, + stub_RawLambda, + isStubbed_RawLambda, } from '@finos/legend-graph'; import { LambdaEditorState } from '@finos/legend-application'; import { pureInstanceSetImpl_setMappingFilter } from '../../../graphModifier/DSLMapping_GraphModifierHelper'; @@ -71,7 +73,7 @@ export class PurePropertyMappingState extends PropertyMappingState { } *convertLambdaGrammarStringToObject(): GeneratorFn { - const emptyLambda = RawLambda.createStub(); + const emptyLambda = stub_RawLambda(); if (this.lambdaString) { try { const lambda = @@ -98,7 +100,7 @@ export class PurePropertyMappingState extends PropertyMappingState { } *convertLambdaObjectToGrammarString(pretty: boolean): GeneratorFn { - if (!this.propertyMapping.transform.isStub) { + if (!isStubbed_RawLambda(this.propertyMapping.transform)) { try { const lambdas = new Map(); lambdas.set(this.lambdaId, this.propertyMapping.transform); @@ -155,7 +157,7 @@ export class PureInstanceSetImplementationFilterState extends LambdaEditorState } *convertLambdaGrammarStringToObject(): GeneratorFn { - const emptyFunctionDefinition = RawLambda.createStub(); + const emptyFunctionDefinition = stub_RawLambda(); if (this.lambdaString) { try { const lambda = @@ -181,7 +183,7 @@ export class PureInstanceSetImplementationFilterState extends LambdaEditorState } } else { this.clearErrors(); - if (this.instanceSetImplementation.filter?.isStub) { + if (this.instanceSetImplementation.filter) { pureInstanceSetImpl_setMappingFilter( this.instanceSetImplementation, emptyFunctionDefinition, @@ -191,10 +193,7 @@ export class PureInstanceSetImplementationFilterState extends LambdaEditorState } *convertLambdaObjectToGrammarString(pretty: boolean): GeneratorFn { - if ( - this.instanceSetImplementation.filter && - !this.instanceSetImplementation.isStub - ) { + if (this.instanceSetImplementation.filter) { try { const grammarText = (yield this.editorStore.graphManagerState.graphManager.lambdaToPureCode( @@ -294,7 +293,7 @@ export class PureInstanceSetImplementationState extends InstanceSetImplementatio const lambdas = new Map(); const propertyMappingsMap = new Map(); this.propertyMappingStates.forEach((pm) => { - if (!pm.propertyMapping.transform.isStub) { + if (!isStubbed_RawLambda(pm.propertyMapping.transform)) { lambdas.set(pm.lambdaId, pm.propertyMapping.transform); propertyMappingsMap.set(pm.lambdaId, pm); } diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/relational/RelationalInstanceSetImplementationState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/relational/RelationalInstanceSetImplementationState.ts index 5776853b9f2..ce88d90ff1a 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/relational/RelationalInstanceSetImplementationState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/mapping/relational/RelationalInstanceSetImplementationState.ts @@ -37,11 +37,12 @@ import { type CompilationError, type SourceInformation, RelationalPropertyMapping, - createStubRelationalOperationElement, ParserError, GRAPH_MANAGER_EVENT, EmbeddedRelationalInstanceSetImplementation, buildSourceInformationSourceId, + isStubbed_RawRelationalOperationElement, + stub_RawRelationalOperationElement, } from '@finos/legend-graph'; export class RelationalPropertyMappingState extends PropertyMappingState { @@ -78,7 +79,7 @@ export class RelationalPropertyMappingState extends PropertyMappingState { } *convertLambdaGrammarStringToObject(): GeneratorFn { - const stubOperation = createStubRelationalOperationElement(); + const stubOperation = stub_RawRelationalOperationElement(); if (this.lambdaString) { try { const operation = @@ -110,7 +111,7 @@ export class RelationalPropertyMappingState extends PropertyMappingState { *convertLambdaObjectToGrammarString(pretty: boolean): GeneratorFn { if (this.propertyMapping instanceof RelationalPropertyMapping) { - if (!this.propertyMapping.isStub) { + if (!isStubbed_RawRelationalOperationElement(this.propertyMapping)) { try { const operations = new Map(); operations.set( @@ -310,7 +311,9 @@ export class RootRelationalInstanceSetImplementationState extends RelationalInst this.propertyMappingStates.forEach((pmState) => { if ( pmState.propertyMapping instanceof RelationalPropertyMapping && - !pmState.propertyMapping.isStub + !isStubbed_RawRelationalOperationElement( + pmState.propertyMapping.relationalOperation, + ) ) { operations.set( pmState.lambdaId, diff --git a/packages/legend-studio/src/stores/editor-state/element-editor-state/service/LegacyServiceTestState.ts b/packages/legend-studio/src/stores/editor-state/element-editor-state/service/LegacyServiceTestState.ts index 2b6383232be..514a64a6dea 100644 --- a/packages/legend-studio/src/stores/editor-state/element-editor-state/service/LegacyServiceTestState.ts +++ b/packages/legend-studio/src/stores/editor-state/element-editor-state/service/LegacyServiceTestState.ts @@ -63,6 +63,7 @@ import { ConnectionPointer, PackageableElementExplicitReference, PureClientVersion, + generateIdentifiedConnectionId, } from '@finos/legend-graph'; import { TAB_SIZE } from '@finos/legend-application'; import type { DSLService_LegendStudioPlugin_Extension } from '../../../DSLService_LegendStudioPlugin_Extension'; @@ -203,7 +204,7 @@ export class TestContainerState { runtime_addIdentifiedConnection( newRuntime, new IdentifiedConnection( - newRuntime.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(newRuntime), new JsonModelConnection( PackageableElementExplicitReference.create( this.editorStore.graphManagerState.graph.modelStore, @@ -225,7 +226,7 @@ export class TestContainerState { runtime_addIdentifiedConnection( newRuntime, new IdentifiedConnection( - newRuntime.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(newRuntime), new XmlModelConnection( PackageableElementExplicitReference.create( this.editorStore.graphManagerState.graph.modelStore, @@ -244,7 +245,7 @@ export class TestContainerState { runtime_addIdentifiedConnection( newRuntime, new IdentifiedConnection( - newRuntime.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(newRuntime), new FlatDataConnection( PackageableElementExplicitReference.create( connection.store.value, @@ -262,7 +263,7 @@ export class TestContainerState { runtime_addIdentifiedConnection( newRuntime, new IdentifiedConnection( - newRuntime.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(newRuntime), new RelationalDatabaseConnection( PackageableElementExplicitReference.create( connection.store.value, @@ -296,7 +297,7 @@ export class TestContainerState { runtime_addIdentifiedConnection( newRuntime, new IdentifiedConnection( - newRuntime.generateIdentifiedConnectionId(), + generateIdentifiedConnectionId(newRuntime), testConnection, ), this.editorStore.changeDetectionState.observerContext, diff --git a/packages/legend-studio/src/stores/graphModifier/DSLMapping_GraphModifierHelper.ts b/packages/legend-studio/src/stores/graphModifier/DSLMapping_GraphModifierHelper.ts index 2aa05f73f24..19f1bfe385c 100644 --- a/packages/legend-studio/src/stores/graphModifier/DSLMapping_GraphModifierHelper.ts +++ b/packages/legend-studio/src/stores/graphModifier/DSLMapping_GraphModifierHelper.ts @@ -72,6 +72,8 @@ import { observe_Class, observe_Connection, observe_EngineRuntime, + getEnumValueNames, + getEnumValue, } from '@finos/legend-graph'; import { addUniqueEntry, @@ -230,9 +232,9 @@ export const enumValueMapping_updateSourceValue = action( if ( sourceType instanceof Enumeration && typeof val === 'string' && - sourceType.getValueNames().includes(val) + getEnumValueNames(sourceType).includes(val) ) { - sourceValue_setValue(sourceValue, sourceType.getValue(val)); + sourceValue_setValue(sourceValue, getEnumValue(sourceType, val)); } else { // Here we update the source values depending on the source type. sourceValue_setValue( diff --git a/packages/legend-studio/src/stores/graphModifier/DomainGraphModifierHelper.ts b/packages/legend-studio/src/stores/graphModifier/DomainGraphModifierHelper.ts index d402ea9e092..765649ec3f3 100644 --- a/packages/legend-studio/src/stores/graphModifier/DomainGraphModifierHelper.ts +++ b/packages/legend-studio/src/stores/graphModifier/DomainGraphModifierHelper.ts @@ -62,6 +62,8 @@ import { observe_Type, observe_Unit, observe_RawLambda, + isStubbed_PackageableElement, + getOtherAssociatedProperty, } from '@finos/legend-graph'; // --------------------------------------------- PackageableElementReference ------------------------------------- @@ -119,11 +121,11 @@ export const class_deleteSuperType = action( }, ); export const class_addSubclass = action((_class: Class, val: Class): void => { - addUniqueEntry(_class.subclasses, val); + addUniqueEntry(_class._subclasses, val); }); export const class_deleteSubclass = action( (_class: Class, val: Class): void => { - deleteEntry(_class.subclasses, val); + deleteEntry(_class._subclasses, val); }, ); @@ -307,7 +309,7 @@ export const enumValueReference_setValue = action( export const association_changePropertyType = action( (association: Association, property: Property, type: Class): void => { - const otherProperty = association.getOtherProperty(property); + const otherProperty = getOtherAssociatedProperty(association, property); // remove other property from current parent class of the to-be-changed property const otherPropertyAssociatedClass = guaranteeType( property.genericType.ownerReference.value, @@ -315,7 +317,7 @@ export const association_changePropertyType = action( `Association property '${property.name}' must be of type 'class'`, ); // don't invoke deletion if the class is a stub (otherProperty is not present) - if (!otherPropertyAssociatedClass.isStub) { + if (!isStubbed_PackageableElement(otherPropertyAssociatedClass)) { assertTrue( deleteEntry( otherPropertyAssociatedClass.propertiesFromAssociations, diff --git a/packages/legend-studio/src/stores/shared/MockDataUtil.ts b/packages/legend-studio/src/stores/shared/MockDataUtil.ts index 75e6f7f86c6..05223b15756 100644 --- a/packages/legend-studio/src/stores/shared/MockDataUtil.ts +++ b/packages/legend-studio/src/stores/shared/MockDataUtil.ts @@ -28,6 +28,7 @@ import { type Enumeration, PRIMITIVE_TYPE, Class, + getAllClassProperties, } from '@finos/legend-graph'; import { DATE_FORMAT, DATE_TIME_FORMAT } from '@finos/legend-application'; import { CLASS_PROPERTY_TYPE, getClassPropertyType } from './ModelUtil'; @@ -82,8 +83,8 @@ export const createMockClassInstance = ( depth = 0, ): Record => { const properties = traverseNonRequiredProperties - ? _class.getAllProperties() - : _class.getAllProperties().filter((p) => p.multiplicity.lowerBound); + ? getAllClassProperties(_class) + : getAllClassProperties(_class).filter((p) => p.multiplicity.lowerBound); const mockData: Record = {}; properties.forEach((property) => { const propertyType = property.genericType.value.rawType; @@ -137,8 +138,8 @@ export const classHasCycle = ( return true; } const properties = traverseNonRequiredProperties - ? _class.getAllProperties() - : _class.getAllProperties().filter((p) => p.multiplicity.lowerBound); + ? getAllClassProperties(_class) + : getAllClassProperties(_class).filter((p) => p.multiplicity.lowerBound); const complexProperties = properties .map((property) => property.genericType.value.rawType) .filter((c) => getClassPropertyType(c) === CLASS_PROPERTY_TYPE.CLASS); diff --git a/packages/legend-studio/src/stores/sidebar-state/testable/GlobalTestRunnerState.ts b/packages/legend-studio/src/stores/sidebar-state/testable/GlobalTestRunnerState.ts index 7cb1b3935d5..a23024bf4ce 100644 --- a/packages/legend-studio/src/stores/sidebar-state/testable/GlobalTestRunnerState.ts +++ b/packages/legend-studio/src/stores/sidebar-state/testable/GlobalTestRunnerState.ts @@ -31,7 +31,7 @@ import { AssertPass, AssertFail, PackageableElement, - getNullableIdFromTestable, + getNullableIDFromTestable, } from '@finos/legend-graph'; import { type GeneratorFn, @@ -70,7 +70,7 @@ export const getTestableMetadata = ( return { testable: testable, id: - getNullableIdFromTestable( + getNullableIDFromTestable( testable, editorStore.graphManagerState.graph, editorStore.graphManagerState.pluginManager.getPureGraphManagerPlugins(), @@ -411,9 +411,8 @@ export class TestableState { } const testResults = (yield this.editorStore.graphManagerState.graphManager.runTests( - this.editorStore.graphManagerState.graph, - this.editorStore.graphManagerState.pluginManager.getPureGraphManagerPlugins(), [input], + this.editorStore.graphManagerState.graph, )) as TestResult[]; this.globalTestRunnerState.handleResults(testResults); this.isRunningTests.complete(); @@ -537,9 +536,8 @@ export class GlobalTestRunnerState { } const testResults = (yield this.editorStore.graphManagerState.graphManager.runTests( - this.editorStore.graphManagerState.graph, - this.editorStore.graphManagerState.pluginManager.getPureGraphManagerPlugins(), inputs, + this.editorStore.graphManagerState.graph, )) as TestResult[]; this.handleResults(testResults); this.isRunningTests.complete(); diff --git a/scripts/github-bot/package.json b/scripts/github-bot/package.json index e3695879053..9866727fcae 100644 --- a/scripts/github-bot/package.json +++ b/scripts/github-bot/package.json @@ -14,8 +14,8 @@ "lint:js": "echo \"Skipped - already done as part of linting ./scripts\"" }, "dependencies": { - "@actions/core": "1.8.0", - "@actions/github": "5.0.1", + "@actions/core": "1.8.1", + "@actions/github": "5.0.2", "chalk": "5.0.1" } } diff --git a/yarn.lock b/yarn.lock index a97b842fda7..6f965ac44d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,33 +5,31 @@ __metadata: version: 6 cacheKey: 8 -"@actions/core@npm:1.8.0": - version: 1.8.0 - resolution: "@actions/core@npm:1.8.0" +"@actions/core@npm:1.8.1": + version: 1.8.1 + resolution: "@actions/core@npm:1.8.1" dependencies: - "@actions/http-client": ^1.0.11 - checksum: 0634770fce3fdf56fd76338731921fde67dcea54cba7e5be2398d62445ada2ee8afca6694da1c6f72d9b4d257cbf3ed0dacbd58753adac712e06249f57156cf3 + "@actions/http-client": ^2.0.0 + checksum: 9a3758528e32a951d457cf29494125360251a3631bc63af9465895ab5749a55b85db043226c39c260b8d931c16a237156051e40a7351d484ab2f7249f82fa3bf languageName: node linkType: hard -"@actions/github@npm:5.0.1": - version: 5.0.1 - resolution: "@actions/github@npm:5.0.1" +"@actions/github@npm:5.0.2": + version: 5.0.2 + resolution: "@actions/github@npm:5.0.2" dependencies: - "@actions/http-client": ^1.0.11 + "@actions/http-client": ^2.0.0 "@octokit/core": ^3.6.0 "@octokit/plugin-paginate-rest": ^2.17.0 "@octokit/plugin-rest-endpoint-methods": ^5.13.0 - checksum: 4c8541cbe8332a616a405c84a67566c2e0ef07f401967ab72f8e3608e68bbc73f94bff1b002d28147a58f812e9546b475f58629514532882f59200073b80bd0b + checksum: fb6c4cda9e55d10533ad091b0d001c13083057c127fcc7d6c287c0ae35d7a5f78eecd829c57a1224880d109a943d4a788c019215bde8ff4d811b36c5a71b72f9 languageName: node linkType: hard -"@actions/http-client@npm:^1.0.11": - version: 1.0.11 - resolution: "@actions/http-client@npm:1.0.11" - dependencies: - tunnel: 0.0.6 - checksum: 2c72834ec36a121ae95d2cb61fd28234eae2ab265a2aefe857a9eeb788ea77b284ad727ecd3c67fefd1920d5f2800b6c1ba6916b39d44f81f293b4b0020d367c +"@actions/http-client@npm:^2.0.0": + version: 2.0.0 + resolution: "@actions/http-client@npm:2.0.0" + checksum: ac0818271563f3608601a4781014a2df98be4324adac43572509846066e64329637c2f4982624de99ff1df4a92911d393f5978ae3a779e26639e031dba593e6f languageName: node linkType: hard @@ -2047,7 +2045,7 @@ __metadata: "@changesets/write": 0.1.8 "@juggle/resize-observer": 3.3.1 "@manypkg/get-packages": 1.1.3 - "@pmmmwh/react-refresh-webpack-plugin": 0.5.5 + "@pmmmwh/react-refresh-webpack-plugin": 0.5.6 autoprefixer: 10.4.7 babel-jest: 28.1.0 babel-loader: 8.2.5 @@ -2359,8 +2357,8 @@ __metadata: version: 0.0.0-use.local resolution: "@finos/legend-internal-github-bot@workspace:scripts/github-bot" dependencies: - "@actions/core": 1.8.0 - "@actions/github": 5.0.1 + "@actions/core": 1.8.1 + "@actions/github": 5.0.2 chalk: 5.0.1 languageName: unknown linkType: soft @@ -2534,7 +2532,7 @@ __metadata: "@types/lodash-es": 4.17.6 "@types/lossless-json": 1.0.1 "@types/object-hash": 2.2.1 - "@types/pako": 1.0.3 + "@types/pako": 2.0.0 "@types/seedrandom": 3.0.2 "@types/uuid": 8.3.4 cross-env: 7.0.3 @@ -2706,7 +2704,7 @@ __metadata: rimraf: 3.0.2 sass: 1.51.0 serializr: 2.0.5 - sql-formatter: 4.0.2 + sql-formatter: 6.1.0 typescript: 4.6.4 peerDependencies: react: ^18.0.0 @@ -3525,9 +3523,9 @@ __metadata: languageName: node linkType: hard -"@pmmmwh/react-refresh-webpack-plugin@npm:0.5.5": - version: 0.5.5 - resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.5" +"@pmmmwh/react-refresh-webpack-plugin@npm:0.5.6": + version: 0.5.6 + resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.6" dependencies: ansi-html-community: ^0.0.8 common-path-prefix: ^3.0.0 @@ -3560,7 +3558,7 @@ __metadata: optional: true webpack-plugin-serve: optional: true - checksum: 9914430fc3c5bb6a907cc94faaf6232ee7fdcc8b631a33d3541ae1273f46cdd719eca87932755abf8433c9297666484ed6707c568a131a7a0f55bb442b0e6243 + checksum: 21ab1157c3b8f5d9a1114cc25f14692757506aa47117ffdeeaf484a71ceeba114d9f9a33b705c51b0991f66f573dc30298eb246b939b4e5afb7592add25fb987 languageName: node linkType: hard @@ -3921,13 +3919,13 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:27.5.0": - version: 27.5.0 - resolution: "@types/jest@npm:27.5.0" +"@types/jest@npm:27.5.1": + version: 27.5.1 + resolution: "@types/jest@npm:27.5.1" dependencies: jest-matcher-utils: ^27.0.0 pretty-format: ^27.0.0 - checksum: ca09ac3a17972e18683c57b681a6866c7a56c67f429810ece00425d948da62f207d271becb5cc759da3630f120596ec3c8e0ceb0eecefbe26daffba168b82879 + checksum: be20e39f7aaf17179109c0060d0a0489cec2034d4e2e28a631284c7ecd13c5ae52f62697a33a0e89b03b6cfe54e9d5e8c2bd387ab2bd90d6071d68c63b86d1e3 languageName: node linkType: hard @@ -4032,13 +4030,20 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:17.0.31": +"@types/node@npm:*": version: 17.0.31 resolution: "@types/node@npm:17.0.31" checksum: 704618350f8420d5c47db0f7778398e821b7724369946f5c441a7e6b9343295553936400eb8309f0b07d5e39c240988ab3456b983712ca86265dabc9aee4ad3d languageName: node linkType: hard +"@types/node@npm:17.0.32": + version: 17.0.32 + resolution: "@types/node@npm:17.0.32" + checksum: afb05704b42032566b3da8b2d80a68883cd3b888472d1b8b4dd6c84f8fad371454f083d4e28bd30c10589187296119d92aba255638b30067afe062b5922388a5 + languageName: node + linkType: hard + "@types/node@npm:^12.7.1": version: 12.20.50 resolution: "@types/node@npm:12.20.50" @@ -4060,10 +4065,10 @@ __metadata: languageName: node linkType: hard -"@types/pako@npm:1.0.3": - version: 1.0.3 - resolution: "@types/pako@npm:1.0.3" - checksum: a0fcada8fe162b191b43b68036772bf6344fc047426a7187100f9570ef73c9b953fef2098ade84e709a280790e7e92043ed8f83675dfd042fa605ffc78c7e400 +"@types/pako@npm:2.0.0": + version: 2.0.0 + resolution: "@types/pako@npm:2.0.0" + checksum: 50240a036b5e6acabbf36ac4dca93ec9e619241f0404da8d401cdb427bec3029833324b8a04c4b1ae2ecbc33422fdec31dbf9f43653d9d07cafb82ace78dfccd languageName: node linkType: hard @@ -10125,16 +10130,16 @@ __metadata: version: 0.0.0-use.local resolution: "legend-studio@workspace:." dependencies: - "@actions/core": 1.8.0 - "@actions/github": 5.0.1 + "@actions/core": 1.8.1 + "@actions/github": 5.0.2 "@babel/core": 7.17.10 "@changesets/cli": 2.22.0 "@finos/babel-preset-legend-studio": "workspace:*" "@finos/eslint-plugin-legend-studio": "workspace:*" "@finos/legend-dev-utils": "workspace:*" "@finos/stylelint-config-legend-studio": "workspace:*" - "@types/jest": 27.5.0 - "@types/node": 17.0.31 + "@types/jest": 27.5.1 + "@types/node": 17.0.32 chalk: 5.0.1 cross-env: 7.0.3 envinfo: 7.8.1 @@ -10153,7 +10158,7 @@ __metadata: sort-package-json: 1.57.0 stylelint: 14.8.2 typescript: 4.6.4 - yargs: 17.4.1 + yargs: 17.5.0 languageName: unknown linkType: soft @@ -14504,14 +14509,14 @@ __metadata: languageName: node linkType: hard -"sql-formatter@npm:4.0.2": - version: 4.0.2 - resolution: "sql-formatter@npm:4.0.2" +"sql-formatter@npm:6.1.0": + version: 6.1.0 + resolution: "sql-formatter@npm:6.1.0" dependencies: argparse: ^2.0.1 bin: - sql-formatter: bin/sqlfmt.js - checksum: ce2bd1c507bc3435cfc17184d6404e39d033541ebf0f092087623972a4cf0f72822aec0752060b9f8ed387b63e3a1c46e3d621037dd069fe15f258a83e235940 + sql-formatter: bin/sql-formatter-cli.js + checksum: 6d72e3752acf5fd831fded05c9120c42271b8ef313986f772b128c38c11d09fc7c6c439feb0cd6fdd4d31bbf913328509d4ed1ba9912d2ff55d5ea036d25b4cd languageName: node linkType: hard @@ -15291,13 +15296,6 @@ __metadata: languageName: node linkType: hard -"tunnel@npm:0.0.6": - version: 0.0.6 - resolution: "tunnel@npm:0.0.6" - checksum: c362948df9ad34b649b5585e54ce2838fa583aa3037091aaed66793c65b423a264e5229f0d7e9a95513a795ac2bd4cb72cda7e89a74313f182c1e9ae0b0994fa - languageName: node - linkType: hard - "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -16315,9 +16313,9 @@ __metadata: languageName: node linkType: hard -"yargs@npm:17.4.1, yargs@npm:^17.3.1": - version: 17.4.1 - resolution: "yargs@npm:17.4.1" +"yargs@npm:17.5.0": + version: 17.5.0 + resolution: "yargs@npm:17.5.0" dependencies: cliui: ^7.0.2 escalade: ^3.1.1 @@ -16326,7 +16324,7 @@ __metadata: string-width: ^4.2.3 y18n: ^5.0.5 yargs-parser: ^21.0.0 - checksum: e9012322870d7e4e912a6ae1f63b203e365f911c0cf158be92c36edefddfb3bd38ce17eb9ef0d18858a4777f047c50589ea22dacb44bd949169ba37dc6d34bee + checksum: e2c662a7a63aa125a162cc0d77e38bdfe2a0dd5121a0d485a464499cd7782c5198b57103aed4608df96a017d01cb6a834bc22d4a1f20b92649fa82983d53522b languageName: node linkType: hard @@ -16349,6 +16347,21 @@ __metadata: languageName: node linkType: hard +"yargs@npm:^17.3.1": + version: 17.4.1 + resolution: "yargs@npm:17.4.1" + dependencies: + cliui: ^7.0.2 + escalade: ^3.1.1 + get-caller-file: ^2.0.5 + require-directory: ^2.1.1 + string-width: ^4.2.3 + y18n: ^5.0.5 + yargs-parser: ^21.0.0 + checksum: e9012322870d7e4e912a6ae1f63b203e365f911c0cf158be92c36edefddfb3bd38ce17eb9ef0d18858a4777f047c50589ea22dacb44bd949169ba37dc6d34bee + languageName: node + linkType: hard + "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0"