GHHG10's picture
download
raw
5.12 kB
export * as Credential from "./credential"
import { asc, eq } from "drizzle-orm"
import { Context, Effect, Layer, Schema } from "effect"
import { Database } from "./database/database"
import { IntegrationSchema } from "./integration/schema"
import { NonNegativeInt, withStatics } from "./schema"
import { Identifier } from "./util/identifier"
import { CredentialTable } from "./credential/sql"
export const ID = Schema.String.pipe(
Schema.brand("Credential.ID"),
withStatics((schema) => ({ create: () => schema.make("cred_" + Identifier.ascending()) })),
)
export type ID = typeof ID.Type
export class OAuth extends Schema.Class<OAuth>("Credential.OAuth")({
type: Schema.Literal("oauth"),
methodID: IntegrationSchema.MethodID,
refresh: Schema.String,
access: Schema.String,
expires: NonNegativeInt,
metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)),
}) {}
export class Key extends Schema.Class<Key>("Credential.Key")({
type: Schema.Literal("key"),
key: Schema.String,
metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)),
}) {}
export const Info = Schema.Union([OAuth, Key])
.pipe(Schema.toTaggedUnion("type"))
.annotate({ identifier: "Credential.Info" })
export type Info = Schema.Schema.Type<typeof Info>
export class Stored extends Schema.Class<Stored>("Credential.Stored")({
id: ID,
integrationID: IntegrationSchema.ID,
label: Schema.String,
value: Info,
}) {}
export interface Interface {
/** Returns every stored credential. */
readonly all: () => Effect.Effect<Stored[]>
/** Returns stored credentials belonging to one integration. */
readonly list: (integrationID: IntegrationSchema.ID) => Effect.Effect<Stored[]>
/** Replaces any credential for an integration and returns the new record. */
readonly create: (input: {
readonly integrationID: IntegrationSchema.ID
readonly value: Info
readonly label?: string
}) => Effect.Effect<Stored>
/** Updates the label or secret value of a stored credential. */
readonly update: (id: ID, updates: Partial<Pick<Stored, "label" | "value">>) => Effect.Effect<void>
/** Removes a stored credential. */
readonly remove: (id: ID) => Effect.Effect<void>
}
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Credential") {}
export const layer = Layer.effect(
Service,
Effect.gen(function* () {
const { db } = yield* Database.Service
const decode = Schema.decodeUnknownSync(Info)
const stored = (row: typeof CredentialTable.$inferSelect) => {
if (!row.integration_id) return
return new Stored({
id: row.id,
integrationID: row.integration_id,
label: row.label,
value: decode(row.value),
})
}
return Service.of({
all: Effect.fn("Credential.all")(function* () {
return (yield* db
.select()
.from(CredentialTable)
.orderBy(asc(CredentialTable.time_created))
.all()
.pipe(Effect.orDie)).flatMap((row) => {
const credential = stored(row)
return credential ? [credential] : []
})
}),
list: Effect.fn("Credential.list")(function* (integrationID) {
return (yield* db
.select()
.from(CredentialTable)
.where(eq(CredentialTable.integration_id, integrationID))
.orderBy(asc(CredentialTable.time_created))
.all()
.pipe(Effect.orDie)).flatMap((row) => {
const credential = stored(row)
return credential ? [credential] : []
})
}),
create: Effect.fn("Credential.create")(function* (input) {
const credential = new Stored({
id: ID.create(),
integrationID: input.integrationID,
label: input.label ?? "default",
value: input.value,
})
yield* db
.transaction((tx) =>
Effect.gen(function* () {
yield* tx
.delete(CredentialTable)
.where(eq(CredentialTable.integration_id, credential.integrationID))
.run()
yield* tx
.insert(CredentialTable)
.values({
id: credential.id,
integration_id: credential.integrationID,
label: credential.label,
value: credential.value,
})
.run()
}),
)
.pipe(Effect.orDie)
return credential
}),
update: Effect.fn("Credential.update")(function* (id, updates) {
if (!updates.label && !updates.value) return
yield* db
.update(CredentialTable)
.set({ label: updates.label, value: updates.value })
.where(eq(CredentialTable.id, id))
.run()
.pipe(Effect.orDie)
}),
remove: Effect.fn("Credential.remove")(function* (id) {
yield* db.delete(CredentialTable).where(eq(CredentialTable.id, id)).run().pipe(Effect.orDie)
}),
})
}),
)
export const defaultLayer = layer.pipe(Layer.provide(Database.defaultLayer))

Xet Storage Details

Size:
5.12 kB
·
Xet hash:
09855441356829d433242fe34807397b73567f8bb1f81e678ff0bedb63f824bf

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.