{"version":3,"file":"index.cjs","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import { stringify, type ParsedUrlQueryInput } from \"node:querystring\";\nimport {\n    Methods,\n    type IHeader,\n    type Options,\n    type Output,\n    type Post,\n    type Update,\n    type Result,\n    type ResultOutput,\n} from \"./interfaces.js\";\n\nconst defaultOptions = {\n    baseUrl: \"https://api.paste.gg\",\n    mainUrl: \"https://paste.gg\",\n    version: 1,\n} satisfies Options;\n\n/**\n * The main class for interacting with the Paste.gg API\n */\nexport default class PasteGG {\n    readonly #auth: string | undefined;\n    readonly #url: string;\n    readonly options: Options;\n    readonly version: string;\n\n    /**\n     * Create a new instance of PasteGG\n     * @param {string} auth Optional auth key\n     * @param {Options} options Options for the paste server\n     * @class PasteGG\n     * @public\n     * @example\n     * // If you want to be anonymous\n     * const pasteGG = new PasteGG()\n     *\n     * // If you want to use an api key\n     * const pasteGG = new PasteGG(\"apiKeyHere\")\n     */\n    constructor(auth?: string, options: Options = defaultOptions) {\n        /**\n         * The auth key\n         * @type {string}\n         * @private\n         * @readonly\n         */\n        this.#auth = auth;\n        /**\n         * The options for the paste server\n         * @type {Options}\n         * @public\n         * @readonly\n         */\n        this.options = Object.assign<Options, Options>(defaultOptions, options);\n        /**\n         * The version of the API wrapper\n         * @type {string}\n         * @public\n         * @readonly\n         */\n        this.version = \"v[VI]{{inject}}[/VI]\";\n        /**\n         * The full URL for the API\n         * @type {string}\n         * @private\n         * @readonly\n         */\n        this.#url = `${this.options.baseUrl}/v${this.options.version}`;\n    }\n\n    /**\n     * Make a request to the API.\n     * @param {keyof typeof Methods} method\n     * @param {string} path\n     * @param {object} body\n     * @param {string} key\n     * @returns {Promise<Output<T>>}\n     * @private\n     */\n    private async _request<T = Result>(\n        method: keyof typeof Methods,\n        path: string,\n        body?: unknown,\n        key?: string,\n    ): Promise<Output<T>> {\n        const headers: IHeader = {};\n        if (this.#auth) headers.Authorization = `Key ${this.#auth}`;\n        if (key?.length) headers.Authorization = `Key ${key}`;\n        if (method !== \"GET\") headers[\"Content-Type\"] = \"application/json\";\n\n        let urlPath = `${this.#url}${path}`;\n        if (body && method === \"GET\")\n            urlPath += `?${stringify(body as ParsedUrlQueryInput)}`;\n\n        const res = await fetch(urlPath, {\n            method,\n            headers,\n            body: body && method !== \"GET\" ? JSON.stringify(body) : null,\n        });\n\n        try {\n            return (await res.json()) as Output<T>;\n        } catch (error) {\n            if (error instanceof Error) {\n                if (error.message === \"Unexpected end of JSON input\") {\n                    return { status: \"success\", result: null as unknown as T };\n                }\n                return {\n                    status: \"error\",\n                    error: error.name,\n                    message: error.message,\n                };\n            }\n\n            return {\n                status: \"error\",\n                error: String(error),\n                message: \"Something went wrong\",\n            };\n        }\n    }\n\n    /**\n     * Get an existing paste.\n     * @see https://github.com/ascclemens/paste/blob/master/api.md#get-pastesid\n     * @param {string} id The ID of the paste.\n     * @param {boolean} full Includes the contents of files if true.\n     * @returns {Promise<ResultOutput>}\n     * @public\n     * @example\n     * // if you would like to exclude file contents\n     * await pasteGG.get(\"idHere\")\n     *\n     * // If you would like to include file contents\n     * await pasteGG.get(\"idHere\", true)\n     */\n    async get(id: string, full: boolean = false): Promise<Output> {\n        if (!id?.length) {\n            throw new Error(\"A paste ID is required to use PasteGG#get()\");\n        }\n\n        return this._request(Methods.GET, `/pastes/${id}`, { full });\n    }\n\n    /**\n     * Create a new paste.\n     * @see https://github.com/ascclemens/paste/blob/master/api.md#post-pastes\n     * @param {Post} input The information to create the paste with.\n     * @returns {Promise<ResultOutput>}\n     * @public\n     * @example\n     * await pasteGG.post({\n     *   name: \"Paste name\", // Optional\n     *   description: \"Paste description\", // Optional\n     *   expires: \"2020-12-21T02:25:56.428Z\", // Optional (must be a UTC ISO 8601 string)\n     *   files: [{\n     *     name: \"file.txt\", // Optional\n     *     content: {\n     *       format: \"text\",\n     *       value: \"This is where the file content will go\"\n     *     }\n     *   }]\n     * })\n     */\n    async post(input: Post): Promise<ResultOutput> {\n        if (!input) {\n            throw new Error(\n                \"An input object is required to use PasteGG#post()\",\n            );\n        }\n\n        const res = await this._request(Methods.POST, \"/pastes\", input);\n        if (res.status === \"success\")\n            res.result.url = `${this.options.mainUrl}/${res.result.id}`;\n        return res;\n    }\n\n    /**\n     * Deletes an existing paste.\n     * @see https://github.com/ascclemens/paste/blob/master/api.md#delete-pastesid\n     * @param {string} id The ID of the paste to delete.\n     * @param {string} [key] Auth key or deletion key (leave blank if you have set the auth key in the constructor)\n     * @returns {Promise<Output<null>>}\n     * @public\n     * @example\n     * // Delete with deletion key\n     * await pasteGG.delete(\"idHere\", \"deletionKeyHere\")\n     *\n     * // Delete with auth key if not set in constructor\n     * await pasteGG.delete(\"idHere\", \"authKeyHere\")\n     *\n     * // Leave blank if auth key is in the class constructor\n     * await pasteGG.delete(\"idHere\")\n     */\n    async delete(id: string, key?: string): Promise<Output<null>> {\n        if (!this.#auth?.length && !key?.length)\n            throw new Error(\n                \"An auth key or deletion key is needed to use PasteGG#delete()\",\n            );\n\n        return this._request(Methods.DELETE, `/pastes/${id}`, null, key);\n    }\n\n    /**\n     * Update an existing paste.\n     * @see https://github.com/ascclemens/paste/blob/master/api.md#patch-pastesid\n     * @param {string} id The ID for the paste to update.\n     * @param {Update} options The options you wish to update.\n     * @returns {Promise<Output<null>>}\n     * @public\n     * @example\n     * await pasteGG.update(\"idHere\", {\n     *   name: \"new name\", // Optional (if you want to remove the name)\n     *   description: \"new description\"\n     * })\n     */\n    async update(id: string, options: Update): Promise<Output<null>> {\n        if (!this.#auth?.length)\n            throw new Error(\"An auth key is required to use PasteGG#update()\");\n\n        if (!options.name) options.name = null;\n        return this._request(Methods.PATCH, `/pastes/${id}`, options);\n    }\n}\n\n/**\n * The header options\n * @typedef {IHeader} IHeader\n * @property {string} [Content-Type] The request content type\n * @property {string} [Authorization] Authorization for the request\n */\n\n/**\n * @typedef {Options} Options\n * @property {string} [baseUrl=https://api.paste.gg] The base URL of the API\n * @property {string} [mainUrl=https://paste.gg] The URL of the main website\n * @property {number} [version=1] The version of the API\n */\n\n/**\n * @typedef {Result} Result\n * @property {string} id The ID of the created paste\n * @property {string} [name] The name of the created paste\n * @property {string} [url] The URL for the result\n * @property {Author} [author] The author of the paste\n * @property {string} [description] The description of the created paste\n * @property {public | unlisted | private} [visibility=unlisted] The visibility of the created paste\n * @property {string} created_at The date the paste was created\n * @property {string} updated_at The date the paste was last updated\n * @property {string} [expires] The date when the paste expires\n * @property {File[]} [files] The files used in the created paste\n * @property {string} [deletion_key] The deletion key of the created paste\n */\n\n/**\n * @typedef {Output} Output\n * @property {\"success\" | \"error\"} status The output status\n * @property {Result} [result] The result data object\n * @property {string} [error] The error key\n * @property {string} [message] The error message\n */\n\n/**\n * @typedef {Post} Post\n * @property {string} [name] The name of the paste\n * @property {string} [description] The description of the paste (must be less than 25 KiB)\n * @property {public | unlisted | private} [visibility=unlisted] The visibility of the paste\n * @property {string} [expires] The expiration date of the paste (must be a UTC ISO 8601 string)\n * @property {FileOut[]} files Array of files to add to the paste (at least one file)\n */\n\n/**\n * @typedef {Author} Author\n * @property {string} [id] The ID of the author\n * @property {string} [username] The username of the author\n * @property {string} [name] The name of the author\n */\n\n/**\n * @typedef {Update} Update\n * @property {string} [name] The new name of the post\n * @property {string} description The new description of the post\n */\n\n/**\n * @typedef {File} File\n * @property {string} id The ID of the file\n * @property {string} name The name of the file\n * @property {string | null} highlight_language The syntax highlighting language used\n */\n\n/**\n * @typedef {Content} Content\n * @property {text | base64 | gzip | xz} format The format of the file\n * @property {string} [highlight_language] The syntax highlighting language to use\n * @property {string} value The value of the file contents\n */\n\n/**\n * @typedef {FileOut} FileOut\n * @property {string} [name] The name of the file\n * @property {Content} content The content of the file\n */\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,MAAA,iBAAA;CACA,SAAA;CACA,SAAA;CACA,SAAA;CACA;;;;;;AAKA,IAAA,UAAA,MAAA;;;;;;;;;;;;;;CAmBA,YAAA,MAAA,UAAA,gBAAA;iDAlBA;gDACA;;;;;;;AAwBA,sCAAA,KAAA;;;;;;;AAOA,OAAA,UAAA,OAAA,OAAA,gBAAA,QAAA;;;;;;;AAOA,OAAA,UAAA;;;;;;;AAOA,qCAAA,GAAA,KAAA,QAAA,QAAA,IAAA,KAAA,QAAA,UAAA;;;;;;;;;;;CAYA,MAAA,SACA,QACA,MACA,MACA,KACA;EACA,MAAA,UAAA,EAAA;AACA,oCAAA,KAAA,CAAA,SAAA,gBAAA,qCAAA,KAAA;AACA,MAAA,KAAA,OAAA,SAAA,gBAAA,OAAA;AACA,MAAA,WAAA,MAAA,SAAA,kBAAA;EAEA,IAAA,UAAA,gCAAA,KAAA,GAAA;AACA,MAAA,QAAA,WAAA,MACA,YAAA,oCAAA,KAAA;EAEA,MAAA,MAAA,MAAA,MAAA,SAAA;GACA;GACA;GACA,MAAA,QAAA,WAAA,QAAA,KAAA,UAAA,KAAA,GAAA;GACA,CAAA;AAEA,MAAA;AACA,UAAA,MAAA,IAAA,MAAA;WACA,OAAA;AACA,OAAA,iBAAA,OAAA;AACA,QAAA,MAAA,YAAA,+BACA,QAAA;KAAA,QAAA;KAAA,QAAA;KAAA;AAEA,WAAA;KACA,QAAA;KACA,OAAA,MAAA;KACA,SAAA,MAAA;KACA;;AAGA,UAAA;IACA,QAAA;IACA,OAAA,OAAA,MAAA;IACA,SAAA;IACA;;;;;;;;;;;;;;;;;CAkBA,MAAA,IAAA,IAAA,OAAA,OAAA;AACA,MAAA,CAAA,IAAA,OACA,OAAA,IAAA,MAAA,8CAAA;AAGA,SAAA,KAAA,gBAAA,WAAA,MAAA,EAAA,MAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;CAuBA,MAAA,KAAA,OAAA;AACA,MAAA,CAAA,MACA,OAAA,IAAA,MACA,oDACA;EAGA,MAAA,MAAA,MAAA,KAAA,iBAAA,WAAA,MAAA;AACA,MAAA,IAAA,WAAA,UACA,KAAA,OAAA,MAAA,GAAA,KAAA,QAAA,QAAA,GAAA,IAAA,OAAA;AACA,SAAA;;;;;;;;;;;;;;;;;;;CAoBA,MAAA,OAAA,IAAA,KAAA;AACA,MAAA,+BAAA,KAAA,EAAA,UAAA,CAAA,KAAA,OACA,OAAA,IAAA,MACA,gEACA;AAEA,SAAA,KAAA,mBAAA,WAAA,MAAA,MAAA,IAAA;;;;;;;;;;;;;;;CAgBA,MAAA,OAAA,IAAA,SAAA;AACA,MAAA,+BAAA,KAAA,EAAA,OACA,OAAA,IAAA,MAAA,kDAAA;AAEA,MAAA,CAAA,QAAA,KAAA,SAAA,OAAA;AACA,SAAA,KAAA,kBAAA,WAAA,MAAA,QAAA"}