Skip to content

Commit

Permalink
feat(core): adds better typing for IDS facets
Browse files Browse the repository at this point in the history
  • Loading branch information
HoyosJuan committed Nov 9, 2024
1 parent 196da1a commit 6995f7a
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 58 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/core/Types/src/data-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ export class DataMap<K, V> extends Map<K, V> {
}

/**
* Sets the value for the specified key in the map and triggers the appropriate event (onItemSet or onItemUpdated).
* Sets the value for the specified key in the map.
* If the item is new, then onItemSet is triggered.
* If the item is already in the map, then onItemUpdated is triggered.
*
* @param key - The key of the item to set.
* @param value - The value of the item to set.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/openbim/IDSSpecifications/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class IDSSpecifications extends Component {
ifcVersion,
);

if (identifier) specification.identifier = identifier;
if (identifier) (specification.identifier as any) = identifier;
this.list.set(specification.identifier, specification);
return specification;
}
Expand Down
20 changes: 17 additions & 3 deletions packages/core/src/openbim/IDSSpecifications/src/Specification.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import * as FRAGS from "@thatopen/fragments";
import { Components } from "../../../core/Components";
import { DataSet } from "../../../core/Types";
import { IDSCheckResult, IfcVersion } from "./types";
import { IDSCheckResult, IDSSpecificationData, IfcVersion } from "./types";
import { UUID } from "../../../utils";
import { IDSFacet } from "./facets";
import { IDSSpecifications } from "..";

/**
* Represents a single specification from the Information Delivery Specification (IDS) standard.
*
* @remarks This class provides methods for testing a model against the specification,
* as well as serializing the specification into XML format.
*/
export class IDSSpecification {
export class IDSSpecification implements IDSSpecificationData {
name: string;
ifcVersion = new Set<IfcVersion>();
identifier = UUID.create();
readonly identifier = UUID.create();
description?: string;
instructions?: string;
requirementsDescription?: string;
Expand All @@ -31,6 +32,19 @@ export class IDSSpecification {
}
}

set(data: Partial<IDSSpecificationData>) {
const _data = data as any;
const _this = this as any;
for (const key in data) {
if (key === "identifier") continue;
const value = _data[key];
if (key in this) _this[key] = value;
}
const manager = this.components.get(IDSSpecifications);
manager.list.set(this.identifier, this);
return this;
}

/**
* Tests the model to test against the specification's requirements.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
IDSFacetParameterName,
IDSFacetParameter,
IDSEnumerationParameter,
IDSPatternParameter,
} from "../types";
import { IDSFacetParameterName, IDSFacetParameter } from "../types";

export const getParameterXML = (
name: IDSFacetParameterName,
Expand All @@ -16,14 +11,14 @@ export const getParameterXML = (
}

if (parameter.type === "enumeration") {
const value = parameter.parameter as IDSEnumerationParameter;
const value = parameter.parameter;
parameterXML = `<xs:restriction base="xs:string">
${value.map((v) => `<xs:enumeration value="${v}" />`).join("\r\n")}
</xs:restriction>`;
}

if (parameter.type === "pattern") {
const value = parameter.parameter as IDSPatternParameter;
const value = parameter.parameter;
parameterXML = `<xs:restriction base="xs:string">
<xs:pattern value="${value}" />
</xs:restriction>`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getParameterXML } from "../exporters/parameter";
// https://github.com/buildingSMART/IDS/blob/development/Documentation/UserManual/attribute-facet.md

export class IDSAttribute extends IDSFacet {
facetType = "Attribute" as const;
name: IDSFacetParameter;
value?: IDSFacetParameter;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getParameterXML } from "../exporters/parameter";
// https://github.com/buildingSMART/IDS/blob/development/Documentation/UserManual/classification-facet.md

export class IDSClassification extends IDSFacet {
facetType = "Classification" as const;
system: IDSFacetParameter;
value?: IDSFacetParameter;
uri?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { getParameterXML } from "../exporters/parameter";
// https://github.com/buildingSMART/IDS/blob/development/Documentation/UserManual/entity-facet.md

export class IDSEntity extends IDSFacet {
facetType = "Entity" as const;
name: IDSFacetParameter;
predefinedType?: IDSFacetParameter;

Expand Down
23 changes: 8 additions & 15 deletions packages/core/src/openbim/IDSSpecifications/src/facets/Facet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@ import {
IDSFacetParameter,
IDSCheckResult,
IDSFacetParameterName,
IDSSimpleParameter,
IDSEnumerationParameter,
IDSPatternParameter,
IDSLengthParameter,
IDSBoundsParameter,
IDSCheck,
IDSConditionalCardinaltiy,
IDSSimpleCardinality,
IDSFacetType,
} from "../types";

export abstract class IDSFacet {
abstract facetType: IDSFacetType;

// Used when the facet is a requirement
// On IDSEntity is always required
cardinality: IDSSimpleCardinality | IDSConditionalCardinaltiy = "required";
Expand Down Expand Up @@ -54,24 +52,20 @@ export abstract class IDSFacet {
let pass = false;

if (facetParameter.type === "simple") {
const parameter = facetParameter.parameter as IDSSimpleParameter;
pass = value === parameter;
pass = value === facetParameter.parameter;
}

if (facetParameter.type === "enumeration") {
const parameter = facetParameter.parameter as IDSEnumerationParameter;
pass = parameter.includes(value as never);
pass = facetParameter.parameter.includes(value as never);
}

if (facetParameter.type === "pattern") {
const parameter = facetParameter.parameter as IDSPatternParameter;
const regex = new RegExp(parameter);
const regex = new RegExp(facetParameter.parameter);
pass = regex.test(String(value));
}

if (facetParameter.type === "length") {
const parameter = facetParameter.parameter as IDSLengthParameter;
const { min, length, max } = parameter;
const { min, length, max } = facetParameter.parameter;
if (length !== undefined) {
pass = String(value).length === length;
}
Expand All @@ -84,8 +78,7 @@ export abstract class IDSFacet {
}

if (facetParameter.type === "bounds" && typeof value === "number") {
const { min, minInclusive, max, maxInclusive } =
facetParameter.parameter as IDSBoundsParameter;
const { min, minInclusive, max, maxInclusive } = facetParameter.parameter;

let minPass = true;
let maxPass = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IDSFacet } from "./Facet";
// https://github.com/buildingSMART/IDS/blob/development/Documentation/UserManual/material-facet.md

export class IdsMaterialFacet extends IDSFacet {
facetType = "Material" as const;
value?: IDSFacetParameter;
uri?: string;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { IDSEntity } from "./Entity";
// https://github.com/buildingSMART/IDS/blob/development/Documentation/UserManual/partof-facet.md

export class IDSPartOf extends IDSFacet {
facetType = "PartOf" as const;

private _entityFacet: IDSEntity;

private _entity: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getParameterXML } from "../exporters/parameter";
// https://github.com/buildingSMART/IDS/blob/development/Documentation/UserManual/property-facet.md

export class IDSProperty extends IDSFacet {
facetType = "Property" as const;
propertySet: IDSFacetParameter;
baseName: IDSFacetParameter;
value?: IDSFacetParameter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { IDSFacetParameter } from "../types";

export const getParameterValue = (property: any) => {
if (!property) return undefined;
const result: Partial<IDSFacetParameter> = { type: "simple" };
const result: Partial<IDSFacetParameter> = {};
if ("simpleValue" in property) {
result.type = "simple";
result.parameter = property.simpleValue;
}
if ("restriction" in property) {
Expand Down
83 changes: 54 additions & 29 deletions packages/core/src/openbim/IDSSpecifications/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,62 @@ export type IDSFacetParameterName =
| "Entity"
| "Relation";

export type IDSFacetType =
| "Entity"
| "Attribute"
| "Property"
| "Classification"
| "Material"
| "PartOf";

// required must match
// prohibited mustn't match
// optional passes for matches and nulls
export type IDSSimpleCardinality = "required" | "prohibited";
export type IDSConditionalCardinaltiy = IDSSimpleCardinality | "optional";

export type IDSSimpleParameter = string | number | boolean;
export type IDSEnumerationParameter = string[] | number[] | boolean[];
export type IDSPatternParameter = string;
export type IDSBoundsParameter = {
min?: number;
minInclusive?: boolean;
max?: number;
maxInclusive?: boolean;
};
export type IDSLengthParameter = {
min?: number;
length?: number;
max?: number;
};
export interface IDSSimpleParameter {
type: "simple";
parameter: string | number | boolean;
}

export interface IDSEnumerationParameter {
type: "enumeration";
parameter: string[] | number[] | boolean[];
}

export interface IDSRestrictionParameter {}
export interface IDSPatternParameter {
type: "pattern";
parameter: string;
}

export type IDSFacetParameterType =
| "simple"
| "enumeration"
| "pattern"
| "bounds"
| "length";
export interface IDSBoundsParameter {
type: "bounds";
parameter: {
min?: number;
minInclusive?: boolean;
max?: number;
maxInclusive?: boolean;
};
}

export interface IDSFacetParameter {
type: IDSFacetParameterType;
parameter:
| IDSSimpleParameter
| IDSEnumerationParameter
| IDSPatternParameter
| IDSBoundsParameter
| IDSLengthParameter;
export interface IDSLengthParameter {
type: "length";
parameter: {
min?: number;
length?: number;
max?: number;
};
}

export type IDSRestrictionParameter =
| IDSEnumerationParameter
| IDSPatternParameter
| IDSBoundsParameter
| IDSLengthParameter;

export type IDSFacetParameter = IDSSimpleParameter | IDSRestrictionParameter;

export interface IDSCheck {
parameter: IDSFacetParameterName;
currentValue: string | number | boolean | null;
Expand Down Expand Up @@ -81,3 +97,12 @@ export interface IDSInfo {
purpose?: string;
milestone?: string;
}

export interface IDSSpecificationData {
name: string;
ifcVersion: Set<IfcVersion>;
identifier: string;
description?: string;
instructions?: string;
requirementsDescription?: string;
}

0 comments on commit 6995f7a

Please sign in to comment.