{
  "version": 3,
  "sources": ["../src/store.ts"],
  "sourcesContent": ["import type { Driver } from 'iso-kv'\nimport type { CID } from 'multiformats'\nimport { parse as didParse } from 'iso-did'\nimport { KV } from 'iso-kv'\nimport merge from './merge.js'\nimport { Delegation } from './delegation.js'\nimport { validate } from './policy.js'\nimport type { StoreProofsOptions } from './types.js'\n\nconst POWERLINE = '$pwrl'\n\n/**\n * Store\n */\nexport class Store {\n    driver:Driver\n    kv:KV\n\n    constructor (driver:Driver) {\n        this.driver = driver\n\n        this.kv = new KV({\n            driver,\n        })\n    }\n\n    /**\n     * Set a delegation in the store by CID and index it by cmd and aud\n     */\n    async #set (delegation:Delegation):Promise<void> {\n        const options = {\n            expiration: delegation.envelope.payload.exp,\n        }\n        const cid = delegation.cid.toString()\n\n        // Index by CID\n        await this.kv.set([cid], delegation.toString(), options)\n\n        // Index by subject and audience\n        let sub:string | null = delegation.sub ? delegation.sub : null\n        if (sub === null) {\n            sub = POWERLINE\n        }\n        await this.kv.set([sub, delegation.aud, cid], cid, options)\n    }\n\n    async add (delegations:Delegation[]):Promise<void> {\n        for (const delegation of delegations) {\n            await this.#set(delegation)\n        }\n    }\n\n    /**\n     * Get a delegation by cid\n     */\n    async get (cid:string):Promise<Delegation | undefined> {\n        const str = await (this.kv.get as (key: string[]) => Promise<string | undefined>)([\n            cid,\n        ])\n        if (!str) {\n            return undefined\n        }\n        return await Delegation.fromString(str)\n    }\n\n    /**\n     * Resolve a proof by CID\n     */\n    async resolveProof (cid:CID):Promise<Delegation> {\n        const delegation = await this.get(cid.toString())\n        if (!delegation) {\n            throw new Error(`Delegation not found: ${cid.toString()}`)\n        }\n        return delegation\n    }\n\n    /**\n     * List proofs by sub and aud\n     */\n    async * proofs (options:Omit<StoreProofsOptions, 'args'>):AsyncGenerator<Delegation> {\n        let sub:string | null = options.sub ? options.sub.toString() : null\n        let aud:string | undefined = options.aud ? options.aud.toString() : undefined\n\n        if (!aud && !sub) {\n            throw new Error('No audience or subject provided')\n        }\n        if (!aud && sub) {\n            aud = sub\n        }\n        if (sub === null) {\n            sub = POWERLINE\n        }\n        if (!aud) {\n            throw new Error('No audience provided')\n        }\n\n        for await (const element of this.kv.list({\n            prefix: [sub, aud],\n        })) {\n            const value = await this.get(element.value as string)\n\n            if (value) {\n                yield value\n            }\n        }\n    }\n\n    /**\n     * Resolve a single chain of proofs ending with a root (subject === issuer).\n     * Returns the first such chain found (depth-first).\n     */\n    async chain ({ aud, sub, cmd, args }:StoreProofsOptions):Promise<Delegation[]> {\n    // console.log('\uD83D\uDE80 ~ aud', aud, 'sub', sub, 'cmd', cmd)\n        const parents = parentCmds(cmd)\n\n        const sources = merge(\n            this.proofs({ sub, aud, cmd }),\n            this.proofs({ sub: null, aud, cmd })\n        )\n\n        for await (const proof of sources) {\n            if (!parents.includes(proof.cmd)) continue\n            if (!validate(args, proof.pol)) continue\n\n            // If root, return this proof as the end of the path\n            if (proof.sub === didParse(proof.iss).did) {\n                // console.log('\uD83D\uDE80 ~ found root:', proof.iss, proof.sub, proof.cmd)\n                return [proof]\n            }\n\n            // Otherwise, go deeper and prepend this proof if a path is found\n            // console.log('\uD83D\uDE80 ~ trying deeper:', proof.iss, proof.sub, proof.cmd)\n            const nextPath = await this.chain({\n                aud: didParse(proof.iss).did,\n                sub: proof.sub ? proof.sub : sub,\n                cmd: proof.cmd,\n                args,\n            })\n            if (nextPath?.length) {\n                return [proof, ...nextPath]\n            }\n            // console.log('\uD83D\uDE80 ~ no path found')\n        }\n\n        // No path found\n        return []\n    }\n}\n\n/**\n * Returns all parent commands for a given command string.\n *\n * @example\n * ```ts twoslash\n * import { parentCmds } from 'iso-ucan/store'\n * parentCmds('/foo/bar/baz') // [\"/\", \"/foo\", \"/foo/bar\", \"/foo/bar/baz\"]\n * ```\n */\nfunction parentCmds (cmd:string):string[] {\n    if (!cmd || cmd === '/') return ['/']\n    const parts = cmd.split('/').filter(Boolean)\n    const result = ['/']\n    let current = ''\n    for (const part of parts) {\n        current += `/${part}`\n        result.push(current)\n    }\n    return result\n}\n"],
  "mappings": "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",
  "names": ["merge", "didParse"]
}
