Fix: Shopify tasks and KV get() return types (#770)

* Improve KV get types

* Fix shopify find and all task return types

* Add changeset
This commit is contained in:
nicktrn
2023-12-04 12:37:55 +00:00
committed by GitHub
parent 1f3733b70f
commit de652c1dfb
7 changed files with 71 additions and 19 deletions
+7
View File
@@ -0,0 +1,7 @@
---
"@trigger.dev/airtable": patch
"@trigger.dev/shopify": patch
"@trigger.dev/sdk": patch
---
Fix Shopify task types and KV `get()` return types
+8
View File
@@ -315,6 +315,10 @@ export function createWebhookSource(
delete: async ({ io, ctx }) => {
const webhookId = await io.store.job.get<string>("get-webhook-id", "webhook-id");
if (!webhookId) {
throw new Error("Missing webhook ID for delete operation.");
}
await io.integration.webhooks().delete("delete-webhook", {
baseId: ctx.params?.baseId,
webhookId,
@@ -327,6 +331,10 @@ export function createWebhookSource(
`${registerJobNamespace(ctx.key)}:webhook-secret-base64`
);
if (!secretBase64) {
throw new Error("Missing secret for verification.");
}
return await verifyRequestSignature({
request,
headerName: "x-airtable-content-mac",
+36 -7
View File
@@ -9,8 +9,23 @@ import {
ShopifyInputType,
} from "./types";
type AllReturnType<TResource extends ShopifyRestResources[ResourcesWithStandardMethods]> = Promise<{
data: RecursiveShopifySerializer<Awaited<ReturnType<TResource["all"]>>["data"]>;
type ResourceArrayWithIndexSignature<T extends any[]> = T extends Array<infer U>
? Array<U & { [key: string]: any }>
: never;
type RecursiveSomeNonNullable<T, TSome> = T extends object
? T extends Array<infer U>
? Array<RecursiveSomeNonNullable<U, TSome extends keyof U ? TSome : never>>
: SomeNonNullable<T, TSome extends keyof T ? TSome : never>
: T;
type AllReturnType<
TResource extends ShopifyRestResources[ResourcesWithStandardMethods],
TSerializedData extends Record<any, any>[] = RecursiveShopifySerializer<
Awaited<ReturnType<TResource["all"]>>["data"]
>,
> = Promise<{
data: ResourceArrayWithIndexSignature<RecursiveSomeNonNullable<TSerializedData, "id">>;
pageInfo?: PageInfo;
}>;
@@ -18,13 +33,23 @@ type CountReturnType = Promise<{ count: number }>;
type DeleteReturnType = Promise<void>;
type FindReturnType<
TResource extends ShopifyRestResources[ResourcesWithStandardMethods],
TSerialized extends Record<any, any> = RecursiveShopifySerializer<InstanceType<TResource>>,
> = Promise<
| (SomeNonNullable<TSerialized, "id"> & {
[key: string]: any;
})
| null
>;
type SaveReturnType<
TResource extends ShopifyRestResources[ResourcesWithStandardMethods],
TUpdate extends boolean,
TFromData extends any,
> = Promise<
TUpdate extends true
? SomeNonNullable<RecursiveShopifySerializer<TResource["prototype"], false>, "id">
? SomeNonNullable<RecursiveShopifySerializer<TResource["prototype"]>, "id">
: TFromData
>;
@@ -58,14 +83,18 @@ export class Resource<
/**
* Fetch a single resource by its ID.
*/
async find(key: string, params: Optional<Parameters<TResource["find"]>[0], "session">) {
async find(
key: string,
params: Optional<Parameters<TResource["find"]>[0], "session">
): FindReturnType<TResource> {
return this.runTask(
key,
async (client, task, io) => {
const abc = this.#withSession(params ?? {});
const resource = await client.rest[this.resourceType].find(this.#withSession(params));
const resource = (await client.rest[this.resourceType].find(
this.#withSession(params)
)) as Awaited<ReturnType<TResource["find"]>>;
return serializeShopifyResource(resource);
return JSON.parse(JSON.stringify(resource));
},
{
name: `Find ${this.resourceType}`,
+5 -8
View File
@@ -1,5 +1,4 @@
import {
ObjectNonNullable,
OmitFunctions,
OmitIndexSignature,
OmitValues,
@@ -7,16 +6,14 @@ import {
} from "@trigger.dev/integration-kit";
import { ShopifyRestResources } from "./index";
type OmitNonSerializable<T> = Omit<OmitFunctions<OmitIndexSignature<T>>, "session">;
type OmitNonSerializable<T> = OmitFunctions<OmitIndexSignature<T>>;
export type SerializedShopifyResource<T, TNonNullable extends boolean = true> = Prettify<
TNonNullable extends true ? ObjectNonNullable<OmitNonSerializable<T>> : OmitNonSerializable<T>
>;
export type SerializedShopifyResource<T> = Prettify<Omit<OmitNonSerializable<T>, "session">>;
export type RecursiveShopifySerializer<T, TNonNullable extends boolean = true> = T extends object
export type RecursiveShopifySerializer<T> = T extends object
? T extends Array<infer U>
? Array<RecursiveShopifySerializer<U>>
: SerializedShopifyResource<T, TNonNullable>
: SerializedShopifyResource<T>
: T;
export type ShopifyReturnType<
@@ -42,7 +39,7 @@ export type ShopifyWebhookPayload = {
export type ShopifyInputType = {
[K in keyof OmitIndexSignature<ShopifyRestResources>]: Prettify<
Partial<SerializedShopifyResource<ShopifyResource<K>, false>>
Partial<SerializedShopifyResource<ShopifyResource<K>>>
> & { id?: number };
};
+8
View File
@@ -105,6 +105,10 @@ export function createWebhookEventSource(integration: Shopify) {
delete: async ({ io, ctx }) => {
const webhookId = await io.store.job.get<number>("get-webhook-id", "webhook-id");
if (!webhookId) {
throw new Error("Missing webhook ID for delete operation.");
}
await io.integration.rest.Webhook.delete("delete-webhook", {
id: webhookId,
});
@@ -130,6 +134,10 @@ export function createWebhookEventSource(integration: Shopify) {
`${registerJobNamespace(ctx.key)}:webhook-secret`
);
if (!clientSecret) {
throw new Error("Missing secret for verification.");
}
return await verifyRequestSignature({
request,
headerName: "x-shopify-hmac-sha256",
@@ -74,9 +74,12 @@ export class KeyValueStore {
);
}
async get<T extends Json<T> = any>(cacheKey: string | any[], key: string): Promise<T>;
async get<T extends Json<T> = any>(key: string): Promise<T>;
async get<T extends Json<T> = any>(param1: string | any[], param2?: string): Promise<T> {
async get<T extends Json<T> = any>(cacheKey: string | any[], key: string): Promise<T | undefined>;
async get<T extends Json<T> = any>(key: string): Promise<T | undefined>;
async get<T extends Json<T> = any>(
param1: string | any[],
param2?: string
): Promise<T | undefined> {
const runStore = runLocalStorage.getStore();
if (!runStore) {
@@ -47,7 +47,7 @@ export class KeyValueStoreClient implements AsyncMap {
return result.deleted;
}
async get<T extends Json<T>>(key: string): Promise<T> {
async get<T extends Json<T>>(key: string): Promise<T | undefined> {
const result = await this.queryStore("GET", {
key: this.#namespacedKey(key),
});