import { type Array, Schema } from "effect"
type EncodedBucketKey<Params extends Array.NonEmptyReadonlyArray<Schema.Any>> = Params extends [
infer Head,
...infer Tail extends Array.NonEmptyReadonlyArray<Schema.Any>
] ? `${Schema.Schema.Encoded<Head> & string}/${EncodedBucketKey<Tail>}`
: Schema.Schema.Encoded<Params[0]> & string
type DecodedBucketKey<Params extends Array.NonEmptyReadonlyArray<Schema.Any>> = {
[K in keyof Params]: Schema.Schema.Type<Params[K]>
}
const BucketKey = <Params extends Array.NonEmptyReadonlyArray<Schema.Any>>(
...params: Params
): Schema.Schema<DecodedBucketKey<Params>, `/${EncodedBucketKey<Params>}`> => {
// @ts-expect-error
const Tuple = Schema.Tuple(...params)
// @ts-expect-error
return Schema.transform(Schema.String, Tuple, {
strict: true,
decode: (item) => item.split("/").slice(1),
encode: (item) => "/" + item.join("/")
})
}
const ListingId = Schema.UUID.pipe(Schema.brand("ListingId"))
const MyBucketKey = BucketKey(Schema.Literal("a"), ListingId)
// const MyBucketKey: Schema.Schema<["a", string & Brand<"ListingId">], `/a/${string}`, never>
import { type Array, Schema } from "effect"
type EncodedBucketKey<Params extends Array.NonEmptyReadonlyArray<Schema.Any>> = Params extends [
infer Head,
...infer Tail extends Array.NonEmptyReadonlyArray<Schema.Any>
] ? `${Schema.Schema.Encoded<Head> & string}/${EncodedBucketKey<Tail>}`
: Schema.Schema.Encoded<Params[0]> & string
type DecodedBucketKey<Params extends Array.NonEmptyReadonlyArray<Schema.Any>> = {
[K in keyof Params]: Schema.Schema.Type<Params[K]>
}
const BucketKey = <Params extends Array.NonEmptyReadonlyArray<Schema.Any>>(
...params: Params
): Schema.Schema<DecodedBucketKey<Params>, `/${EncodedBucketKey<Params>}`> => {
// @ts-expect-error
const Tuple = Schema.Tuple(...params)
// @ts-expect-error
return Schema.transform(Schema.String, Tuple, {
strict: true,
decode: (item) => item.split("/").slice(1),
encode: (item) => "/" + item.join("/")
})
}
const ListingId = Schema.UUID.pipe(Schema.brand("ListingId"))
const MyBucketKey = BucketKey(Schema.Literal("a"), ListingId)
// const MyBucketKey: Schema.Schema<["a", string & Brand<"ListingId">], `/a/${string}`, never>