We’re using the generated Typescript SDK and have generally found it to work quite well. The main thing that I’ve found wanting is the inability to wrap the Ontology/FoundryClient types due to the #private
field that gets generated on the Ontology
class:
export declare class Ontology<O extends OntologyDefinition<any>> {
#private;
constructor(client: ClientContext<O>);
get objects(): Objects<O>;
get actions(): Actions<O>;
get queries(): Queries<O>;
get attachments(): Attachments;
}
I’d like to be able to override the objects
/actions
/queries
in order to wrap them with some telemetry, like so:
type WrappedBaseObjectSet<O extends OntologyObject> = Omit<BaseObjectSet<O>, "get" | "select"> & {
get(primaryKey: O["__primaryKey"]): Promise<Result<O, GetObjectError>>;
select<T extends keyof SelectableProperties<O>>(
properties: readonly T[]
): FilteredPropertiesTerminalOperationsWithGet<O, T[]>;
};
type WrappedObjects<O extends Ontology["objects"]> = {
[K in keyof O]: O[K] extends BaseObjectSet<infer T> ? WrappedBaseObjectSet<T> : O[K];
};
function wrapOntologyObjects<O extends Ontology["objects"]>(objects: O): WrappedObjects<O> {
const wrappedObjects = {} as WrappedObjects<O>;
Object.entries(objects).forEach(([key, object]) => {
const k = key as keyof O;
wrappedObjects[k] = wrapBaseObjectSet(object) as WrappedObjects<O>[typeof k];
});
return wrappedObjects;
}
function wrapBaseObjectSet<O extends OntologyObject>(
baseObjectSet: BaseObjectSet<O>
): WrappedBaseObjectSet<O> {
return {
...baseObjectSet,
get: async (primaryKey: O["__primaryKey"]) => {
const start = Date.now();
const result = await baseObjectSet.get(primaryKey);
const duration = (Date.now() - start) / 1000;
ontologySdkApiRequestCounter.inc({
object_or_action: baseObjectSet.apiName,
ontology_method: "get",
});
ontologySdkApiRequestDuration.observe(
{ object_or_action: baseObjectSet.apiName, ontology_method: "get" },
duration
);
if (result.type === "error") {
ontologySdkApiErrorCounter.inc({
object_or_action: baseObjectSet.apiName,
error_type: result.error.errorType,
error_name: result.error.errorName,
ontology_method: "get",
});
}
return result;
},
...
and then have some TelemetryFoundryClient
that implements or extends FoundryClient
generated by the SDK. But because of the #private
field in the generated types, the compiler will not allow creating a new Ontology
object.
Curious if there are:
a) any other approaches to generating Telemetry for the SDK that is generic
b) any thoughts on the Palantir side on changing this to allow more flexibility