Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix GraphicRepresentation types according to latest Mesh Export API docs #7570

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
8 changes: 4 additions & 4 deletions common/api/frontend-tiles.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,18 @@ export type GraphicRepresentation = {
});

// @beta
export type GraphicRepresentationFormat = "IMDL" | "3DTILES" | string;
export type GraphicRepresentationFormat = "IMODEL" | "3DTiles" | "CESIUM";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danieliborra @arvindsvenkat To clarify, is "3DFT" as an export type still returned by the service? If so I'll add it here


// @beta
export enum GraphicRepresentationStatus {
// (undocumented)
Complete = "Complete",
// (undocumented)
Failed = "Failed",
InProgress = "InProgress",
// (undocumented)
InProgress = "In progress",
Invalid = "Invalid",
// (undocumented)
NotStarted = "Not started"
NotStarted = "NotStarted"
}

// @beta
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/frontend-tiles",
"comment": "Update GraphicRepresentationFormat type and GraphicRepresentationStatus enum to reflect the latest Mesh Export Service docs.",
"type": "none"
}
],
"packageName": "@itwin/frontend-tiles"
}
4 changes: 2 additions & 2 deletions extensions/frontend-tiles/src/FrontendTiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { IModelApp, IModelConnection, SpatialTileTreeReferences, SpatialViewState } from "@itwin/core-frontend";
import { createBatchedSpatialTileTreeReferences } from "./BatchedSpatialTileTreeRefs";
import { queryGraphicRepresentations } from "./GraphicsProvider/GraphicRepresentationProvider";
import { GraphicRepresentationFormat, queryGraphicRepresentations } from "./GraphicsProvider/GraphicRepresentationProvider";
import { AccessToken } from "@itwin/core-bentley";
import { obtainIModelTilesetUrl, ObtainIModelTilesetUrlArgs } from "./GraphicsProvider/GraphicsProvider";

Expand Down Expand Up @@ -92,7 +92,7 @@ export async function* queryMeshExports(args: QueryMeshExportsArgs): AsyncIterab
changeId: args.changesetId,
type: "IMODEL",
},
format: "IMDL",
format: "IMODEL" as GraphicRepresentationFormat,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the cast here necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without the cast the compiler was complaining about the type of format being incorrect, inferred to be string instead of GraphicRepresentationFormat. Explicitly stating the type is wordier but is that preferred? E.g.

const testArgs: {
  accessToken: string;
  sessionId: string;
  dataSource: {
    iTwinId: string;
    id: string;
    changeId?: string;
    type: string;
  };
  format: GraphicRepresentationFormat;
} = {
  accessToken: "this-is-a-fake-access-token",
  sessionId: "testSession",
  dataSource: {
    iTwinId: "iTwinId",
    id: "srcId",
    changeId: undefined,
    type: "srcType",
  },
  format: "IMODEL",
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while wordier, i think its safer to extract the type out for an internal interface to use

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

urlPrefix: args.urlPrefix,
includeIncomplete: args.includeIncomplete,
enableCDN: args.enableCDN,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,17 @@ import { IModelApp, ITWINJS_CORE_VERSION } from "@itwin/core-frontend";
/** The expected format of the Graphic Representation
* @beta
*/
/* eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents */
export type GraphicRepresentationFormat = "IMDL" | "3DTILES" | string;
export type GraphicRepresentationFormat = "IMODEL" | "3DTiles" | "CESIUM";

/** Graphic representations are generated from Data Sources.
* The status of a Graphic Representation indicates the progress of that generation process.
* @beta
*/
// ###TODO this needs to be expanded to include more statuses, and/or "failed" needs to be replaced with "invalid".
export enum GraphicRepresentationStatus {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious why in one place we're using a string literal type and another place an enum

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't completely remember, but my guess is because GraphicRepresentationFormat used to have enum values that were strings different from the constant names, like this:

export enum GraphicRepresentationStatus {
  InProgress = "In progress",
  Complete = "Complete",
  NotStarted = "Not started",
  Failed = "Failed"
}

Why those different strings were necessary to begin with, I'm not sure and it could have just been a poor decision. Since all that is needed are the strings "InProgress", "Complete", "NotStarted", and "Invalid", it could become a type like GraphicRepresentationFormat

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized one reason we did this is the enum is used in a conditional type definition of GraphicRepresentation here:

export type GraphicRepresentation = {
  displayName: string;
  representationId: string;
  status: GraphicRepresentationStatus;
  format: GraphicRepresentationFormat;
  dataSource: DataSource;
  /** The url of the graphic representation
   * @note The url can only be guaranteed to be valid if the status is complete.
   * Therefore, the url is optional if the status is not complete, and required if the status is complete.
   */
} & ({
  status: Omit<GraphicRepresentationStatus, GraphicRepresentationStatus.Complete>;
  url?: string;
} | {
  status: GraphicRepresentationStatus.Complete;
  url: string;
});

Where the url prop is only guaranteed to exist if status = GraphicRepresentationStatus.Complete. This could also be done with a union type though with Exclude<GraphicRepresentationStatus, "Complete">, etc. instead of Omit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aruniverse do you have a preference between enum and string literal type here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally would prefer the string literals, not a huge fan of enums. I think the Exclude utility would be perfect for the discriminated union type

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also fixed this

InProgress = "In progress",
InProgress = "InProgress",
Complete = "Complete",
NotStarted = "Not started",
Failed = "Failed",
NotStarted = "NotStarted",
Invalid = "Invalid",
}

/**
Expand Down Expand Up @@ -138,8 +136,6 @@ export async function* queryGraphicRepresentations(args: QueryGraphicRepresentat
iModelId: string;
changesetId: string;
exportType: string;
geometryOptions: any;
viewDefinitionFilter: any;
};

/* eslint-disable-next-line @typescript-eslint/naming-convention */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { AccessToken, Logger } from "@itwin/core-bentley";
import { IModelApp } from "@itwin/core-frontend";
import { obtainGraphicRepresentationUrl } from "./GraphicRepresentationProvider";
import { GraphicRepresentationFormat, obtainGraphicRepresentationUrl } from "./GraphicRepresentationProvider";
import { loggerCategory } from "../LoggerCategory";

/** Arguments supplied to [[obtainIModelTilesetUrl]].
Expand Down Expand Up @@ -57,7 +57,7 @@ export async function obtainIModelTilesetUrl(args: ObtainIModelTilesetUrlArgs):
changeId: args.changesetId,
type: "IMODEL",
},
format: "IMDL",
format: "IMODEL" as GraphicRepresentationFormat,
urlPrefix: args.urlPrefix,
requireExactVersion: args.requireExactChangeset,
enableCDN: args.enableCDN,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { expect, use } from "chai";
import * as chaiAsPromised from "chai-as-promised";
import * as sinon from "sinon";
import { IModelApp } from "@itwin/core-frontend";
import { createGraphicRepresentationsQueryUrl, obtainGraphicRepresentationUrl, queryGraphicRepresentations, QueryGraphicRepresentationsArgs } from "../../GraphicsProvider/GraphicRepresentationProvider";
import { createGraphicRepresentationsQueryUrl, GraphicRepresentationFormat, obtainGraphicRepresentationUrl, queryGraphicRepresentations, QueryGraphicRepresentationsArgs } from "../../GraphicsProvider/GraphicRepresentationProvider";

use(chaiAsPromised);

Expand Down Expand Up @@ -122,7 +122,7 @@ const testArgs = {
changeId: undefined,
type: "srcType",
},
format: "IMDL",
format: "IMODEL" as GraphicRepresentationFormat,
};

describe("queryGraphicRepresentations", () => {
Expand Down Expand Up @@ -216,7 +216,7 @@ describe("obtainGraphicRepresentationUrl", () => {
changeId: args.versionId,
type: "srcType",
},
format: "IMDL",
format: "IMODEL" as GraphicRepresentationFormat,
requireExactVersion: args.exact,
});

Expand Down
Loading