thingworx-field-work / ThingworxVSCodeProject

Develop thingworx models using a real IDE
MIT License
33 stars 17 forks source link

Invalid DataShape when returning query from DataTable #61

Closed makon closed 11 months ago

makon commented 11 months ago

First at all thank you very much for this great project and I really appreciate the the work you put in it guys.

I am currently struggling with quering a DataTable. When using a DataTable the base class is the DataTable<T extends DataShapeBase>, right? So when using the QueryDataTableEntries it will return a union type of DataTableEntry & T.

QueryDataTableEntries(args?:{maxItems?: NUMBER, query?: QUERY, values?: INFOTABLE<T>, source?: STRING, tags?: TAGS}): INFOTABLE<DataTableEntry & T>;

So what I am trying is to return this Infotable with the generic information but in the validation step it always fails.

getQueryResults( ... ): INFOTABLE<DataTableEntry & MyDataShapeType> 

The error message is:

πŸ›‘ Installation failed for "bm-thingworx-vscode-2.7.73": "Import Failed: Validation Failure: Thing MyQueryThing Had An Invalid DataShape [DataTableEntry & MyDataShapeType] assigned to the result type in service [getQueryResults]"

Am I missing something? It works when I just use INFOTABLE as return type but then I lose the type safety and code completions.

BogdanMihaiciuc commented 11 months ago

Hey,

This fails the validation step because the generic argument for infotables is used directly as the data shape name that will be assigned to the data shape aspect in thingworx. In this case the entire generic argument DataTableEntry & MyDataShapeType is interpreted as a data shape name which is not valid. It works for the base data table definition because it is a supporting type that doesn't get compiled.

While thingworx does have the option to mark a service result as a stream entry or data table entry, this isn't yet supported here because the same infotable type is used everywhere but this special union type only makes sense for service results.

As a workaround for now, you can clone the DataTableEntry data shape in your project with a new name and create separate data shapes with the additional data table entry fields by extending from both the new data table entry data shape as well as your own data shape. Then use the new data shape as the result for services where you would select Data Table Entry as the data shape type in thingworx:

Step 1 - clone the data table entry shape

/**
 * Data Table Entries
 */
 declare class MyDataTableEntry extends DataShapeBase {

    /**
     * Source type
     */
    sourceType: STRING;

    /**
     * Location of last modification
     */
    location: LOCATION;

    /**
     * Source of last modification
     */
    source: STRING;

    /**
     * Internal key value
     */
    key: STRING;

    /**
     * Tags
     */
    tags: TAGS;

    /**
     * Time of last modification
     */
    timestamp: DATETIME;
}

Step 2 - extend the data shapes for use with data table entry results

class MyDataShapeTypeDataTableEntry extends DataShapeBase(MyDataTableEntry, MyDataShapeType) {
}
makon commented 11 months ago

Thanks for the fast reply. This seems to work.

As I am using the DataTable from an imported project I can't use the generated types but have to redeclare them in my project as long as I want to have specific INFOTABLE return types, right? Because otherwise I am running in the following error:

DataShapes can only extend other dataShapes declared in the project, and not external ones

There is no other solution, right?

BogdanMihaiciuc commented 11 months ago

Yes this is the way to work around this.

The reason typing files aren't used for compilation is because they can't fully model everything needed for data shapes (in particular, decorators are not supported in ambient contexts).

makon commented 11 months ago

Got it! Thank you for your help!