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:
@@ -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
|
||||
@@ -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",
|
||||
|
||||
@@ -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}`,
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
|
||||
|
||||
@@ -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),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user