dibbo
dibbo
Aarktype
Created by dibbo on 12/18/2024 in #questions
Best way of sharing/compiling types?
Thats cool though, thanks for the reply! A monorepo might make more sense for this setup.. I'll draw up some pros and cons and see where I land haha
7 replies
Aarktype
Created by dibbo on 12/18/2024 in #questions
Best way of sharing/compiling types?
Close enough! 😄
7 replies
Aarktype
Created by dibbo on 11/3/2024 in #questions
Generic middleware validator
Thank you!
10 replies
Aarktype
Created by dibbo on 11/3/2024 in #questions
Generic middleware validator
Hey @ssalbdivad I've updated https://github.com/bgribben/type-issue to use my own recursive type for the middleware
type Chain<T = APIGatewayProxyEventV2> = {
(event: APIGatewayProxyEventV2): Promise<void>;
use: <K extends Middleware>(
middleware: K
) => Chain<
keyof ReturnType<K["before"]> extends keyof T
? Omit<T, keyof ReturnType<K["before"]>> & ReturnType<K["before"]>
: T & ReturnType<K["before"]>
>;
handler: (fn: HandlerFn<T>) => void;
};
type Chain<T = APIGatewayProxyEventV2> = {
(event: APIGatewayProxyEventV2): Promise<void>;
use: <K extends Middleware>(
middleware: K
) => Chain<
keyof ReturnType<K["before"]> extends keyof T
? Omit<T, keyof ReturnType<K["before"]>> & ReturnType<K["before"]>
: T & ReturnType<K["before"]>
>;
handler: (fn: HandlerFn<T>) => void;
};
and I'm still seeing the issue with the following usage
const validate = <T extends Type>(
validator: T
): Middleware<{ body: T["infer"] }> => ({
before: (event) => {
if (!event.body) return { statusCode: 400 };
const result = validator(event.body);
if (result instanceof type.errors) {
throw new Error(result.summary);
}
event.body = result;
return event;
},
after: () => {},
});

const handleCreatePet = chain()
.use(validate(createPetPayload))
.handler(async ({ body }) => {});

const handleUpdatePet = chain()
.use(validate(updatePetPayload))
.handler(async ({ body }) => {});
const validate = <T extends Type>(
validator: T
): Middleware<{ body: T["infer"] }> => ({
before: (event) => {
if (!event.body) return { statusCode: 400 };
const result = validator(event.body);
if (result instanceof type.errors) {
throw new Error(result.summary);
}
event.body = result;
return event;
},
after: () => {},
});

const handleCreatePet = chain()
.use(validate(createPetPayload))
.handler(async ({ body }) => {});

const handleUpdatePet = chain()
.use(validate(updatePetPayload))
.handler(async ({ body }) => {});
The strange thing is if I move handleUpdatePet above handleCreatePet, the error disappears At a glance, would you know why the order of the calls impacts the output of TS? Apologies for the direct ping, but if you get a second to check out the error in the repo, it would be greatly appreciated. Thanks!
10 replies
Aarktype
Created by dibbo on 11/3/2024 in #questions
Generic middleware validator
This might be an issue with the middy library, or at least how I'm using it. One call to use seems to impact the other e.g.
const handleCreatePet = middy()
.use(validateBody(createPetPayload))
.handler(async ({ body }) => {});

const handleUpdatePet = middy()
.use(validateBody(updatePetPayload))
.handler(async ({ body }) => {});
const handleCreatePet = middy()
.use(validateBody(createPetPayload))
.handler(async ({ body }) => {});

const handleUpdatePet = middy()
.use(validateBody(updatePetPayload))
.handler(async ({ body }) => {});
in this instance, commenting out the handleCreatePet gets rid of the Type instantiation is excessively deep and possibly infinite error in handleUpdatePet. I have no idea how they could impact each other, gonna do some digging to see if I'm even using the library correctly 🙃
10 replies
Aarktype
Created by dibbo on 11/3/2024 in #questions
Generic middleware validator
I think that should show the issue, thanks for looking into this
10 replies
Aarktype
Created by dibbo on 11/3/2024 in #questions
Generic middleware validator
10 replies
Aarktype
Created by dibbo on 11/3/2024 in #questions
Generic middleware validator
Sure. I've moved the call outside of the middleware chain i.e.
const test = validateBody(schema);
const test = validateBody(schema);
and I'm still seeing the error so I think we can rule out use/handler interfering with it. Here are the other types
// From @middy/core
declare type MiddlewareFn<
TEvent = any,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> = (request: Request<TEvent, TResult, TErr, TContext, TInternal>) => any

export interface MiddlewareObj<
TEvent = unknown,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> {
before?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
after?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
onError?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
name?: string
}

// My own ValidatedBody type
type ValidatedBody<T> = Omit<APIGatewayProxyEventV2, "body"> & {
body: T;
};
// From @middy/core
declare type MiddlewareFn<
TEvent = any,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> = (request: Request<TEvent, TResult, TErr, TContext, TInternal>) => any

export interface MiddlewareObj<
TEvent = unknown,
TResult = any,
TErr = Error,
TContext extends LambdaContext = LambdaContext,
TInternal extends Record<string, unknown> = {}
> {
before?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
after?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
onError?: MiddlewareFn<TEvent, TResult, TErr, TContext, TInternal>
name?: string
}

// My own ValidatedBody type
type ValidatedBody<T> = Omit<APIGatewayProxyEventV2, "body"> & {
body: T;
};
Here's a CodeSandbox link to the ark schemas and their usage
10 replies
Aarktype
Created by PIat on 9/17/2024 in #questions
Dynamic type based on another value
As always, thank you for the help 🙏
24 replies
Aarktype
Created by PIat on 9/17/2024 in #questions
Dynamic type based on another value
Although thinking about it, I would also like to use it as a Type in the application, so I'm guessing I'll have to do the oring
24 replies
Aarktype
Created by PIat on 9/17/2024 in #questions
Dynamic type based on another value
Runtime (I think - its used to validate incoming request bodies)
24 replies
Aarktype
Created by PIat on 9/17/2024 in #questions
Dynamic type based on another value
const example = type({
status: "'Available'|'Unavailable'|'Reclaimed'|'Needs Reclaimed'",
species: "'Dog'|'Cat'|'Other'",
"dateOfBirth?": "Date", // Should be required when status is Available|Unavailable
"breed?": "string", // Should be required when species is Dog
"crossBreed?": "string", // Optional but only to be supplied when species is Dog
"summary?": "string", // Required when status is Available|Needs Reclaimed
});
const example = type({
status: "'Available'|'Unavailable'|'Reclaimed'|'Needs Reclaimed'",
species: "'Dog'|'Cat'|'Other'",
"dateOfBirth?": "Date", // Should be required when status is Available|Unavailable
"breed?": "string", // Should be required when species is Dog
"crossBreed?": "string", // Optional but only to be supplied when species is Dog
"summary?": "string", // Required when status is Available|Needs Reclaimed
});
24 replies
Aarktype
Created by PIat on 9/17/2024 in #questions
Dynamic type based on another value
Sure, 2 secs
24 replies
Aarktype
Created by PIat on 9/17/2024 in #questions
Dynamic type based on another value
Is there an alternative approach to this available via arktype at all? I have run into a similar scenario but with many possible key/value combinations. Rather than writing a specific type for each scenario and oring them, can I configure a property to be required/optional based on the value(s) of other properties?
24 replies
Aarktype
Created by dibbo on 8/29/2024 in #questions
Optional property with const string array
Oh nice, I didn’t know that was an option. Thank you for the replies
6 replies
Aarktype
Created by dibbo on 8/27/2024 in #questions
Indexed Access Types
Nice, thank you for the help!
9 replies
Aarktype
Created by dibbo on 8/27/2024 in #questions
Indexed Access Types
Thank you! Good question... I've been looking at this for so long I can't remember 😂 Let me give a more detailed example: I'm trying to create a type to be used to validate the payload in a search request. I've landed on this as the implementation
const status = ["Available", "Unavailable", "Sold"] as const;
const size = [
{ label: "Big", value: "100kg" },
{ label: "Small", value: "10kg" },
] as const;

const searchPayload = type({
"page?": "number",
"sort?": "string",
filters: {
"status?": type(["===", ...status]).array(),
"size?": type(["===", ...size.map((s) => s.value)]).array(),
},
});

type SearchPayload = typeof searchPayload.infer;
// Evaluates to the type I want
// type SearchPayload = {
// filters: {
// status?: ("Available" | "Unavailable" | "Sold")[];
// size?: ("100kg" | "10kg")[];
// };
// page?: number;
// sort?: string;
// }
const status = ["Available", "Unavailable", "Sold"] as const;
const size = [
{ label: "Big", value: "100kg" },
{ label: "Small", value: "10kg" },
] as const;

const searchPayload = type({
"page?": "number",
"sort?": "string",
filters: {
"status?": type(["===", ...status]).array(),
"size?": type(["===", ...size.map((s) => s.value)]).array(),
},
});

type SearchPayload = typeof searchPayload.infer;
// Evaluates to the type I want
// type SearchPayload = {
// filters: {
// status?: ("Available" | "Unavailable" | "Sold")[];
// size?: ("100kg" | "10kg")[];
// };
// page?: number;
// sort?: string;
// }
I was wondering if there was a cleaner/preferred way to pick out the value prop from the size array with arktype, rather than creating a new array via the map.
9 replies
Aarktype
Created by dibbo on 8/16/2024 in #questions
Latest "keys:distilled" equivalent?
No problem at all, thank you for the (impressively fast) response! 👍
11 replies