@dual-os/github-api 6.0.3 → 6.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +24 -0
- package/README.md +35 -0
- package/Runner.js +342 -576
- package/Runner.js.map +5 -9
- package/bundle-inventory.json +1 -1
- package/dist/auth.d.ts +13 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +5 -3
- package/dist/auth.js.map +1 -1
- package/dist/channel/github-app-client.d.ts +67 -0
- package/dist/channel/github-app-client.d.ts.map +1 -0
- package/dist/channel/github-app-client.js +18 -0
- package/dist/channel/github-app-client.js.map +9 -0
- package/dist/channel/github-app-definition.d.ts +190 -0
- package/dist/channel/github-app-definition.d.ts.map +1 -0
- package/dist/channel/github-app-definition.js +32 -0
- package/dist/channel/github-app-definition.js.map +9 -0
- package/dist/channel/github-app.d.ts +126 -0
- package/dist/channel/github-app.d.ts.map +1 -0
- package/dist/channel/github-app.js +17 -0
- package/dist/channel/github-app.js.map +9 -0
- package/dist/channel/internal/webhook.d.ts +38 -0
- package/dist/channel/internal/webhook.d.ts.map +1 -0
- package/dist/channel/internal/webhook.js +22 -0
- package/dist/channel/internal/webhook.js.map +9 -0
- package/dist/generated/http.js +7 -5
- package/dist/generated/http.js.map +1 -1
- package/dist/generated/operations.d.ts +1154 -1154
- package/dist/generated/operations.d.ts.map +1 -1
- package/dist/generated/operations.js +7 -5
- package/dist/generated/operations.js.map +1 -1
- package/dist/generated/plugin.js +14 -10515
- package/dist/generated/plugin.js.map +3 -4
- package/dist/plugin.d.ts +10 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +33 -0
- package/dist/plugin.js.map +10 -0
- package/dist/triggers.d.ts +26 -2
- package/dist/triggers.d.ts.map +1 -1
- package/dist/triggers.js +8 -6
- package/dist/triggers.js.map +1 -1
- package/dual-plugin.json +1 -1
- package/package.json +1 -1
- package/{plugin-t4j28rxn.js → plugin-1b35jx9g.js} +6 -4
- package/{plugin-t4j28rxn.js.map → plugin-1b35jx9g.js.map} +2 -2
- package/plugin-2qqpmr67.js +108 -0
- package/plugin-2qqpmr67.js.map +10 -0
- package/{plugin-yzj02c6j.js → plugin-3ryytw13.js} +193 -308
- package/{plugin-yzj02c6j.js.map → plugin-3ryytw13.js.map} +5 -6
- package/{plugin-3mpmm6hc.js → plugin-5rkcrntd.js} +4 -4
- package/plugin-7hfrx1dg.js +167 -0
- package/plugin-7hfrx1dg.js.map +10 -0
- package/plugin-e0mt19z7.js +377 -0
- package/plugin-e0mt19z7.js.map +10 -0
- package/{plugin-ahctqzvj.js → plugin-gtd7vh23.js} +4 -4
- package/plugin-p1y3h7d7.js +10516 -0
- package/plugin-p1y3h7d7.js.map +10 -0
- package/plugin-p6f7n836.js +631 -0
- package/plugin-p6f7n836.js.map +12 -0
- package/plugin-r0m0v72b.js +156 -0
- package/plugin-r0m0v72b.js.map +10 -0
- package/{plugin-gajxsj3f.js → plugin-w0va8331.js} +2495 -2288
- package/{plugin-gajxsj3f.js.map → plugin-w0va8331.js.map} +12 -13
- /package/licenses/{@dual-os_sdk@0.8.1 → @dual-os_sdk@0.9.0}/LICENSE +0 -0
- /package/{plugin-3mpmm6hc.js.map → plugin-5rkcrntd.js.map} +0 -0
- /package/{plugin-ahctqzvj.js.map → plugin-gtd7vh23.js.map} +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../node_modules/.bun/effect@4.1.2/node_modules/effect/dist/MutableHashMap.js", "../../../../node_modules/.bun/effect@4.1.2/node_modules/effect/dist/Cache.js", "../bundle-input/dist/channel/github-app-client.js"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import * as Equal from \"./Equal.js\";\nimport { format } from \"./Formatter.js\";\nimport { dual } from \"./Function.js\";\nimport * as Hash from \"./Hash.js\";\nimport { NodeInspectSymbol, toJson } from \"./Inspectable.js\";\nimport * as Option from \"./Option.js\";\nimport { pipeArguments } from \"./Pipeable.js\";\nimport { hasProperty } from \"./Predicate.js\";\nconst TypeId = \"~effect/MutableHashMap\";\n/**\n * Checks whether the specified value is a `MutableHashMap`, `false` otherwise.\n *\n * **When to use**\n *\n * Use to narrow an unknown value before treating it as a mutable hash map.\n *\n * **Details**\n *\n * The check looks for the `MutableHashMap` runtime marker.\n *\n * **Gotchas**\n *\n * The check does not validate the key or value types carried by the map.\n *\n * @see {@link MutableHashMap} for the mutable hash map interface\n *\n * @stability stable\n * @category guards\n * @since 4.0.0\n */\nexport const isMutableHashMap = value => hasProperty(value, TypeId);\nconst MutableHashMapProto = {\n [TypeId]: TypeId,\n [Symbol.iterator]() {\n return this.backing[Symbol.iterator]();\n },\n toString() {\n return `MutableHashMap(${format(Array.from(this))})`;\n },\n toJSON() {\n return {\n _id: \"MutableHashMap\",\n values: toJson(Array.from(this))\n };\n },\n [NodeInspectSymbol]() {\n return this.toJSON();\n },\n pipe() {\n return pipeArguments(this, arguments);\n }\n};\n/**\n * Creates an empty MutableHashMap.\n *\n * **When to use**\n *\n * Use to create a fresh mutable map before adding entries over time.\n *\n * **Details**\n *\n * Each call returns a new empty map instance.\n *\n * **Example** (Creating an empty map)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap } from \"effect\"\n *\n * const map = MutableHashMap.empty<string, number>()\n *\n * // Add some entries\n * MutableHashMap.set(map, \"key1\", 42)\n * MutableHashMap.set(map, \"key2\", 100)\n *\n * MutableHashMap.size(map) // => 2\n * ```\n *\n * @see {@link make} for creating a map from explicit entries\n * @see {@link fromIterable} for creating a map from an iterable of entries\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const empty = () => {\n const self = Object.create(MutableHashMapProto);\n self.backing = new Map();\n self.buckets = new Map();\n return self;\n};\n/**\n * Creates a MutableHashMap from a variable number of key-value pairs.\n *\n * **When to use**\n *\n * Use to create a mutable hash map from explicit entries known at the call site.\n *\n * **Example** (Creating a map from entries)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap, Option } from \"effect\"\n *\n * const map = MutableHashMap.make(\n * [\"key1\", 42],\n * [\"key2\", 100],\n * [\"key3\", 200]\n * )\n *\n * MutableHashMap.get(map, \"key1\") // => Option.some(42)\n * MutableHashMap.size(map) // => 3\n * ```\n *\n * @see {@link empty} for creating an empty map\n * @see {@link fromIterable} for creating a map from an iterable of entries\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const make = (...entries) => fromIterable(entries);\n/**\n * Creates a MutableHashMap from an iterable collection of key-value pairs.\n *\n * **When to use**\n *\n * Use to create a mutable hash map from an existing iterable of entries.\n *\n * **Example** (Creating a map from an iterable)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap, Option } from \"effect\"\n *\n * const entries = [\n * [\"apple\", 1],\n * [\"banana\", 2],\n * [\"cherry\", 3]\n * ] as const\n *\n * const map = MutableHashMap.fromIterable(entries)\n *\n * MutableHashMap.get(map, \"banana\") // => Option.some(2)\n * MutableHashMap.size(map) // => 3\n *\n * // Works with any iterable\n * const fromMap = MutableHashMap.fromIterable(new Map([[\"x\", 10], [\"y\", 20]]))\n * MutableHashMap.get(fromMap, \"x\") // => Option.some(10)\n * ```\n *\n * @see {@link make} for creating a map from explicit entries\n * @see {@link empty} for creating an empty map\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const fromIterable = entries => {\n const self = empty();\n for (const [key, value] of entries) {\n set(self, key, value);\n }\n return self;\n};\n/**\n * Looks up a key in the `MutableHashMap` safely.\n *\n * **When to use**\n *\n * Use to safely read a `MutableHashMap` value for a key as an `Option`.\n *\n * **Details**\n *\n * Returns `Some(value)` when an equal key is present and `None` when the key is\n * absent.\n *\n * **Example** (Getting a value)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap, Option } from \"effect\"\n *\n * const map = MutableHashMap.make([\"key1\", 42], [\"key2\", 100])\n *\n * MutableHashMap.get(map, \"key1\") // => Option.some(42)\n * MutableHashMap.get(map, \"key3\") // => Option.none()\n *\n * // Pipe-able version\n * MutableHashMap.get(\"key1\")(map) // => Option.some(42)\n * ```\n *\n * @see {@link has} for checking only whether a key is present\n * @see {@link set} for inserting or replacing a value by key\n *\n * @stability stable\n * @category getters\n * @since 2.0.0\n */\nexport const get = /*#__PURE__*/dual(2, (self, key) => {\n if (self.backing.has(key)) {\n return Option.some(self.backing.get(key));\n } else if (isSimpleKey(key)) {\n return Option.none();\n }\n const hash = Hash.hash(key);\n const bucket = self.buckets.get(hash);\n if (bucket === undefined) {\n return Option.none();\n }\n return getFromBucket(self, bucket, key);\n});\nconst isSimpleKey = u => typeof u !== \"object\" && typeof u !== \"function\";\n/**\n * Returns an iterable over the keys in the `MutableHashMap`.\n *\n * **When to use**\n *\n * Use to iterate over the keys currently stored in a mutable hash map.\n *\n * **Example** (Reading keys)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap } from \"effect\"\n *\n * const map = MutableHashMap.make(\n * [\"apple\", 1],\n * [\"banana\", 2],\n * [\"cherry\", 3]\n * )\n *\n * Array.from(MutableHashMap.keys(map)) // => [\"apple\", \"banana\", \"cherry\"]\n * ```\n *\n * @see {@link values} for iterating over stored values\n * @see {@link has} for checking one key without iterating\n *\n * @stability stable\n * @category getters\n * @since 3.8.0\n */\nexport const keys = self => self.backing.keys();\n/**\n * Returns an iterable over the values in the `MutableHashMap`.\n *\n * **When to use**\n *\n * Use to iterate over the values currently stored in a mutable hash map.\n *\n * **Example** (Reading values)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap } from \"effect\"\n *\n * const map = MutableHashMap.make(\n * [\"apple\", 1],\n * [\"banana\", 2],\n * [\"cherry\", 3]\n * )\n *\n * const allValues = Array.from(MutableHashMap.values(map)) // => [1, 2, 3]\n *\n * // Useful for calculations\n * allValues.reduce((sum, value) => sum + value, 0) // => 6\n *\n * // Filter values\n * allValues.filter((value) => value > 1) // => [2, 3]\n * ```\n *\n * @see {@link keys} for iterating over stored keys\n *\n * @stability stable\n * @category getters\n * @since 3.8.0\n */\nexport const values = self => self.backing.values();\nconst getFromBucket = (self, bucket, key) => {\n for (let i = 0, len = bucket.length; i < len; i++) {\n if (Equal.equals(key, bucket[i])) {\n const refKey = bucket[i];\n return Option.some(self.backing.get(refKey));\n }\n }\n return Option.none();\n};\n/**\n * Checks whether the MutableHashMap contains the specified key.\n *\n * **When to use**\n *\n * Use to test whether a key is present in a `MutableHashMap` without reading\n * its value.\n *\n * **Example** (Checking for a key)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap } from \"effect\"\n *\n * const map = MutableHashMap.make([\"key1\", 42], [\"key2\", 100])\n *\n * MutableHashMap.has(map, \"key1\") // => true\n * MutableHashMap.has(map, \"key3\") // => false\n *\n * // Pipe-able version\n * MutableHashMap.has(\"key1\")(map) // => true\n * ```\n *\n * @see {@link get} for reading the value as an `Option`\n *\n * @stability stable\n * @category predicates\n * @since 2.0.0\n */\nexport const has = /*#__PURE__*/dual(2, (self, key) => Option.isSome(get(self, key)));\n/**\n * Sets a key-value pair in the MutableHashMap, mutating the map in place.\n * If the key already exists, its value is updated.\n *\n * **When to use**\n *\n * Use to insert a new `MutableHashMap` entry or replace an existing entry in\n * place.\n *\n * **Example** (Setting key-value pairs)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap, Option } from \"effect\"\n *\n * const map = MutableHashMap.empty<string, number>()\n *\n * // Add new entries\n * MutableHashMap.set(map, \"key1\", 42)\n * MutableHashMap.set(map, \"key2\", 100)\n *\n * MutableHashMap.get(map, \"key1\") // => Option.some(42)\n * MutableHashMap.size(map) // => 2\n *\n * // Update existing entry\n * MutableHashMap.set(map, \"key1\", 999)\n * MutableHashMap.get(map, \"key1\") // => Option.some(999)\n *\n * // Pipe-able version\n * MutableHashMap.set(\"key3\", 300)(map)\n * MutableHashMap.size(map) // => 3\n * ```\n *\n * @see {@link modify} for updating an existing value with a function\n * @see {@link modifyAt} for setting or removing based on the current optional value\n * @see {@link remove} for deleting an entry by key\n *\n * @stability stable\n * @category mutations\n * @since 2.0.0\n */\nexport const set = /*#__PURE__*/dual(3, (self, key, value) => {\n if (self.backing.has(key) || isSimpleKey(key)) {\n self.backing.set(key, value);\n return self;\n }\n const hash = Hash.hash(key);\n const bucket = self.buckets.get(hash);\n if (bucket === undefined) {\n self.buckets.set(hash, [key]);\n self.backing.set(key, value);\n return self;\n }\n let refKey = getRefKey(bucket, key);\n if (refKey === undefined) {\n bucket.push(key);\n refKey = key;\n }\n self.backing.set(refKey, value);\n return self;\n});\nconst getRefKey = (bucket, key) => {\n for (let i = 0, len = bucket.length; i < len; i++) {\n if (Equal.equals(key, bucket[i])) {\n return bucket[i];\n }\n }\n};\n/**\n * Updates the value of the specified key within the MutableHashMap if it exists.\n * If the key doesn't exist, the map remains unchanged.\n *\n * **When to use**\n *\n * Use to transform an existing `MutableHashMap` value in place without\n * inserting missing keys.\n *\n * **Example** (Modifying existing values)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap, Option } from \"effect\"\n *\n * const map = MutableHashMap.make([\"count\", 5], [\"total\", 100])\n *\n * // Increment existing value\n * MutableHashMap.modify(map, \"count\", (n) => n + 1)\n * MutableHashMap.get(map, \"count\") // => Option.some(6)\n *\n * // Double existing value\n * MutableHashMap.modify(map, \"total\", (n) => n * 2)\n * MutableHashMap.get(map, \"total\") // => Option.some(200)\n *\n * // Try to modify non-existent key (no effect)\n * MutableHashMap.modify(map, \"missing\", (n) => n + 1)\n * MutableHashMap.has(map, \"missing\") // => false\n *\n * // Pipe-able version\n * MutableHashMap.modify(\"count\", (n: number) => n + 1)(map)\n * MutableHashMap.get(map, \"count\") // => Option.some(7)\n * ```\n *\n * @see {@link set} for inserting or replacing a value directly\n * @see {@link modifyAt} for handling both missing and existing keys\n *\n * @stability stable\n * @category mutations\n * @since 2.0.0\n */\nexport const modify = /*#__PURE__*/dual(3, (self, key, f) => {\n const hasKey = self.backing.has(key);\n if (hasKey || isSimpleKey(key)) {\n if (hasKey) {\n self.backing.set(key, f(self.backing.get(key)));\n }\n return self;\n }\n const hash = Hash.hash(key);\n const bucket = self.buckets.get(hash);\n if (bucket === undefined) {\n return self;\n }\n const refKey = getRefKey(bucket, key);\n if (refKey === undefined) {\n return self;\n }\n self.backing.set(refKey, f(self.backing.get(refKey)));\n return self;\n});\n/**\n * Updates or removes the specified key using a function from the current\n * optional value to the next optional value.\n *\n * **When to use**\n *\n * Use to decide whether to insert, update, or remove a key based on its current\n * optional value.\n *\n * **Example** (Updating or removing a key)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap, Option } from \"effect\"\n *\n * const map = MutableHashMap.make([\"count\", 5])\n *\n * // Update existing key\n * MutableHashMap.modifyAt(\n * map,\n * \"count\",\n * (option) => Option.map(option, (n) => n * 2)\n * )\n * MutableHashMap.get(map, \"count\") // => Option.some(10)\n *\n * // Add new key\n * MutableHashMap.modifyAt(\n * map,\n * \"new\",\n * (option) => Option.isNone(option) ? Option.some(42) : option\n * )\n * MutableHashMap.get(map, \"new\") // => Option.some(42)\n *\n * // Remove key by returning None\n * MutableHashMap.modifyAt(map, \"count\", () => Option.none())\n * MutableHashMap.get(map, \"count\") // => Option.none()\n *\n * // Conditional update\n * MutableHashMap.modifyAt(\n * map,\n * \"new\",\n * (option) => Option.filter(option, (n) => n > 50) // Remove if <= 50\n * )\n * MutableHashMap.get(map, \"new\") // => Option.none()\n * ```\n *\n * @see {@link modify} for updating only when the key already exists\n * @see {@link set} for inserting or replacing directly\n * @see {@link remove} for deleting directly\n *\n * @stability stable\n * @category mutations\n * @since 2.0.0\n */\nexport const modifyAt = /*#__PURE__*/dual(3, (self, key, f) => {\n const current = get(self, key);\n const result = f(current);\n if (Option.isNone(result)) {\n if (Option.isSome(current)) {\n remove(self, key);\n }\n return self;\n }\n set(self, key, result.value);\n return self;\n});\n/**\n * Removes the specified key from the MutableHashMap, mutating the map in place.\n * If the key doesn't exist, the map remains unchanged.\n *\n * **When to use**\n *\n * Use to delete one key from a mutable hash map in place.\n *\n * **Example** (Removing a key)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap } from \"effect\"\n *\n * const map = MutableHashMap.make(\n * [\"key1\", 42],\n * [\"key2\", 100],\n * [\"key3\", 200]\n * )\n *\n * MutableHashMap.size(map) // => 3\n *\n * // Remove existing key\n * MutableHashMap.remove(map, \"key2\")\n * MutableHashMap.size(map) // => 2\n * MutableHashMap.has(map, \"key2\") // => false\n *\n * // Remove non-existent key (no effect)\n * MutableHashMap.remove(map, \"nonexistent\")\n * MutableHashMap.size(map) // => 2\n *\n * // Pipe-able version\n * MutableHashMap.remove(\"key1\")(map)\n * MutableHashMap.size(map) // => 1\n * ```\n *\n * @see {@link clear} for removing all entries\n * @see {@link modifyAt} for conditionally removing based on the current value\n *\n * @stability stable\n * @category mutations\n * @since 2.0.0\n */\nexport const remove = /*#__PURE__*/dual(2, (self, key_) => {\n if (isSimpleKey(key_)) {\n self.backing.delete(key_);\n return self;\n }\n const hash = Hash.hash(key_);\n const bucket = self.buckets.get(hash);\n if (bucket === undefined) {\n return self;\n }\n for (let i = 0, len = bucket.length; i < len; i++) {\n const bkey = bucket[i];\n if (bkey === key_ || Equal.equals(key_, bkey)) {\n self.backing.delete(bkey);\n bucket.splice(i, 1);\n break;\n }\n }\n if (bucket.length === 0) {\n self.buckets.delete(hash);\n }\n return self;\n});\n/**\n * Removes all key-value pairs from the MutableHashMap, mutating the map in place.\n * The map becomes empty after this operation.\n *\n * **When to use**\n *\n * Use to empty a mutable hash map while keeping the same map instance.\n *\n * **Example** (Clearing all entries)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap } from \"effect\"\n *\n * const map = MutableHashMap.make(\n * [\"key1\", 42],\n * [\"key2\", 100],\n * [\"key3\", 200]\n * )\n *\n * MutableHashMap.size(map) // => 3\n *\n * // Clear all entries\n * MutableHashMap.clear(map)\n *\n * MutableHashMap.size(map) // => 0\n * MutableHashMap.has(map, \"key1\") // => false\n *\n * // Can still add new entries after clearing\n * MutableHashMap.set(map, \"new\", 999)\n * Array.from(map) // => [[\"new\", 999]]\n * ```\n *\n * @see {@link remove} for deleting one key\n * @see {@link empty} for creating a fresh empty map\n *\n * @stability stable\n * @category mutations\n * @since 2.0.0\n */\nexport const clear = self => {\n self.backing.clear();\n self.buckets.clear();\n return self;\n};\n/**\n * Returns the number of key-value pairs in the MutableHashMap.\n *\n * **When to use**\n *\n * Use to read how many entries are currently stored in the mutable hash map.\n *\n * **Example** (Checking map size)\n *\n * ```ts import.meta.vitest\n * import { MutableHashMap } from \"effect\"\n *\n * const map = MutableHashMap.empty<string, number>()\n * MutableHashMap.size(map) // => 0\n *\n * MutableHashMap.set(map, \"key1\", 42)\n * MutableHashMap.set(map, \"key2\", 100)\n * MutableHashMap.size(map) // => 2\n *\n * MutableHashMap.remove(map, \"key1\")\n * MutableHashMap.size(map) // => 1\n *\n * MutableHashMap.clear(map)\n * MutableHashMap.size(map) // => 0\n * ```\n *\n * @see {@link isEmpty} for checking whether the map has no entries\n *\n * @stability stable\n * @category getters\n * @since 2.0.0\n */\nexport const size = self => self.backing.size;\n/**\n * Returns `true` when the `MutableHashMap` contains no key-value pairs.\n *\n * **When to use**\n *\n * Use to branch on whether a mutable map currently has any entries.\n *\n * @see {@link size} for reading the exact number of entries\n *\n * @stability stable\n * @category predicates\n * @since 2.0.0\n */\nexport const isEmpty = self => self.backing.size === 0;\n/**\n * Runs a callback for each key-value pair in the `MutableHashMap`.\n *\n * **When to use**\n *\n * Use to run a synchronous side-effecting callback for every key-value pair in\n * an existing mutable map.\n *\n * **Details**\n *\n * Iteration follows the backing map's order. The callback receives the value\n * first and the key second, matching `Map.prototype.forEach`.\n *\n * @see {@link keys} for iterating only keys\n * @see {@link values} for iterating only values\n *\n * @stability stable\n * @category traversing\n * @since 2.0.0\n */\nexport const forEach = /*#__PURE__*/dual(2, (self, f) => {\n self.backing.forEach(f);\n});\n//# sourceMappingURL=MutableHashMap.js.map",
|
|
6
|
+
"/**\n * Caches values loaded by an Effect lookup function.\n *\n * A cache stores successful and failed lookup results, shares an in-progress\n * lookup when multiple callers request the same missing key, and limits entries\n * by capacity and optional time-to-live rules. This module includes helpers for\n * reading, setting, refreshing, invalidating, and inspecting cache contents.\n *\n * @stability stable\n * @since 4.0.0\n */\nimport * as Context from \"./Context.js\";\nimport * as Duration from \"./Duration.js\";\nimport { dual } from \"./Function.js\";\nimport * as core from \"./internal/core.js\";\nimport { PipeInspectableProto } from \"./internal/core.js\";\nimport * as effect from \"./internal/effect.js\";\nimport * as Iterable from \"./Iterable.js\";\nimport * as MutableHashMap from \"./MutableHashMap.js\";\nimport * as Option from \"./Option.js\";\nimport * as Result from \"./Result.js\";\nconst TypeId = \"~effect/Cache\";\n/**\n * Creates a cache with dynamic time-to-live based on the result and key.\n *\n * **When to use**\n *\n * Use when you need different cache entry lifetimes based on the lookup result\n * or key characteristics.\n *\n * **Details**\n *\n * The timeToLive function receives both the exit result and the key, allowing\n * for flexible TTL policies based on success/failure state and key characteristics.\n *\n * **Example** (Configuring dynamic time to live)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect, Exit } from \"effect\"\n *\n * // Cache with TTL based on computed value\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.makeWith(\n * (id: number) => Effect.succeed({ id, active: id % 2 === 0 }),\n * {\n * capacity: 1000,\n * timeToLive(exit) {\n * if (Exit.isSuccess(exit)) {\n * const user = exit.value\n * return user.active ? \"1 hour\" : \"5 minutes\"\n * }\n * return \"30 seconds\"\n * }\n * }\n * )\n *\n * return cache.capacity\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => 1000\n * ```\n *\n * @see {@link make} for a simpler cache constructor with a fixed time-to-live for all entries\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const makeWith = (lookup, options) => effect.contextWith(context => {\n const self = Object.create(Proto);\n self.lookup = key => effect.updateContext(lookup(key), input => Context.merge(context, input));\n self.map = MutableHashMap.make();\n self.capacity = options.capacity;\n self.timeToLive = options.timeToLive ? (exit, key) => Duration.fromInputUnsafe(options.timeToLive(exit, key)) : defaultTimeToLive;\n return effect.succeed(self);\n});\n/**\n * Creates a cache with a fixed time-to-live for all entries.\n *\n * **Details**\n *\n * This is the basic cache constructor where all entries share the same TTL.\n * The lookup function will be called when a key is not found or has expired.\n *\n * **Example** (Creating a basic cache)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * // Basic cache with string keys\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make<string, number>({\n * capacity: 100,\n * lookup: (key) => Effect.succeed(key.length)\n * })\n *\n * const result1 = yield* Cache.get(cache, \"hello\")\n * const result2 = yield* Cache.get(cache, \"world\")\n * return { result1, result2 }\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => { result1: 5, result2: 5 }\n * ```\n *\n * **Example** (Creating a cache with TTL)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * const program = Effect.gen(function*() {\n * const users = new Map([\n * [123, { name: \"Ada\", email: \"ada@example.com\" }],\n * [456, { name: \"Grace\", email: \"grace@example.com\" }]\n * ])\n *\n * const cache = yield* Cache.make<\n * number,\n * { name: string; email: string },\n * string\n * >({\n * capacity: 500,\n * lookup: (userId) =>\n * Effect.suspend(() => {\n * const user = users.get(userId)\n * return user === undefined\n * ? Effect.fail(`User ${userId} not found`)\n * : Effect.succeed(user)\n * }),\n * timeToLive: \"15 minutes\"\n * })\n *\n * const user1 = yield* Cache.get(cache, 123)\n * const user2 = yield* Cache.get(cache, 123)\n * return [user1, user2, user1 === user2] as const\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [{ name: \"Ada\", email: \"ada@example.com\" }, { name: \"Ada\", email: \"ada@example.com\" }, true]\n * ```\n *\n * @stability stable\n * @category constructors\n * @since 2.0.0\n */\nexport const make = options => makeWith(options.lookup, {\n ...options,\n timeToLive: options.timeToLive !== undefined ? () => options.timeToLive : defaultTimeToLive\n});\nconst Proto = {\n ...PipeInspectableProto,\n [TypeId]: TypeId,\n toJSON() {\n return {\n _id: \"Cache\",\n capacity: this.capacity,\n map: this.map\n };\n }\n};\nconst defaultTimeToLive = (_, _key) => Duration.infinity;\n/**\n * Retrieves the value for a key, invoking the lookup function on a cache miss\n * or expired entry.\n *\n * **Details**\n *\n * Concurrent `get` calls for the same missing key share the same pending\n * lookup. The cache stores the lookup `Exit`, so failed lookups are cached and\n * will fail again until the entry expires, is invalidated, or is refreshed.\n *\n * **Example** (Getting cached values)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Cache miss - triggers lookup function\n * const result1 = yield* Cache.get(cache, \"hello\")\n *\n * // Cache hit - returns cached value without lookup\n * const result2 = yield* Cache.get(cache, \"hello\")\n *\n * return { result1, result2 }\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => { result1: 5, result2: 5 }\n * ```\n *\n * **Example** (Handling lookup failures)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect, Exit } from \"effect\"\n *\n * // Error handling when lookup fails\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make<string, number, string>({\n * capacity: 10,\n * lookup: (key: string) =>\n * key === \"error\"\n * ? Effect.fail(\"Lookup failed\")\n * : Effect.succeed(key.length)\n * })\n *\n * // Successful lookup\n * const success = yield* Cache.get(cache, \"hello\")\n *\n * // Failed lookup - returns error\n * const failure = yield* Effect.exit(Cache.get(cache, \"error\"))\n * return [success, failure] as const\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [5, Exit.fail(\"Lookup failed\")]\n * ```\n *\n * **Example** (Sharing concurrent lookups)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * // Concurrent access - multiple gets of same key only invoke lookup once\n * const program = Effect.gen(function*() {\n * let lookupCount = 0\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) =>\n * Effect.sync(() => {\n * lookupCount++\n * return key.length\n * })\n * })\n *\n * // Multiple concurrent gets\n * const results = yield* Effect.all([\n * Cache.get(cache, \"hello\"),\n * Cache.get(cache, \"hello\"),\n * Cache.get(cache, \"hello\")\n * ], { concurrency: \"unbounded\" })\n *\n * return { results, lookupCount }\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => { results: [5, 5, 5], lookupCount: 1 }\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const get = /*#__PURE__*/dual(2, (self, key) => core.withFiber(fiber => {\n const oentry = MutableHashMap.get(self.map, key);\n if (Option.isSome(oentry)) {\n MutableHashMap.remove(self.map, key);\n if (!hasExpired(oentry.value, fiber)) {\n // Move the entry to the end of the map to keep it fresh\n MutableHashMap.set(self.map, key, oentry.value);\n return oentry.value.await(fiber);\n }\n }\n const entry = new EntryImpl(fiber, self.lookup(key));\n entry.onInterrupt = () => removeEntry(self, key, entry);\n let skipCache = false;\n entry.fiber.addObserver(exit => {\n // Release the key once the lookup can no longer be interrupted.\n entry.onInterrupt = undefined;\n if (effect.exitHasInterrupts(exit)) {\n removeEntry(self, key, entry);\n return;\n }\n const ttl = self.timeToLive(exit, key);\n if (Duration.isZero(ttl)) {\n skipCache = true;\n removeEntry(self, key, entry);\n } else if (Duration.isFinite(ttl)) {\n entry.expiresAt = fiber.getRef(effect.ClockRef).currentTimeMillisUnsafe() + Duration.toMillis(ttl);\n }\n });\n const exit = entry.fiber.pollUnsafe();\n if (!skipCache && (exit === undefined || !effect.exitHasInterrupts(exit))) {\n MutableHashMap.set(self.map, key, entry);\n }\n if (Number.isFinite(self.capacity)) {\n checkCapacity(self);\n }\n return entry.await(fiber);\n}));\nclass EntryImpl {\n expiresAt;\n awaiters;\n fiber;\n onInterrupt;\n constructor(parent, valueEffect) {\n this.fiber = effect.forkUnsafe(parent, valueEffect, true, true);\n this.awaiters = 0;\n this.expiresAt = undefined;\n }\n await(fiber) {\n if (fiber === undefined) return core.withFiber(fiber => this.await(fiber));\n const exit = this.fiber.pollUnsafe();\n if (exit) return exit;\n this.awaiters++;\n // Register cleanup in the same evaluation as the increment, before interruption\n // can prevent the returned join effect from starting.\n effect.onExitUnsafe(fiber, () => {\n this.awaiters--;\n if (this.awaiters > 0 || this.fiber.pollUnsafe()) return effect.void;\n // Detach before interrupting so new lookups do not join the abandoned fiber\n // while its finalizers run.\n this.onInterrupt?.();\n return effect.fiberInterrupt(this.fiber);\n });\n return effect.fiberJoin(this.fiber);\n }\n}\nconst removeEntry = (self, key, entry) => {\n const current = MutableHashMap.get(self.map, key);\n if (Option.isSome(current) && current.value === entry) {\n MutableHashMap.remove(self.map, key);\n }\n};\nconst hasExpired = (entry, fiber) => {\n if (entry.expiresAt === undefined) {\n return false;\n }\n return fiber.getRef(effect.ClockRef).currentTimeMillisUnsafe() >= entry.expiresAt;\n};\nconst checkCapacity = self => {\n let diff = MutableHashMap.size(self.map) - self.capacity;\n if (diff <= 0) return;\n // MutableHashMap has insertion order, so we can remove the oldest entries\n for (const [key] of self.map) {\n MutableHashMap.remove(self.map, key);\n diff--;\n if (diff === 0) return;\n }\n};\n/**\n * Reads an existing cache entry without invoking the lookup function.\n *\n * **Details**\n *\n * Returns `Option.none()` when the key is missing or expired, and `Option.some`\n * when a cached lookup has succeeded. If the entry is still pending, waits for\n * it to complete. If the cached or pending lookup fails, this effect fails with\n * the same error.\n *\n * **Example** (Reading cached values without lookup)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect, Option } from \"effect\"\n *\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // No value in cache yet - returns None without lookup\n * const empty = yield* Cache.getOption(cache, \"hello\")\n *\n * // Populate cache using get\n * yield* Cache.get(cache, \"hello\")\n *\n * // Now getOption returns the cached value\n * const cached = yield* Cache.getOption(cache, \"hello\")\n * return [empty, cached] as const\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [Option.none(), Option.some(5)]\n * ```\n *\n * **Example** (Skipping expired entries)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect, Option } from \"effect\"\n * import { TestClock } from \"effect/testing\"\n *\n * // Expired entries return None\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length),\n * timeToLive: \"1 hour\"\n * })\n *\n * // Add value to cache\n * yield* Cache.get(cache, \"hello\")\n *\n * // Value exists before expiration\n * const beforeExpiry = yield* Cache.getOption(cache, \"hello\")\n *\n * // Simulate time passing\n * yield* TestClock.adjust(\"2 hours\")\n *\n * // Value expired - returns None\n * const afterExpiry = yield* Cache.getOption(cache, \"hello\")\n * return [beforeExpiry, afterExpiry] as const\n * })\n *\n * const actual = await Effect.runPromise(Effect.provide(program, TestClock.layer()))\n * actual // => [Option.some(5), Option.none()]\n * ```\n *\n * **Example** (Waiting for pending lookups)\n *\n * ```ts import.meta.vitest\n * import { Cache, Deferred, Effect, Fiber, Option } from \"effect\"\n *\n * // Waits for ongoing computation to complete\n * const program = Effect.gen(function*() {\n * const deferred = yield* Deferred.make<void>()\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (_key: string) => Deferred.await(deferred).pipe(Effect.as(42))\n * })\n *\n * // Start lookup in background\n * const getFiber = yield* Effect.forkChild(Cache.get(cache, \"key\"))\n *\n * // getOption waits for ongoing computation\n * const optionFiber = yield* Effect.forkChild(Cache.getOption(cache, \"key\"))\n *\n * // Complete the computation\n * yield* Deferred.succeed(deferred, void 0)\n *\n * const result = yield* Fiber.join(optionFiber)\n * const value = yield* Fiber.join(getFiber)\n * return [result, value] as const\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [Option.some(42), 42]\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const getOption = /*#__PURE__*/dual(2, (self, key) => core.withFiber(fiber => {\n const entry = getImpl(self, key, fiber);\n return entry ? effect.asSome(entry.await(fiber)) : effect.succeedNone;\n}));\nconst getImpl = (self, key, fiber, isRead = true) => {\n const oentry = MutableHashMap.get(self.map, key);\n if (Option.isNone(oentry)) {\n return undefined;\n } else if (hasExpired(oentry.value, fiber)) {\n MutableHashMap.remove(self.map, key);\n return undefined;\n } else if (isRead) {\n MutableHashMap.remove(self.map, key);\n MutableHashMap.set(self.map, key, oentry.value);\n }\n return oentry.value;\n};\n/**\n * Retrieves the value associated with the specified key from the cache, only if\n * it contains a resolved successful value.\n *\n * **Details**\n *\n * This checks only an existing non-expired entry. It returns `Option.some` when\n * the entry has already resolved successfully, and `Option.none` for missing,\n * expired, failed, or still-pending entries.\n *\n * @see {@link get} for triggering or awaiting the cache lookup\n * @see {@link getOption} for reading an existing entry as an optional effect\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const getSuccess = /*#__PURE__*/dual(2, (self, key) => core.withFiber(fiber => {\n const exit = getImpl(self, key, fiber)?.fiber.pollUnsafe();\n if (exit && effect.exitIsSuccess(exit)) {\n return effect.succeedSome(exit.value);\n }\n return effect.succeedNone;\n}));\n/**\n * Sets the value associated with the specified key in the cache. This will\n * overwrite any existing value for that key, skipping the lookup function.\n *\n * **Example** (Setting values directly)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 100,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Set a value directly without invoking lookup\n * yield* Cache.set(cache, \"hello\", 42)\n * return yield* Cache.get(cache, \"hello\")\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => 42\n * ```\n *\n * **Example** (Overwriting cached values)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * // Overwriting existing cached values\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 100,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // First get populates via lookup\n * const original = yield* Cache.get(cache, \"test\") // 4\n *\n * // Set overwrites the cached value\n * yield* Cache.set(cache, \"test\", 999)\n * const updated = yield* Cache.get(cache, \"test\") // 999\n *\n * return { original, updated }\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => { original: 4, updated: 999 }\n * ```\n *\n * **Example** (Applying TTL to set values)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n * import { TestClock } from \"effect/testing\"\n *\n * // TTL behavior with set operations\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 100,\n * lookup: (key: string) => Effect.succeed(key.length),\n * timeToLive: \"1 hour\"\n * })\n *\n * // Set value with TTL applied\n * yield* Cache.set(cache, \"temporary\", 123)\n * const beforeExpiry = yield* Cache.has(cache, \"temporary\")\n *\n * // Advance time past TTL\n * yield* TestClock.adjust(\"2 hours\")\n * const afterExpiry = yield* Cache.has(cache, \"temporary\")\n * return [beforeExpiry, afterExpiry]\n * })\n *\n * const actual = await Effect.runPromise(Effect.provide(program, TestClock.layer()))\n * actual // => [true, false]\n * ```\n *\n * **Example** (Enforcing capacity when setting values)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * // Capacity enforcement with set operations\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 2,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Fill cache to capacity\n * yield* Cache.set(cache, \"a\", 1)\n * yield* Cache.set(cache, \"b\", 2)\n * const sizeBeforeEviction = yield* Cache.size(cache)\n *\n * // Adding another entry evicts oldest\n * yield* Cache.set(cache, \"c\", 3)\n * const sizeAfterEviction = yield* Cache.size(cache)\n * const hasOldest = yield* Cache.has(cache, \"a\")\n * const hasNewest = yield* Cache.has(cache, \"c\")\n * return [sizeBeforeEviction, sizeAfterEviction, hasOldest, hasNewest]\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [2, 2, false, true]\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const set = /*#__PURE__*/dual(3, (self, key, value) => core.withFiber(fiber => {\n const exit = core.exitSucceed(value);\n const entry = new EntryImpl(fiber, exit);\n const ttl = self.timeToLive(exit, key);\n if (Duration.isZero(ttl)) {\n MutableHashMap.remove(self.map, key);\n return effect.void;\n }\n entry.expiresAt = Duration.isFinite(ttl) ? fiber.getRef(effect.ClockRef).currentTimeMillisUnsafe() + Duration.toMillis(ttl) : undefined;\n MutableHashMap.set(self.map, key, entry);\n checkCapacity(self);\n return effect.void;\n}));\n/**\n * Checks whether the cache contains an entry for the specified key.\n *\n * **Details**\n *\n * This checks for an existing non-expired entry without invoking the cache\n * lookup function. Expired entries are treated as absent.\n *\n * **Example** (Checking for cached keys)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 100,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Check non-existent key\n * const missing = yield* Cache.has(cache, \"missing\")\n *\n * // Add entry and check existence\n * yield* Cache.get(cache, \"hello\")\n * const present = yield* Cache.has(cache, \"hello\")\n * return [missing, present]\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [false, true]\n * ```\n *\n * **Example** (Checking TTL expiration)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n * import { TestClock } from \"effect/testing\"\n *\n * // TTL expiration behavior\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 100,\n * lookup: (key: string) => Effect.succeed(key.length),\n * timeToLive: \"1 hour\"\n * })\n *\n * // Add entry with TTL\n * yield* Cache.get(cache, \"expires\")\n * const initial = yield* Cache.has(cache, \"expires\")\n *\n * // Still valid before expiration\n * yield* TestClock.adjust(\"30 minutes\")\n * const beforeExpiry = yield* Cache.has(cache, \"expires\")\n *\n * // Expired after TTL\n * yield* TestClock.adjust(\"31 minutes\")\n * const afterExpiry = yield* Cache.has(cache, \"expires\")\n * return [initial, beforeExpiry, afterExpiry]\n * })\n *\n * const actual = await Effect.runPromise(Effect.provide(program, TestClock.layer()))\n * actual // => [true, true, false]\n * ```\n *\n * **Example** (Checking multiple keys)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * // Checking multiple keys efficiently\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 100,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Populate some entries\n * yield* Cache.set(cache, \"apple\", 5)\n * yield* Cache.set(cache, \"banana\", 6)\n *\n * // Check multiple keys\n * const keys = [\"apple\", \"banana\", \"cherry\", \"date\"]\n * const results: Array<string> = []\n * for (const key of keys) {\n * const exists = yield* Cache.has(cache, key)\n * results.push(`${key}: ${exists}`)\n * }\n * return results\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [\"apple: true\", \"banana: true\", \"cherry: false\", \"date: false\"]\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const has = /*#__PURE__*/dual(2, (self, key) => core.withFiber(fiber => {\n const oentry = getImpl(self, key, fiber, false);\n return effect.succeed(oentry !== undefined);\n}));\n/**\n * Invalidates the entry associated with the specified key in the cache.\n *\n * **Example** (Invalidating cached entries)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Add a value to the cache\n * yield* Cache.get(cache, \"hello\")\n * const beforeInvalidation = yield* Cache.has(cache, \"hello\")\n *\n * // Invalidate the entry\n * yield* Cache.invalidate(cache, \"hello\")\n * const afterInvalidation = yield* Cache.has(cache, \"hello\")\n *\n * // Invalidating non-existent keys doesn't error\n * yield* Cache.invalidate(cache, \"nonexistent\")\n *\n * // Get after invalidation will invoke lookup again\n * let lookupCount = 0\n * const cache2 = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) =>\n * Effect.sync(() => {\n * lookupCount++\n * return key.length\n * })\n * })\n *\n * yield* Cache.get(cache2, \"test\") // lookupCount = 1\n * yield* Cache.invalidate(cache2, \"test\")\n * yield* Cache.get(cache2, \"test\") // lookupCount = 2 (lookup called again)\n * return { beforeInvalidation, afterInvalidation, lookupCount }\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => { beforeInvalidation: true, afterInvalidation: false, lookupCount: 2 }\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const invalidate = /*#__PURE__*/dual(2, (self, key) => effect.sync(() => {\n MutableHashMap.remove(self.map, key);\n}));\n/**\n * Invalidates the entry associated with the specified key in the cache when the\n * predicate returns true for the cached value.\n *\n * **Example** (Invalidating entries conditionally)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Add values to the cache\n * yield* Cache.get(cache, \"hello\") // value = 5\n * yield* Cache.get(cache, \"hi\") // value = 2\n *\n * // Invalidate when value equals 5\n * const invalidated1 = yield* Cache.invalidateWhen(\n * cache,\n * \"hello\",\n * (value) => value === 5\n * )\n * const hasHello = yield* Cache.has(cache, \"hello\")\n *\n * // Don't invalidate when predicate doesn't match\n * const invalidated2 = yield* Cache.invalidateWhen(\n * cache,\n * \"hi\",\n * (value) => value === 5\n * )\n * const hasHi = yield* Cache.has(cache, \"hi\")\n *\n * // Returns false for non-existent keys\n * const invalidated3 = yield* Cache.invalidateWhen(\n * cache,\n * \"nonexistent\",\n * () => true\n * )\n *\n * // Returns false for failed cached values\n * const cacheWithErrors = yield* Cache.make<string, number, string>({\n * capacity: 10,\n * lookup: (key: string) =>\n * key === \"fail\" ? Effect.fail(\"error\") : Effect.succeed(key.length)\n * })\n *\n * yield* Effect.exit(Cache.get(cacheWithErrors, \"fail\"))\n * const invalidated4 = yield* Cache.invalidateWhen(\n * cacheWithErrors,\n * \"fail\",\n * () => true\n * )\n * return [invalidated1, hasHello, invalidated2, hasHi, invalidated3, invalidated4]\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [true, false, false, true, false, false]\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const invalidateWhen = /*#__PURE__*/dual(3, (self, key, f) => core.withFiber(fiber => {\n const oentry = getImpl(self, key, fiber, false);\n if (oentry === undefined) {\n return effect.succeed(false);\n }\n return oentry.await(fiber).pipe(effect.map(value => {\n if (f(value)) {\n const current = MutableHashMap.get(self.map, key);\n if (Option.isNone(current) || current.value !== oentry) {\n return false;\n }\n MutableHashMap.remove(self.map, key);\n return true;\n }\n return false;\n }), effect.catchCause(() => effect.succeed(false)));\n}));\n/**\n * Forces a refresh of the value associated with the specified key in the cache.\n *\n * **Details**\n *\n * It will always invoke the lookup function to construct a new value,\n * overwriting any existing value for that key.\n *\n * **Example** (Refreshing cached values)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * // Force refresh of existing cached values\n * const program = Effect.gen(function*() {\n * let counter = 0\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.sync(() => `${key}-${++counter}`)\n * })\n *\n * // Initial cache population\n * const value1 = yield* Cache.get(cache, \"user\")\n *\n * // Get from cache (no lookup)\n * const value2 = yield* Cache.get(cache, \"user\")\n *\n * // Force refresh - always calls lookup\n * const refreshed = yield* Cache.refresh(cache, \"user\")\n *\n * // Subsequent gets return refreshed value\n * const value3 = yield* Cache.get(cache, \"user\")\n * return [value1, value2, refreshed, value3, counter]\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [\"user-1\", \"user-1\", \"user-2\", \"user-2\", 2]\n * ```\n *\n * **Example** (Resetting TTL on refresh)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n * import { TestClock } from \"effect/testing\"\n *\n * // Refresh resets TTL (Time To Live)\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length),\n * timeToLive: \"1 hour\"\n * })\n *\n * yield* Cache.get(cache, \"test\")\n * yield* TestClock.adjust(\"45 minutes\")\n *\n * // Entry would normally expire in 15 minutes\n * const beforeRefresh = yield* Cache.has(cache, \"test\")\n *\n * // Refresh resets the TTL to full 1 hour\n * yield* Cache.refresh(cache, \"test\")\n * yield* TestClock.adjust(\"30 minutes\")\n *\n * // Still valid because TTL was reset\n * const afterRefresh = yield* Cache.has(cache, \"test\")\n * return [beforeRefresh, afterRefresh]\n * })\n *\n * const actual = await Effect.runPromise(Effect.provide(program, TestClock.layer()))\n * actual // => [true, true]\n * ```\n *\n * **Example** (Refreshing missing keys)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * // Refresh non-existent keys\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(`value-for-${key}`)\n * })\n *\n * // Refresh non-existent key creates new entry\n * const result = yield* Cache.refresh(cache, \"newKey\")\n *\n * // Verify it's now cached\n * const cached = yield* Cache.has(cache, \"newKey\")\n * return [result, cached]\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [\"value-for-newKey\", true]\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const refresh = /*#__PURE__*/dual(2, (self, key) => core.withFiber(fiber => {\n const entry = new EntryImpl(fiber, self.lookup(key));\n entry.onInterrupt = () => removeEntry(self, key, entry);\n const existing = getImpl(self, key, fiber, false) !== undefined;\n if (!existing) {\n MutableHashMap.set(self.map, key, entry);\n checkCapacity(self);\n }\n entry.fiber.addObserver(exit => {\n // Release the key once the lookup can no longer be interrupted.\n entry.onInterrupt = undefined;\n if (effect.exitHasInterrupts(exit)) {\n removeEntry(self, key, entry);\n return;\n }\n const ttl = self.timeToLive(exit, key);\n if (Duration.isZero(ttl)) {\n if (existing) MutableHashMap.remove(self.map, key);else removeEntry(self, key, entry);\n return effect.void;\n }\n entry.expiresAt = Duration.isFinite(ttl) ? fiber.getRef(effect.ClockRef).currentTimeMillisUnsafe() + Duration.toMillis(ttl) : undefined;\n if (existing) {\n MutableHashMap.set(self.map, key, entry);\n checkCapacity(self);\n }\n });\n return entry.await(fiber);\n}));\n/**\n * Invalidates all entries in the cache.\n *\n * **Example** (Invalidating all entries)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * // Clear all cached entries at once\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Populate cache with multiple entries\n * yield* Cache.get(cache, \"apple\")\n * yield* Cache.get(cache, \"banana\")\n * yield* Cache.get(cache, \"cherry\")\n *\n * const sizeBeforeInvalidation = yield* Cache.size(cache)\n * const hasAppleBeforeInvalidation = yield* Cache.has(cache, \"apple\")\n *\n * // Clear all entries\n * yield* Cache.invalidateAll(cache)\n *\n * // Verify cache is empty\n * const sizeAfterInvalidation = yield* Cache.size(cache)\n * const hasAppleAfterInvalidation = yield* Cache.has(cache, \"apple\")\n * const hasBananaAfterInvalidation = yield* Cache.has(cache, \"banana\")\n * const hasCherryAfterInvalidation = yield* Cache.has(cache, \"cherry\")\n * return [\n * sizeBeforeInvalidation,\n * hasAppleBeforeInvalidation,\n * sizeAfterInvalidation,\n * hasAppleAfterInvalidation,\n * hasBananaAfterInvalidation,\n * hasCherryAfterInvalidation\n * ]\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [3, true, 0, false, false, false]\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const invalidateAll = self => effect.sync(() => {\n MutableHashMap.clear(self.map);\n});\n/**\n * Retrieves the approximate number of entries in the cache.\n *\n * **Details**\n *\n * Note that expired entries are counted until they are accessed and removed.\n * The size reflects the current number of entries stored, not the number\n * of valid entries.\n *\n * **Example** (Reading cache size)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Empty cache has size 0\n * const emptySize = yield* Cache.size(cache)\n *\n * // Add entries and check size\n * yield* Cache.get(cache, \"hello\")\n * yield* Cache.get(cache, \"world\")\n * const sizeAfterAdding = yield* Cache.size(cache)\n *\n * // Size decreases after invalidation\n * yield* Cache.invalidate(cache, \"hello\")\n * const sizeAfterInvalidation = yield* Cache.size(cache)\n * return [emptySize, sizeAfterAdding, sizeAfterInvalidation]\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [0, 2, 1]\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const size = self => effect.sync(() => MutableHashMap.size(self.map));\n/**\n * Retrieves all active keys from the cache, automatically filtering out expired entries.\n *\n * **Example** (Reading active keys)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * // Basic key enumeration\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Add some entries to the cache\n * yield* Cache.get(cache, \"hello\")\n * yield* Cache.get(cache, \"world\")\n * yield* Cache.get(cache, \"cache\")\n *\n * // Retrieve all active keys\n * const keys = yield* Cache.keys(cache)\n * return Array.from(keys).sort()\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [\"cache\", \"hello\", \"world\"]\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const keys = self => core.withFiber(fiber => {\n const now = fiber.getRef(effect.ClockRef).currentTimeMillisUnsafe();\n return effect.succeed(Iterable.filterMap(self.map, ([key, entry]) => {\n if (entry.expiresAt === undefined || entry.expiresAt > now) {\n return Result.succeed(key);\n }\n MutableHashMap.remove(self.map, key);\n return Result.failVoid;\n }));\n});\n/**\n * Retrieves all successfully cached values from the cache, excluding failed\n * lookups and expired entries.\n *\n * **Example** (Reading all cached values)\n *\n * ```ts import.meta.vitest\n * import { Cache, Effect } from \"effect\"\n *\n * const program = Effect.gen(function*() {\n * const cache = yield* Cache.make({\n * capacity: 10,\n * lookup: (key: string) => Effect.succeed(key.length)\n * })\n *\n * // Add some values to the cache\n * yield* Cache.get(cache, \"a\")\n * yield* Cache.get(cache, \"ab\")\n * yield* Cache.get(cache, \"abc\")\n *\n * // Retrieve all cached values\n * const values = yield* Cache.values(cache)\n * return Array.from(values).sort()\n * })\n *\n * const actual = await Effect.runPromise(program)\n * actual // => [1, 2, 3]\n * ```\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const values = self => effect.map(entries(self), Iterable.map(([, value]) => value));\n/**\n * Retrieves all key-value pairs from the cache as an iterable. This function\n * only returns entries with successfully resolved values, filtering out any\n * failed lookups or expired entries.\n *\n * **Gotchas**\n *\n * Expired entries are removed from the cache while `entries` filters them out.\n *\n * @see {@link keys} for retrieving only cached keys\n * @see {@link values} for retrieving only cached values\n *\n * @stability stable\n * @category combinators\n * @since 4.0.0\n */\nexport const entries = self => core.withFiber(fiber => {\n const now = fiber.getRef(effect.ClockRef).currentTimeMillisUnsafe();\n return effect.succeed(Iterable.filterMap(self.map, ([key, entry]) => {\n if (entry.expiresAt === undefined || entry.expiresAt > now) {\n const exit = entry.fiber.pollUnsafe();\n return exit && exit._tag === \"Success\" ? Result.succeed([key, exit.value]) : Result.failVoid;\n }\n MutableHashMap.remove(self.map, key);\n return Result.failVoid;\n }));\n});\n//# sourceMappingURL=Cache.js.map",
|
|
7
|
+
"import { Permission, apiVersion } from \"./github-app-definition.js\";\nimport { NumericId } from \"./internal/webhook.js\";\nimport { Array, Cache, Clock, Context, DateTime, Duration, Effect, Exit, Layer, Match, Number, Option, Result, Schema, String, pipe } from \"effect\";\nimport { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse } from \"effect/http\";\nimport { AgentChannel } from \"@dual-os/sdk\";\nimport { createPrivateKey, sign } from \"node:crypto\";\nimport { Base64, Base64Url } from \"effect/encoding\";\n//#region src/channel/github-app-client.ts\nconst apiBase = \"https://api.github.com\";\nconst requiredEvents = [\n\t\"issues\",\n\t\"issue_comment\",\n\t\"pull_request\",\n\t\"pull_request_review_comment\"\n];\nconst App = Schema.Struct({\n\tid: NumericId,\n\tslug: Schema.NonEmptyString\n});\nconst AppInstallation = Schema.Struct({\n\tapp_id: NumericId,\n\tevents: Schema.Array(Schema.String),\n\tpermissions: Schema.Struct({\n\t\tissues: Schema.optionalKey(Schema.String),\n\t\tpull_requests: Schema.optionalKey(Schema.String)\n\t}),\n\tsuspended_at: Schema.optionalKey(Schema.NullOr(Schema.String))\n});\nconst HookConfig = Schema.Struct({\n\tcontent_type: Schema.optionalKey(Schema.String),\n\turl: Schema.optionalKey(Schema.String)\n});\nconst BotUser = Schema.Struct({\n\tid: NumericId,\n\ttype: Schema.Literal(\"Bot\")\n});\nconst InstallationToken = Schema.Struct({\n\texpires_at: Schema.DateTimeUtcFromString,\n\ttoken: Schema.NonEmptyString\n});\nconst CollaboratorPermission = Schema.Struct({\n\tpermission: Schema.String,\n\trole_name: Schema.String\n});\nconst Author = Schema.NullOr(Schema.Struct({\n\tid: NumericId,\n\tlogin: Schema.NonEmptyString\n}));\nconst Comment = Schema.Struct({\n\tbody: Schema.NullOr(Schema.String),\n\tcreated_at: AgentChannel.Timestamp,\n\tid: NumericId,\n\tuser: Author\n});\nconst IssueRecord = Schema.Struct({\n\tbody: Schema.NullOr(Schema.String),\n\tcomments: Schema.Natural,\n\tcreated_at: AgentChannel.Timestamp,\n\ttitle: Schema.String,\n\tuser: Author\n});\nconst Created = Schema.Struct({ id: NumericId });\nconst CommentOwner = Schema.Struct({\n\tissue_url: Schema.String,\n\tuser: Author\n});\nconst JwtHeader = Schema.fromJsonString(Schema.Struct({\n\talg: Schema.Literal(\"RS256\"),\n\ttyp: Schema.Literal(\"JWT\")\n}));\nconst JwtClaims = Schema.fromJsonString(Schema.Struct({\n\texp: Schema.Int,\n\tiat: Schema.Int,\n\tiss: Schema.String\n}));\nconst encoder = new TextEncoder();\nconst pemWhitespace = /\\s/gu;\nfunction der(tag, bytes) {\n\tif (bytes.length < 128) return Uint8Array.of(tag, bytes.length, ...bytes);\n\tif (bytes.length < 256) return Uint8Array.of(tag, 129, bytes.length, ...bytes);\n\treturn Uint8Array.of(tag, 130, bytes.length >> 8, bytes.length & 255, ...bytes);\n}\nfunction pkcs8(pem) {\n\tconst trimmed = String.trim(pem);\n\tconst pkcs1 = String.startsWith(\"-----BEGIN RSA PRIVATE KEY-----\")(trimmed);\n\tconst label = pipe(Match.value(pkcs1), Match.when(true, () => \"RSA PRIVATE KEY\"), Match.orElse(() => \"PRIVATE KEY\"));\n\tif (!String.startsWith(`-----BEGIN ${label}-----`)(trimmed) || !String.endsWith(`-----END ${label}-----`)(trimmed)) return Option.none();\n\tconst body = pipe(trimmed, String.replace(`-----BEGIN ${label}-----`, \"\"), String.replace(`-----END ${label}-----`, \"\"), String.replaceAll(pemWhitespace, \"\"));\n\treturn pipe(Result.getSuccess(Base64.decode(body)), Option.map((bytes) => {\n\t\tif (!pkcs1) return bytes;\n\t\treturn der(48, Uint8Array.of(...[\n\t\t\t2,\n\t\t\t1,\n\t\t\t0,\n\t\t\t48,\n\t\t\t13,\n\t\t\t6,\n\t\t\t9,\n\t\t\t42,\n\t\t\t134,\n\t\t\t72,\n\t\t\t134,\n\t\t\t247\n\t\t], 13, 1, 1, 1, 5, 0, ...der(4, bytes)));\n\t}));\n}\nfunction uncertain(sending) {\n\tif (sending) return \"unknown_completion\";\n\treturn \"unavailable\";\n}\nfunction failure(response, sending) {\n\tconst limited = response.headers[\"x-ratelimit-remaining\"] === \"0\" || response.headers[\"retry-after\"] !== void 0;\n\tif (response.status === 429 || response.status === 403 && limited) return \"rate_limited\";\n\tif (response.status === 401 || response.status === 403) return \"unauthorized\";\n\tif (response.status >= 500) return uncertain(sending);\n\treturn \"rejected\";\n}\nconst read = Effect.fnUntraced(function* (schema, response, sending = false) {\n\tif (response.status < 200 || response.status >= 300) return yield* AgentChannel.HandlerError.make({ code: failure(response, sending) });\n\treturn yield* pipe(HttpClientResponse.schemaBodyJson(schema)(response), Effect.timeout(\"20 seconds\"), Effect.mapError(() => AgentChannel.HandlerError.make({ code: uncertain(sending) })));\n});\nfunction readFound(schema, response) {\n\tif (response.status === 404) return Effect.succeed(Option.none());\n\treturn Effect.asSome(read(schema, response));\n}\nfunction gone(response) {\n\tif (response.status === 204 || response.status === 404) return Effect.void;\n\treturn Effect.fail(AgentChannel.HandlerError.make({ code: failure(response, false) }));\n}\nfunction repositoryPath(repository) {\n\treturn `/repos/${encodeURIComponent(repository.owner)}/${encodeURIComponent(repository.name)}`;\n}\nfunction issuePath(issue) {\n\treturn `${repositoryPath(issue)}/issues/${issue.number}`;\n}\nfunction commentPath(repository, id) {\n\treturn `${repositoryPath(repository)}/issues/comments/${id}`;\n}\nvar GitHubAppClient = class GitHubAppClient extends Context.Service()(\"@dual-os/github-app/github-app-client/GitHubAppClient\") {\n\tstatic layer = Layer.effect(this, Effect.gen(function* () {\n\t\tconst http = yield* HttpClient.HttpClient;\n\t\tconst github = pipe(http, HttpClient.mapRequest((request) => pipe(request, HttpClientRequest.prependUrl(apiBase), HttpClientRequest.setHeaders({\n\t\t\taccept: \"application/vnd.github+json\",\n\t\t\t\"user-agent\": \"dual-github-app\",\n\t\t\t\"x-github-api-version\": apiVersion\n\t\t}))));\n\t\tconst send = Effect.fn(\"GitHubAppClient.send\")(function* (request, token, sending) {\n\t\t\treturn yield* pipe(github.execute(HttpClientRequest.bearerToken(request, token)), Effect.provideService(FetchHttpClient.RequestInit, { redirect: \"manual\" }), Effect.timeout(\"20 seconds\"), Effect.mapError(() => AgentChannel.HandlerError.make({ code: uncertain(sending) })));\n\t\t});\n\t\tconst appJwt = Effect.fn(\"GitHubAppClient.appJwt\")(function* (auth) {\n\t\t\tconst now = Math.floor((yield* Clock.currentTimeMillis) / 1e3);\n\t\t\tconst unsigned = `${Base64Url.encode(yield* Schema.encodeEffect(JwtHeader)({\n\t\t\t\talg: \"RS256\",\n\t\t\t\ttyp: \"JWT\"\n\t\t\t}))}.${Base64Url.encode(yield* Schema.encodeEffect(JwtClaims)({\n\t\t\t\texp: now + 540,\n\t\t\t\tiat: now - 60,\n\t\t\t\tiss: auth.appId\n\t\t\t}))}`;\n\t\t\tconst key = yield* pipe(pkcs8(auth.privateKey), Effect.fromOption, Effect.mapError(() => AgentChannel.HandlerError.make({ code: \"unauthorized\" })));\n\t\t\tconst signature = yield* pipe(Effect.try(() => sign(\"sha256\", encoder.encode(unsigned), createPrivateKey({\n\t\t\t\tformat: \"der\",\n\t\t\t\tkey: Buffer.from(key),\n\t\t\t\ttype: \"pkcs8\"\n\t\t\t}))), Effect.mapError(() => AgentChannel.HandlerError.make({ code: \"unauthorized\" })));\n\t\t\treturn `${unsigned}.${Base64Url.encode(new Uint8Array(signature))}`;\n\t\t}, Effect.catchTag(\"SchemaError\", () => AgentChannel.HandlerError.make({ code: \"unauthorized\" })));\n\t\tconst appGet = Effect.fn(\"GitHubAppClient.appGet\")(function* (auth, path, schema) {\n\t\t\treturn yield* read(schema, yield* send(HttpClientRequest.get(path), yield* appJwt(auth), false));\n\t\t});\n\t\tconst tokens = yield* Cache.makeWith((installation) => Effect.gen(function* () {\n\t\t\tconst response = yield* send(HttpClientRequest.post(`/app/installations/${installation.installationId}/access_tokens`), yield* appJwt(installation.auth), false);\n\t\t\tconst created = yield* read(InstallationToken, response);\n\t\t\tconst ttl = DateTime.toEpochMillis(created.expires_at) - (yield* Clock.currentTimeMillis) - 6e4;\n\t\t\tif (ttl <= 0) return yield* AgentChannel.HandlerError.make({ code: \"unavailable\" });\n\t\t\treturn {\n\t\t\t\ttoken: created.token,\n\t\t\t\tttl: Number.min(ttl, 354e4)\n\t\t\t};\n\t\t}), {\n\t\t\tcapacity: 1e3,\n\t\t\ttimeToLive: (exit) => {\n\t\t\t\tif (Exit.isSuccess(exit)) return Duration.millis(exit.value.ttl);\n\t\t\t\treturn Duration.zero;\n\t\t\t}\n\t\t});\n\t\tconst call = Effect.fn(\"GitHubAppClient.call\")(function* (installation, request, sending = false) {\n\t\t\tconst minted = yield* Cache.get(tokens, installation);\n\t\t\tconst response = yield* send(request, minted.token, sending);\n\t\t\tif (response.status === 401) yield* Cache.invalidate(tokens, installation);\n\t\t\treturn response;\n\t\t});\n\t\t/** Check the App and its installation, read-only: its permissions, events and bot account. */\n\t\tconst checkInstallation = Effect.fn(\"GitHubAppClient.checkInstallation\")(function* (installation) {\n\t\t\tconst app = yield* appGet(installation.auth, \"/app\", App);\n\t\t\tconst found = yield* appGet(installation.auth, `/app/installations/${installation.installationId}`, AppInstallation);\n\t\t\tif (`${app.id}` !== installation.auth.appId || found.app_id !== app.id) return yield* AgentChannel.HandlerError.make({ code: \"unauthorized\" });\n\t\t\tif (found.suspended_at !== void 0 && found.suspended_at !== null || found.permissions.issues !== \"write\" || found.permissions.pull_requests !== \"write\" || !Array.every(requiredEvents, (event) => Array.contains(found.events, event))) return yield* AgentChannel.HandlerError.make({ code: \"rejected\" });\n\t\t\treturn {\n\t\t\t\tbotUserId: `${(yield* read(BotUser, yield* call(installation, HttpClientRequest.get(`/users/${encodeURIComponent(`${app.slug}[bot]`)}`)))).id}`,\n\t\t\t\tslug: app.slug\n\t\t\t};\n\t\t});\n\t\t/** Point the App's webhook at `ingressUrl` with the Connection's secret; GitHub never shows the secret it has. */\n\t\tconst registerWebhook = Effect.fn(\"GitHubAppClient.registerWebhook\")(function* (auth, ingressUrl) {\n\t\t\tconst hook = yield* read(HookConfig, yield* send(HttpClientRequest.bodyJsonUnsafe(HttpClientRequest.patch(\"/app/hook/config\"), {\n\t\t\t\tcontent_type: \"json\",\n\t\t\t\tinsecure_ssl: \"0\",\n\t\t\t\tsecret: auth.webhookSecret,\n\t\t\t\turl: ingressUrl\n\t\t\t}), yield* appJwt(auth), false));\n\t\t\tif (hook.url !== ingressUrl || hook.content_type !== \"json\") return yield* AgentChannel.HandlerError.make({ code: \"rejected\" });\n\t\t});\n\t\t/** The user's role on the repository; `none` for an account GitHub does not know. */\n\t\tconst permission = Effect.fn(\"GitHubAppClient.permission\")(function* (installation, repository, login) {\n\t\t\tconst found = yield* readFound(CollaboratorPermission, yield* call(installation, HttpClientRequest.get(`${repositoryPath(repository)}/collaborators/${encodeURIComponent(login)}/permission`)));\n\t\t\treturn pipe(found, Option.flatMap((role) => pipe(Schema.decodeUnknownOption(Permission)(role.role_name), Option.orElse(() => Schema.decodeUnknownOption(Permission)(role.permission)))), Option.getOrElse(() => \"none\"));\n\t\t});\n\t\tconst postComment = Effect.fn(\"GitHubAppClient.postComment\")(function* (installation, issue, text) {\n\t\t\tconst response = yield* call(installation, HttpClientRequest.bodyJsonUnsafe(HttpClientRequest.post(`${issuePath(issue)}/comments`), { body: text }), true);\n\t\t\treturn `${(yield* read(Created, response, true)).id}`;\n\t\t});\n\t\tconst checkOwnComment = Effect.fn(\"GitHubAppClient.checkOwnComment\")(function* (installation, issue, id, botUserId) {\n\t\t\tconst found = yield* readFound(CommentOwner, yield* call(installation, HttpClientRequest.get(commentPath(issue, id))));\n\t\t\treturn yield* Option.match(found, {\n\t\t\t\tonNone: () => Effect.succeed(false),\n\t\t\t\tonSome: (comment) => {\n\t\t\t\t\tif (comment.user === null || `${comment.user.id}` !== botUserId || comment.issue_url !== `${apiBase}${issuePath(issue)}`) return Effect.fail(AgentChannel.HandlerError.make({ code: \"rejected\" }));\n\t\t\t\t\treturn Effect.succeed(true);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t\t/** Replace a comment's text; false when the comment is gone. */\n\t\tconst editComment = Effect.fn(\"GitHubAppClient.editComment\")(function* (installation, repository, id, text) {\n\t\t\tconst response = yield* call(installation, HttpClientRequest.bodyJsonUnsafe(HttpClientRequest.patch(commentPath(repository, id)), { body: text }));\n\t\t\treturn Option.isSome(yield* readFound(Created, response));\n\t\t});\n\t\t/** Delete a comment; one already gone counts as deleted. */\n\t\tconst deleteComment = Effect.fn(\"GitHubAppClient.deleteComment\")(function* (installation, repository, id) {\n\t\t\tyield* gone(yield* call(installation, HttpClientRequest.delete(commentPath(repository, id))));\n\t\t});\n\t\tconst react = Effect.fn(\"GitHubAppClient.react\")(function* (installation, issue, target, content, active) {\n\t\t\tconst path = pipe(Match.value(target), Match.when({ kind: \"issue\" }, () => `${issuePath(issue)}/reactions`), Match.when({ kind: \"comment\" }, (comment) => `${commentPath(issue, comment.id)}/reactions`), Match.when({ kind: \"review-comment\" }, (comment) => `${repositoryPath(issue)}/pulls/comments/${comment.id}/reactions`), Match.exhaustive);\n\t\t\tconst response = yield* call(installation, HttpClientRequest.bodyJsonUnsafe(HttpClientRequest.post(path), { content }));\n\t\t\tif (active) {\n\t\t\t\tyield* read(Created, response);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tyield* Option.match(yield* readFound(Created, response), {\n\t\t\t\tonNone: () => Effect.void,\n\t\t\t\tonSome: (reaction) => Effect.flatMap(call(installation, HttpClientRequest.delete(`${path}/${reaction.id}`)), gone)\n\t\t\t});\n\t\t});\n\t\t/** The issue or pull request and its latest `limit` conversation comments, oldest first. */\n\t\tconst readComments = Effect.fn(\"GitHubAppClient.readComments\")(function* (installation, issue, limit) {\n\t\t\tconst record = yield* read(IssueRecord, yield* call(installation, HttpClientRequest.get(issuePath(issue))));\n\t\t\tconst last = Math.ceil(record.comments / 100);\n\t\t\tconst pages = Array.filter([\n\t\t\t\tlast - 2,\n\t\t\t\tlast - 1,\n\t\t\t\tlast\n\t\t\t], (number) => number >= 1 && (last - number) * 100 < limit + 100);\n\t\t\tconst comments = yield* Effect.forEach(pages, (number) => Effect.flatMap(call(installation, HttpClientRequest.setUrlParams(HttpClientRequest.get(`${issuePath(issue)}/comments`), {\n\t\t\t\tpage: `${number}`,\n\t\t\t\tper_page: \"100\"\n\t\t\t})), (response) => read(Schema.Array(Comment), response)), { concurrency: 1 });\n\t\t\treturn {\n\t\t\t\tcomments: Array.takeRight(Array.flatten(comments), limit),\n\t\t\t\tissue: record\n\t\t\t};\n\t\t});\n\t\treturn GitHubAppClient.of({\n\t\t\tcheckInstallation,\n\t\t\tcheckOwnComment,\n\t\t\tdeleteComment,\n\t\t\teditComment,\n\t\t\tpermission,\n\t\t\tpostComment,\n\t\t\treact,\n\t\t\treadComments,\n\t\t\tregisterWebhook\n\t\t});\n\t}));\n};\n//#endregion\nexport { Comment, GitHubAppClient, IssueRecord };\n\n//# sourceMappingURL=github-app-client.js.map"
|
|
8
|
+
],
|
|
9
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,IAAM,SAAS;AAuBf,IAAM,sBAAsB;AAAA,GACzB,SAAS;AAAA,GACT,OAAO,SAAS,GAAG;AAAA,IAClB,OAAO,KAAK,QAAQ,OAAO,UAAU;AAAA;AAAA,EAEvC,QAAQ,GAAG;AAAA,IACT,OAAO,kBAAkB,OAAO,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA,EAElD,MAAM,GAAG;AAAA,IACP,OAAO;AAAA,MACL,KAAK;AAAA,MACL,QAAQ,OAAO,MAAM,KAAK,IAAI,CAAC;AAAA,IACjC;AAAA;AAAA,GAED,kBAAkB,GAAG;AAAA,IACpB,OAAO,KAAK,OAAO;AAAA;AAAA,EAErB,IAAI,GAAG;AAAA,IACL,OAAO,cAAc,MAAM,SAAS;AAAA;AAExC;AAiCO,IAAM,QAAQ,MAAM;AAAA,EACzB,MAAM,OAAO,OAAO,OAAO,mBAAmB;AAAA,EAC9C,KAAK,UAAU,IAAI;AAAA,EACnB,KAAK,UAAU,IAAI;AAAA,EACnB,OAAO;AAAA;AA+BF,IAAM,OAAO,IAAI,YAAY,aAAa,OAAO;AAoCjD,IAAM,eAAe,aAAW;AAAA,EACrC,MAAM,OAAO,MAAM;AAAA,EACnB,YAAY,KAAK,UAAU,SAAS;AAAA,IAClC,IAAI,MAAM,KAAK,KAAK;AAAA,EACtB;AAAA,EACA,OAAO;AAAA;AAmCF,IAAM,sBAAmB,KAAK,GAAG,CAAC,MAAM,QAAQ;AAAA,EACrD,IAAI,KAAK,QAAQ,IAAI,GAAG,GAAG;AAAA,IACzB,OAAc,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC;AAAA,EAC1C,EAAO,SAAI,YAAY,GAAG,GAAG;AAAA,IAC3B,OAAc,KAAK;AAAA,EACrB;AAAA,EACA,MAAM,QAAY,KAAK,GAAG;AAAA,EAC1B,MAAM,SAAS,KAAK,QAAQ,IAAI,KAAI;AAAA,EACpC,IAAI,WAAW,WAAW;AAAA,IACxB,OAAc,KAAK;AAAA,EACrB;AAAA,EACA,OAAO,cAAc,MAAM,QAAQ,GAAG;AAAA,CACvC;AACD,IAAM,cAAc,OAAK,OAAO,MAAM,YAAY,OAAO,MAAM;AAgE/D,IAAM,gBAAgB,CAAC,MAAM,QAAQ,QAAQ;AAAA,EAC3C,SAAS,IAAI,GAAG,MAAM,OAAO,OAAQ,IAAI,KAAK,KAAK;AAAA,IACjD,IAAU,OAAO,KAAK,OAAO,EAAE,GAAG;AAAA,MAChC,MAAM,SAAS,OAAO;AAAA,MACtB,OAAc,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC;AAAA,IAC7C;AAAA,EACF;AAAA,EACA,OAAc,KAAK;AAAA;AAuEd,IAAM,sBAAmB,KAAK,GAAG,CAAC,MAAM,KAAK,UAAU;AAAA,EAC5D,IAAI,KAAK,QAAQ,IAAI,GAAG,KAAK,YAAY,GAAG,GAAG;AAAA,IAC7C,KAAK,QAAQ,IAAI,KAAK,KAAK;AAAA,IAC3B,OAAO;AAAA,EACT;AAAA,EACA,MAAM,QAAY,KAAK,GAAG;AAAA,EAC1B,MAAM,SAAS,KAAK,QAAQ,IAAI,KAAI;AAAA,EACpC,IAAI,WAAW,WAAW;AAAA,IACxB,KAAK,QAAQ,IAAI,OAAM,CAAC,GAAG,CAAC;AAAA,IAC5B,KAAK,QAAQ,IAAI,KAAK,KAAK;AAAA,IAC3B,OAAO;AAAA,EACT;AAAA,EACA,IAAI,SAAS,UAAU,QAAQ,GAAG;AAAA,EAClC,IAAI,WAAW,WAAW;AAAA,IACxB,OAAO,KAAK,GAAG;AAAA,IACf,SAAS;AAAA,EACX;AAAA,EACA,KAAK,QAAQ,IAAI,QAAQ,KAAK;AAAA,EAC9B,OAAO;AAAA,CACR;AACD,IAAM,YAAY,CAAC,QAAQ,QAAQ;AAAA,EACjC,SAAS,IAAI,GAAG,MAAM,OAAO,OAAQ,IAAI,KAAK,KAAK;AAAA,IACjD,IAAU,OAAO,KAAK,OAAO,EAAE,GAAG;AAAA,MAChC,OAAO,OAAO;AAAA,IAChB;AAAA,EACF;AAAA;AAyKK,IAAM,yBAAsB,KAAK,GAAG,CAAC,MAAM,SAAS;AAAA,EACzD,IAAI,YAAY,IAAI,GAAG;AAAA,IACrB,KAAK,QAAQ,OAAO,IAAI;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EACA,MAAM,QAAY,KAAK,IAAI;AAAA,EAC3B,MAAM,SAAS,KAAK,QAAQ,IAAI,KAAI;AAAA,EACpC,IAAI,WAAW,WAAW;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EACA,SAAS,IAAI,GAAG,MAAM,OAAO,OAAQ,IAAI,KAAK,KAAK;AAAA,IACjD,MAAM,OAAO,OAAO;AAAA,IACpB,IAAI,SAAS,QAAc,OAAO,MAAM,IAAI,GAAG;AAAA,MAC7C,KAAK,QAAQ,OAAO,IAAI;AAAA,MACxB,OAAO,OAAO,GAAG,CAAC;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA,EACA,IAAI,OAAO,WAAW,GAAG;AAAA,IACvB,KAAK,QAAQ,OAAO,KAAI;AAAA,EAC1B;AAAA,EACA,OAAO;AAAA,CACR;AA6EM,IAAM,OAAO,UAAQ,KAAK,QAAQ;;;AC9mBzC,IAAM,UAAS;AA+CR,IAAM,WAAW,CAAC,QAAQ,YAAmB,YAAY,aAAW;AAAA,EACzE,MAAM,OAAO,OAAO,OAAO,KAAK;AAAA,EAChC,KAAK,SAAS,SAAc,cAAc,OAAO,GAAG,GAAG,WAAiB,MAAM,SAAS,KAAK,CAAC;AAAA,EAC7F,KAAK,MAAqB,KAAK;AAAA,EAC/B,KAAK,WAAW,QAAQ;AAAA,EACxB,KAAK,aAAa,QAAQ,aAAa,CAAC,MAAM,QAAiB,gBAAgB,QAAQ,WAAW,MAAM,GAAG,CAAC,IAAI;AAAA,EAChH,OAAc,SAAQ,IAAI;AAAA,CAC3B;AA0ED,IAAM,QAAQ;AAAA,KACT;AAAA,GACF,UAAS;AAAA,EACV,MAAM,GAAG;AAAA,IACP,OAAO;AAAA,MACL,KAAK;AAAA,MACL,UAAU,KAAK;AAAA,MACf,KAAK,KAAK;AAAA,IACZ;AAAA;AAEJ;AACA,IAAM,oBAAoB,CAAC,GAAG,SAAkB;AAiGzC,IAAM,uBAAmB,KAAK,GAAG,CAAC,MAAM,QAAa,UAAU,WAAS;AAAA,EAC7E,MAAM,SAAwB,IAAI,KAAK,KAAK,GAAG;AAAA,EAC/C,IAAW,OAAO,MAAM,GAAG;AAAA,IACV,OAAO,KAAK,KAAK,GAAG;AAAA,IACnC,IAAI,CAAC,WAAW,OAAO,OAAO,KAAK,GAAG;AAAA,MAErB,IAAI,KAAK,KAAK,KAAK,OAAO,KAAK;AAAA,MAC9C,OAAO,OAAO,MAAM,MAAM,KAAK;AAAA,IACjC;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,IAAI,UAAU,OAAO,KAAK,OAAO,GAAG,CAAC;AAAA,EACnD,MAAM,cAAc,MAAM,YAAY,MAAM,KAAK,KAAK;AAAA,EACtD,IAAI,YAAY;AAAA,EAChB,MAAM,MAAM,YAAY,UAAQ;AAAA,IAE9B,MAAM,cAAc;AAAA,IACpB,IAAW,kBAAkB,IAAI,GAAG;AAAA,MAClC,YAAY,MAAM,KAAK,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,IACA,MAAM,MAAM,KAAK,WAAW,MAAM,GAAG;AAAA,IACrC,IAAa,OAAO,GAAG,GAAG;AAAA,MACxB,YAAY;AAAA,MACZ,YAAY,MAAM,KAAK,KAAK;AAAA,IAC9B,EAAO,SAAa,SAAS,GAAG,GAAG;AAAA,MACjC,MAAM,YAAY,MAAM,OAAc,QAAQ,EAAE,wBAAwB,IAAa,SAAS,GAAG;AAAA,IACnG;AAAA,GACD;AAAA,EACD,MAAM,OAAO,MAAM,MAAM,WAAW;AAAA,EACpC,IAAI,CAAC,cAAc,SAAS,aAAa,CAAQ,kBAAkB,IAAI,IAAI;AAAA,IAC1D,IAAI,KAAK,KAAK,KAAK,KAAK;AAAA,EACzC;AAAA,EACA,IAAI,OAAO,SAAS,KAAK,QAAQ,GAAG;AAAA,IAClC,cAAc,IAAI;AAAA,EACpB;AAAA,EACA,OAAO,MAAM,MAAM,KAAK;AAAA,CACzB,CAAC;AAAA;AACF,MAAM,UAAU;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW,CAAC,QAAQ,aAAa;AAAA,IAC/B,KAAK,QAAe,WAAW,QAAQ,aAAa,MAAM,IAAI;AAAA,IAC9D,KAAK,WAAW;AAAA,IAChB,KAAK,YAAY;AAAA;AAAA,EAEnB,KAAK,CAAC,OAAO;AAAA,IACX,IAAI,UAAU;AAAA,MAAW,OAAY,UAAU,WAAS,KAAK,MAAM,KAAK,CAAC;AAAA,IACzE,MAAM,OAAO,KAAK,MAAM,WAAW;AAAA,IACnC,IAAI;AAAA,MAAM,OAAO;AAAA,IACjB,KAAK;AAAA,IAGE,aAAa,OAAO,MAAM;AAAA,MAC/B,KAAK;AAAA,MACL,IAAI,KAAK,WAAW,KAAK,KAAK,MAAM,WAAW;AAAA,QAAG,OAAc;AAAA,MAGhE,KAAK,cAAc;AAAA,MACnB,OAAc,eAAe,KAAK,KAAK;AAAA,KACxC;AAAA,IACD,OAAc,UAAU,KAAK,KAAK;AAAA;AAEtC;AACA,IAAM,cAAc,CAAC,MAAM,KAAK,UAAU;AAAA,EACxC,MAAM,UAAyB,IAAI,KAAK,KAAK,GAAG;AAAA,EAChD,IAAW,OAAO,OAAO,KAAK,QAAQ,UAAU,OAAO;AAAA,IACtC,OAAO,KAAK,KAAK,GAAG;AAAA,EACrC;AAAA;AAEF,IAAM,aAAa,CAAC,OAAO,UAAU;AAAA,EACnC,IAAI,MAAM,cAAc,WAAW;AAAA,IACjC,OAAO;AAAA,EACT;AAAA,EACA,OAAO,MAAM,OAAc,QAAQ,EAAE,wBAAwB,KAAK,MAAM;AAAA;AAE1E,IAAM,gBAAgB,UAAQ;AAAA,EAC5B,IAAI,OAAsB,KAAK,KAAK,GAAG,IAAI,KAAK;AAAA,EAChD,IAAI,QAAQ;AAAA,IAAG;AAAA,EAEf,YAAY,QAAQ,KAAK,KAAK;AAAA,IACb,OAAO,KAAK,KAAK,GAAG;AAAA,IACnC;AAAA,IACA,IAAI,SAAS;AAAA,MAAG;AAAA,EAClB;AAAA;AAsaK,IAAM,6BAA0B,KAAK,GAAG,CAAC,MAAM,QAAe,KAAK,MAAM;AAAA,EAC/D,OAAO,KAAK,KAAK,GAAG;AAAA,CACpC,CAAC;;;ACzvBF;AAGA,IAAM,UAAU;AAChB,IAAM,iBAAiB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AACA,IAAM,MAAM,OAAc;AAAA,EACzB,IAAI;AAAA,EACJ,MAAM;AACP,CAAC;AACD,IAAM,kBAAkB,OAAc;AAAA,EACrC,QAAQ;AAAA,EACR,QAAQ,YAAa,OAAa;AAAA,EAClC,aAAa,OAAc;AAAA,IAC1B,QAAQ,YAAmB,OAAa;AAAA,IACxC,eAAe,YAAmB,OAAa;AAAA,EAChD,CAAC;AAAA,EACD,cAAc,YAAmB,OAAc,OAAa,CAAC;AAC9D,CAAC;AACD,IAAM,aAAa,OAAc;AAAA,EAChC,cAAc,YAAmB,OAAa;AAAA,EAC9C,KAAK,YAAmB,OAAa;AACtC,CAAC;AACD,IAAM,UAAU,OAAc;AAAA,EAC7B,IAAI;AAAA,EACJ,MAAM,QAAe,KAAK;AAC3B,CAAC;AACD,IAAM,oBAAoB,OAAc;AAAA,EACvC,YAAY;AAAA,EACZ,OAAO;AACR,CAAC;AACD,IAAM,yBAAyB,OAAc;AAAA,EAC5C,YAAY;AAAA,EACZ,WAAW;AACZ,CAAC;AACD,IAAM,SAAS,OAAc,OAAc;AAAA,EAC1C,IAAI;AAAA,EACJ,OAAO;AACR,CAAC,CAAC;AACF,IAAM,WAAU,OAAc;AAAA,EAC7B,MAAM,OAAc,OAAa;AAAA,EACjC,YAAY,qBAAa;AAAA,EACzB,IAAI;AAAA,EACJ,MAAM;AACP,CAAC;AACD,IAAM,eAAc,OAAc;AAAA,EACjC,MAAM,OAAc,OAAa;AAAA,EACjC,UAAU;AAAA,EACV,YAAY,qBAAa;AAAA,EACzB,OAAO;AAAA,EACP,MAAM;AACP,CAAC;AACD,IAAM,UAAU,OAAc,EAAE,IAAI,WAAU,CAAC;AAC/C,IAAM,eAAe,OAAc;AAAA,EAClC,WAAW;AAAA,EACX,MAAM;AACP,CAAC;AACD,IAAM,YAAY,eAAsB,OAAc;AAAA,EACrD,KAAK,QAAe,OAAO;AAAA,EAC3B,KAAK,QAAe,KAAK;AAC1B,CAAC,CAAC;AACF,IAAM,YAAY,eAAsB,OAAc;AAAA,EACrD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACN,CAAC,CAAC;AACF,IAAM,UAAU,IAAI;AACpB,IAAM,gBAAgB;AACtB,SAAS,GAAG,CAAC,KAAK,OAAO;AAAA,EACxB,IAAI,MAAM,SAAS;AAAA,IAAK,OAAO,WAAW,GAAG,KAAK,MAAM,QAAQ,GAAG,KAAK;AAAA,EACxE,IAAI,MAAM,SAAS;AAAA,IAAK,OAAO,WAAW,GAAG,KAAK,KAAK,MAAM,QAAQ,GAAG,KAAK;AAAA,EAC7E,OAAO,WAAW,GAAG,KAAK,KAAK,MAAM,UAAU,GAAG,MAAM,SAAS,KAAK,GAAG,KAAK;AAAA;AAE/E,SAAS,KAAK,CAAC,KAAK;AAAA,EACnB,MAAM,UAAU,KAAY,GAAG;AAAA,EAC/B,MAAM,QAAQ,WAAkB,iCAAiC,EAAE,OAAO;AAAA,EAC1E,MAAM,QAAQ,KAAK,OAAY,KAAK,GAAG,KAAW,MAAM,MAAM,iBAAiB,GAAG,QAAa,MAAM,aAAa,CAAC;AAAA,EACnH,IAAI,CAAC,WAAkB,cAAc,YAAY,EAAE,OAAO,KAAK,CAAC,SAAgB,YAAY,YAAY,EAAE,OAAO;AAAA,IAAG,OAAO,KAAY;AAAA,EACvI,MAAM,OAAO,KAAK,SAAS,QAAe,cAAc,cAAc,EAAE,GAAG,QAAe,YAAY,cAAc,EAAE,GAAG,WAAkB,eAAe,EAAE,CAAC;AAAA,EAC7J,OAAO,KAAK,WAAkB,QAAc,IAAI,CAAC,GAAG,IAAW,CAAC,UAAU;AAAA,IACzE,IAAI,CAAC;AAAA,MAAO,OAAO;AAAA,IACnB,OAAO,IAAI,IAAI,WAAW,GAAG,GAAG;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC;AAAA,GACvC,CAAC;AAAA;AAEH,SAAS,SAAS,CAAC,SAAS;AAAA,EAC3B,IAAI;AAAA,IAAS,OAAO;AAAA,EACpB,OAAO;AAAA;AAER,SAAS,OAAO,CAAC,UAAU,SAAS;AAAA,EACnC,MAAM,UAAU,SAAS,QAAQ,6BAA6B,OAAO,SAAS,QAAQ,mBAAwB;AAAA,EAC9G,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,OAAO;AAAA,IAAS,OAAO;AAAA,EAC1E,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW;AAAA,IAAK,OAAO;AAAA,EAC/D,IAAI,SAAS,UAAU;AAAA,IAAK,OAAO,UAAU,OAAO;AAAA,EACpD,OAAO;AAAA;AAER,IAAM,OAAO,WAAkB,UAAU,CAAC,QAAQ,UAAU,UAAU,OAAO;AAAA,EAC5E,IAAI,SAAS,SAAS,OAAO,SAAS,UAAU;AAAA,IAAK,OAAO,OAAO,qBAAa,aAAa,KAAK,EAAE,MAAM,QAAQ,UAAU,OAAO,EAAE,CAAC;AAAA,EACtI,OAAO,OAAO,KAAK,eAAkC,MAAM,EAAE,QAAQ,GAAG,QAAe,YAAY,GAAG,UAAgB,MAAM,qBAAa,aAAa,KAAK,EAAE,MAAM,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC;AAAA,CACzL;AACD,SAAS,SAAS,CAAC,QAAQ,UAAU;AAAA,EACpC,IAAI,SAAS,WAAW;AAAA,IAAK,OAAO,SAAe,KAAY,CAAC;AAAA,EAChE,OAAO,OAAc,KAAK,QAAQ,QAAQ,CAAC;AAAA;AAE5C,SAAS,IAAI,CAAC,UAAU;AAAA,EACvB,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW;AAAA,IAAK,OAAO;AAAA,EAC/D,OAAO,MAAY,qBAAa,aAAa,KAAK,EAAE,MAAM,QAAQ,UAAU,KAAK,EAAE,CAAC,CAAC;AAAA;AAEtF,SAAS,cAAc,CAAC,YAAY;AAAA,EACnC,OAAO,UAAU,mBAAmB,WAAW,KAAK,KAAK,mBAAmB,WAAW,IAAI;AAAA;AAE5F,SAAS,SAAS,CAAC,OAAO;AAAA,EACzB,OAAO,GAAG,eAAe,KAAK,YAAY,MAAM;AAAA;AAEjD,SAAS,WAAW,CAAC,YAAY,IAAI;AAAA,EACpC,OAAO,GAAG,eAAe,UAAU,qBAAqB;AAAA;AAEzD,IAAI,mBAAkB,MAAM,wBAAwB,QAAgB,EAAE,uDAAuD,EAAE;AAAA,SACvH,QAAQ,OAAa,MAAM,IAAW,UAAU,GAAG;AAAA,IACzD,MAAM,OAAO,OAAO;AAAA,IACpB,MAAM,SAAS,KAAK,MAAM,WAAsB,CAAC,YAAY,KAAK,SAAS,WAA6B,OAAO,GAAG,WAA6B;AAAA,MAC9I,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,wBAAwB;AAAA,IACzB,CAAC,CAAC,CAAC,CAAC;AAAA,IACJ,MAAM,OAAO,GAAU,sBAAsB,EAAE,UAAU,CAAC,SAAS,OAAO,SAAS;AAAA,MAClF,OAAO,OAAO,KAAK,OAAO,QAAQ,YAA8B,SAAS,KAAK,CAAC,GAAG,eAAsB,aAA6B,EAAE,UAAU,SAAS,CAAC,GAAG,QAAe,YAAY,GAAG,UAAgB,MAAM,qBAAa,aAAa,KAAK,EAAE,MAAM,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC;AAAA,KAC/Q;AAAA,IACD,MAAM,SAAS,GAAU,wBAAwB,EAAE,UAAU,CAAC,MAAM;AAAA,MACnE,MAAM,MAAM,KAAK,OAAO,OAAO,qBAA2B,IAAG;AAAA,MAC7D,MAAM,WAAW,GAAG,QAAiB,OAAO,aAAoB,SAAS,EAAE;AAAA,QAC1E,KAAK;AAAA,QACL,KAAK;AAAA,MACN,CAAC,CAAC,KAAK,QAAiB,OAAO,aAAoB,SAAS,EAAE;AAAA,QAC7D,KAAK,MAAM;AAAA,QACX,KAAK,MAAM;AAAA,QACX,KAAK,KAAK;AAAA,MACX,CAAC,CAAC;AAAA,MACF,MAAM,MAAM,OAAO,KAAK,MAAM,KAAK,UAAU,GAAG,aAAmB,UAAgB,MAAM,qBAAa,aAAa,KAAK,EAAE,MAAM,eAAe,CAAC,CAAC,CAAC;AAAA,MAClJ,MAAM,YAAY,OAAO,KAAK,MAAW,MAAM,KAAK,UAAU,QAAQ,OAAO,QAAQ,GAAG,iBAAiB;AAAA,QACxG,QAAQ;AAAA,QACR,KAAK,OAAO,KAAK,GAAG;AAAA,QACpB,MAAM;AAAA,MACP,CAAC,CAAC,CAAC,GAAG,UAAgB,MAAM,qBAAa,aAAa,KAAK,EAAE,MAAM,eAAe,CAAC,CAAC,CAAC;AAAA,MACrF,OAAO,GAAG,YAAY,QAAiB,IAAI,WAAW,SAAS,CAAC;AAAA,OAC9D,SAAgB,eAAe,MAAM,qBAAa,aAAa,KAAK,EAAE,MAAM,eAAe,CAAC,CAAC,CAAC;AAAA,IACjG,MAAM,SAAS,GAAU,wBAAwB,EAAE,UAAU,CAAC,MAAM,MAAM,QAAQ;AAAA,MACjF,OAAO,OAAO,KAAK,QAAQ,OAAO,KAAK,KAAsB,IAAI,GAAG,OAAO,OAAO,IAAI,GAAG,KAAK,CAAC;AAAA,KAC/F;AAAA,IACD,MAAM,SAAS,OAAO,SAAe,CAAC,iBAAiB,IAAW,UAAU,GAAG;AAAA,MAC9E,MAAM,WAAW,OAAO,KAAK,KAAuB,sBAAsB,aAAa,8BAA8B,GAAG,OAAO,OAAO,aAAa,IAAI,GAAG,KAAK;AAAA,MAC/J,MAAM,UAAU,OAAO,KAAK,mBAAmB,QAAQ;AAAA,MACvD,MAAM,MAAM,cAAuB,QAAQ,UAAU,KAAK,OAAO,qBAA2B;AAAA,MAC5F,IAAI,OAAO;AAAA,QAAG,OAAO,OAAO,qBAAa,aAAa,KAAK,EAAE,MAAM,cAAc,CAAC;AAAA,MAClF,OAAO;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,KAAK,IAAW,KAAK,OAAK;AAAA,MAC3B;AAAA,KACA,GAAG;AAAA,MACH,UAAU;AAAA,MACV,YAAY,CAAC,SAAS;AAAA,QACrB,IAAI,WAAe,IAAI;AAAA,UAAG,OAAO,OAAgB,KAAK,MAAM,GAAG;AAAA,QAC/D,OAAO;AAAA;AAAA,IAET,CAAC;AAAA,IACD,MAAM,OAAO,GAAU,sBAAsB,EAAE,UAAU,CAAC,cAAc,SAAS,UAAU,OAAO;AAAA,MACjG,MAAM,SAAS,OAAO,KAAU,QAAQ,YAAY;AAAA,MACpD,MAAM,WAAW,OAAO,KAAK,SAAS,OAAO,OAAO,OAAO;AAAA,MAC3D,IAAI,SAAS,WAAW;AAAA,QAAK,OAAO,WAAiB,QAAQ,YAAY;AAAA,MACzE,OAAO;AAAA,KACP;AAAA,IAED,MAAM,oBAAoB,GAAU,mCAAmC,EAAE,UAAU,CAAC,cAAc;AAAA,MACjG,MAAM,MAAM,OAAO,OAAO,aAAa,MAAM,QAAQ,GAAG;AAAA,MACxD,MAAM,QAAQ,OAAO,OAAO,aAAa,MAAM,sBAAsB,aAAa,kBAAkB,eAAe;AAAA,MACnH,IAAI,GAAG,IAAI,SAAS,aAAa,KAAK,SAAS,MAAM,WAAW,IAAI;AAAA,QAAI,OAAO,OAAO,qBAAa,aAAa,KAAK,EAAE,MAAM,eAAe,CAAC;AAAA,MAC7I,IAAI,MAAM,iBAAsB,aAAK,MAAM,iBAAiB,QAAQ,MAAM,YAAY,WAAW,WAAW,MAAM,YAAY,kBAAkB,WAAW,CAAC,MAAY,gBAAgB,CAAC,UAAU,SAAe,MAAM,QAAQ,KAAK,CAAC;AAAA,QAAG,OAAO,OAAO,qBAAa,aAAa,KAAK,EAAE,MAAM,WAAW,CAAC;AAAA,MAC1S,OAAO;AAAA,QACN,WAAW,IAAI,OAAO,KAAK,SAAS,OAAO,KAAK,cAAc,KAAsB,UAAU,mBAAmB,GAAG,IAAI,WAAW,GAAG,CAAC,CAAC,GAAG;AAAA,QAC3I,MAAM,IAAI;AAAA,MACX;AAAA,KACA;AAAA,IAED,MAAM,kBAAkB,GAAU,iCAAiC,EAAE,UAAU,CAAC,MAAM,YAAY;AAAA,MACjG,MAAM,OAAO,OAAO,KAAK,YAAY,OAAO,KAAK,eAAiC,MAAwB,kBAAkB,GAAG;AAAA,QAC9H,cAAc;AAAA,QACd,cAAc;AAAA,QACd,QAAQ,KAAK;AAAA,QACb,KAAK;AAAA,MACN,CAAC,GAAG,OAAO,OAAO,IAAI,GAAG,KAAK,CAAC;AAAA,MAC/B,IAAI,KAAK,QAAQ,cAAc,KAAK,iBAAiB;AAAA,QAAQ,OAAO,OAAO,qBAAa,aAAa,KAAK,EAAE,MAAM,WAAW,CAAC;AAAA,KAC9H;AAAA,IAED,MAAM,aAAa,GAAU,4BAA4B,EAAE,UAAU,CAAC,cAAc,YAAY,OAAO;AAAA,MACtG,MAAM,QAAQ,OAAO,UAAU,wBAAwB,OAAO,KAAK,cAAc,KAAsB,GAAG,eAAe,UAAU,mBAAmB,mBAAmB,KAAK,cAAc,CAAC,CAAC;AAAA,MAC9L,OAAO,KAAK,OAAO,QAAe,CAAC,SAAS,KAAK,oBAA2B,WAAU,EAAE,KAAK,SAAS,GAAG,OAAc,MAAM,oBAA2B,WAAU,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,UAAiB,MAAM,MAAM,CAAC;AAAA,KACvN;AAAA,IACD,MAAM,cAAc,GAAU,6BAA6B,EAAE,UAAU,CAAC,cAAc,OAAO,MAAM;AAAA,MAClG,MAAM,WAAW,OAAO,KAAK,cAAc,eAAiC,KAAuB,GAAG,UAAU,KAAK,YAAY,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,IAAI;AAAA,MACzJ,OAAO,IAAI,OAAO,KAAK,SAAS,UAAU,IAAI,GAAG;AAAA,KACjD;AAAA,IACD,MAAM,kBAAkB,GAAU,iCAAiC,EAAE,UAAU,CAAC,cAAc,OAAO,IAAI,WAAW;AAAA,MACnH,MAAM,QAAQ,OAAO,UAAU,cAAc,OAAO,KAAK,cAAc,KAAsB,YAAY,OAAO,EAAE,CAAC,CAAC,CAAC;AAAA,MACrH,OAAO,OAAO,OAAa,OAAO;AAAA,QACjC,QAAQ,MAAM,SAAe,KAAK;AAAA,QAClC,QAAQ,CAAC,YAAY;AAAA,UACpB,IAAI,QAAQ,SAAS,QAAQ,GAAG,QAAQ,KAAK,SAAS,aAAa,QAAQ,cAAc,GAAG,UAAU,UAAU,KAAK;AAAA,YAAK,OAAO,MAAY,qBAAa,aAAa,KAAK,EAAE,MAAM,WAAW,CAAC,CAAC;AAAA,UACjM,OAAO,SAAe,IAAI;AAAA;AAAA,MAE5B,CAAC;AAAA,KACD;AAAA,IAED,MAAM,cAAc,GAAU,6BAA6B,EAAE,UAAU,CAAC,cAAc,YAAY,IAAI,MAAM;AAAA,MAC3G,MAAM,WAAW,OAAO,KAAK,cAAc,eAAiC,MAAwB,YAAY,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,CAAC;AAAA,MACjJ,OAAO,OAAc,OAAO,UAAU,SAAS,QAAQ,CAAC;AAAA,KACxD;AAAA,IAED,MAAM,gBAAgB,GAAU,+BAA+B,EAAE,UAAU,CAAC,cAAc,YAAY,IAAI;AAAA,MACzG,OAAO,KAAK,OAAO,KAAK,cAAc,IAAyB,YAAY,YAAY,EAAE,CAAC,CAAC,CAAC;AAAA,KAC5F;AAAA,IACD,MAAM,QAAQ,GAAU,uBAAuB,EAAE,UAAU,CAAC,cAAc,OAAO,QAAQ,SAAS,QAAQ;AAAA,MACzG,MAAM,OAAO,KAAK,OAAY,MAAM,GAAG,KAAW,EAAE,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,KAAK,aAAa,GAAG,KAAW,EAAE,MAAM,UAAU,GAAG,CAAC,YAAY,GAAG,YAAY,OAAO,QAAQ,EAAE,aAAa,GAAG,KAAW,EAAE,MAAM,iBAAiB,GAAG,CAAC,YAAY,GAAG,eAAe,KAAK,oBAAoB,QAAQ,cAAc,GAAG,UAAgB;AAAA,MAClV,MAAM,WAAW,OAAO,KAAK,cAAc,eAAiC,KAAuB,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC;AAAA,MACtH,IAAI,QAAQ;AAAA,QACX,OAAO,KAAK,SAAS,QAAQ;AAAA,QAC7B;AAAA,MACD;AAAA,MACA,OAAO,OAAa,OAAO,UAAU,SAAS,QAAQ,GAAG;AAAA,QACxD,QAAQ,MAAM;AAAA,QACd,QAAQ,CAAC,aAAa,SAAe,KAAK,cAAc,IAAyB,GAAG,QAAQ,SAAS,IAAI,CAAC,GAAG,IAAI;AAAA,MAClH,CAAC;AAAA,KACD;AAAA,IAED,MAAM,eAAe,GAAU,8BAA8B,EAAE,UAAU,CAAC,cAAc,OAAO,OAAO;AAAA,MACrG,MAAM,SAAS,OAAO,KAAK,cAAa,OAAO,KAAK,cAAc,KAAsB,UAAU,KAAK,CAAC,CAAC,CAAC;AAAA,MAC1G,MAAM,OAAO,KAAK,KAAK,OAAO,WAAW,GAAG;AAAA,MAC5C,MAAM,QAAQ,QAAa;AAAA,QAC1B,OAAO;AAAA,QACP,OAAO;AAAA,QACP;AAAA,MACD,GAAG,CAAC,WAAW,UAAU,MAAM,OAAO,UAAU,MAAM,QAAQ,GAAG;AAAA,MACjE,MAAM,WAAW,OAAO,QAAe,OAAO,CAAC,WAAW,SAAe,KAAK,cAAc,aAA+B,KAAsB,GAAG,UAAU,KAAK,YAAY,GAAG;AAAA,QACjL,MAAM,GAAG;AAAA,QACT,UAAU;AAAA,MACX,CAAC,CAAC,GAAG,CAAC,aAAa,KAAK,YAAa,QAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC;AAAA,MAC7E,OAAO;AAAA,QACN,UAAU,UAAgB,QAAc,QAAQ,GAAG,KAAK;AAAA,QACxD,OAAO;AAAA,MACR;AAAA,KACA;AAAA,IACD,OAAO,gBAAgB,GAAG;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAAA,GACD,CAAC;AACH;",
|
|
10
|
+
"debugId": "647D02E757151B0164756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
__exportAll2
|
|
4
|
+
} from "./plugin-2jdfj02n.js";
|
|
5
|
+
import {
|
|
6
|
+
pipe,
|
|
7
|
+
none,
|
|
8
|
+
map,
|
|
9
|
+
liftPredicate,
|
|
10
|
+
mapError,
|
|
11
|
+
match3,
|
|
12
|
+
all,
|
|
13
|
+
replace,
|
|
14
|
+
slice,
|
|
15
|
+
startsWith,
|
|
16
|
+
fail5,
|
|
17
|
+
fromResult,
|
|
18
|
+
fnUntraced,
|
|
19
|
+
optionalKey,
|
|
20
|
+
optional,
|
|
21
|
+
String3,
|
|
22
|
+
Struct,
|
|
23
|
+
NonEmptyString,
|
|
24
|
+
value2,
|
|
25
|
+
discriminatorsExhaustive,
|
|
26
|
+
HttpClientError,
|
|
27
|
+
TransportError,
|
|
28
|
+
InvalidUrlError,
|
|
29
|
+
fromString,
|
|
30
|
+
setHeader,
|
|
31
|
+
basicAuth,
|
|
32
|
+
bearerToken,
|
|
33
|
+
updateUrl,
|
|
34
|
+
mapRequest,
|
|
35
|
+
mapRequestEffect,
|
|
36
|
+
AuthMethod_exports,
|
|
37
|
+
Plugin_exports
|
|
38
|
+
} from "./plugin-w0va8331.js";
|
|
39
|
+
import {
|
|
40
|
+
gitHubAppAuth2
|
|
41
|
+
} from "./plugin-2qqpmr67.js";
|
|
42
|
+
|
|
43
|
+
// dist/auth.js
|
|
44
|
+
var auth_exports2 = /* @__PURE__ */ __exportAll2({
|
|
45
|
+
Auth: () => auth_exports2,
|
|
46
|
+
authMethods: () => authMethods2,
|
|
47
|
+
authorize: () => authorize2,
|
|
48
|
+
sandboxAccess: () => sandboxAccess2
|
|
49
|
+
});
|
|
50
|
+
var apiBase = "https://api.github.com";
|
|
51
|
+
function webOrigin(server) {
|
|
52
|
+
if (server === undefined || server === "")
|
|
53
|
+
return "https://github.com";
|
|
54
|
+
const origin = match3(fromString(server), {
|
|
55
|
+
onFailure: () => replace(/^(https?:\/\/[^/]+).*$/u, "$1")(server),
|
|
56
|
+
onSuccess: (url) => url.origin
|
|
57
|
+
});
|
|
58
|
+
return origin === apiBase ? "https://github.com" : origin;
|
|
59
|
+
}
|
|
60
|
+
var authMethods2 = [...[AuthMethod_exports.make("personal-access-token", {
|
|
61
|
+
description: "Authenticate with a GitHub personal access token sent as a bearer token; set server for GitHub Enterprise Server",
|
|
62
|
+
name: "GitHub personal access token",
|
|
63
|
+
schema: Struct({
|
|
64
|
+
server: optionalKey(String3),
|
|
65
|
+
token: NonEmptyString
|
|
66
|
+
})
|
|
67
|
+
}), AuthMethod_exports.oauth2("oauth2", {
|
|
68
|
+
authorizationUrl: (context) => `${webOrigin(context.setup.server)}/login/oauth/authorize`,
|
|
69
|
+
client: (options) => ({
|
|
70
|
+
authentication: "post",
|
|
71
|
+
clientId: options.setup.clientId,
|
|
72
|
+
clientSecret: options.setup.clientSecret
|
|
73
|
+
}),
|
|
74
|
+
description: "Authenticate with a GitHub OAuth app; set server for GitHub Enterprise Server, whose OAuth endpoints are on the same host",
|
|
75
|
+
material: AuthMethod_exports.OAuth2TokenMaterial,
|
|
76
|
+
name: "GitHub OAuth app",
|
|
77
|
+
resolve: (material, context) => ({
|
|
78
|
+
accessToken: material.accessToken,
|
|
79
|
+
server: context.setup.server
|
|
80
|
+
}),
|
|
81
|
+
scopes: [
|
|
82
|
+
"repo",
|
|
83
|
+
"admin:repo_hook",
|
|
84
|
+
"admin:org",
|
|
85
|
+
"admin:org_hook",
|
|
86
|
+
"gist",
|
|
87
|
+
"notifications",
|
|
88
|
+
"user",
|
|
89
|
+
"write:packages",
|
|
90
|
+
"read:packages",
|
|
91
|
+
"delete:packages",
|
|
92
|
+
"workflow"
|
|
93
|
+
],
|
|
94
|
+
setup: Struct({
|
|
95
|
+
clientId: String3,
|
|
96
|
+
clientSecret: String3,
|
|
97
|
+
server: optional(String3)
|
|
98
|
+
}),
|
|
99
|
+
tokenUrl: (context) => `${webOrigin(context.setup.server)}/login/oauth/access_token`,
|
|
100
|
+
value: Struct({
|
|
101
|
+
accessToken: String3,
|
|
102
|
+
server: optional(String3)
|
|
103
|
+
})
|
|
104
|
+
})], gitHubAppAuth2];
|
|
105
|
+
function token(binding) {
|
|
106
|
+
return pipe(value2(binding), discriminatorsExhaustive("methodId")({
|
|
107
|
+
oauth2: (binding) => binding.value.accessToken,
|
|
108
|
+
"personal-access-token": (binding) => binding.value.token
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
function authorize2(client, context) {
|
|
112
|
+
const binding = context.auth.current;
|
|
113
|
+
if (binding.methodId === "app")
|
|
114
|
+
return mapRequestEffect(client, (request) => fail5(new HttpClientError({ reason: new TransportError({
|
|
115
|
+
request,
|
|
116
|
+
description: "Use a personal access token or OAuth Connection for GitHub API Actions and Triggers; GitHub App credentials serve the Agent Channel."
|
|
117
|
+
}) })));
|
|
118
|
+
const server = binding.value.server;
|
|
119
|
+
return pipe(client, mapRequest(bearerToken(token(binding))), mapRequest(setHeader("X-GitHub-Api-Version", "2022-11-28")), mapRequestEffect(fnUntraced(function* (request) {
|
|
120
|
+
if (server === undefined || server === "")
|
|
121
|
+
return request;
|
|
122
|
+
const urls = yield* pipe(all({
|
|
123
|
+
base: fromString(server),
|
|
124
|
+
target: fromString(request.url)
|
|
125
|
+
}), mapError((cause) => new HttpClientError({ reason: new InvalidUrlError({
|
|
126
|
+
cause,
|
|
127
|
+
request
|
|
128
|
+
}) })), fromResult);
|
|
129
|
+
const publicApi = urls.base.origin === apiBase && urls.base.pathname === "/";
|
|
130
|
+
const enterprise = `${urls.base.origin}${pipe(urls.base.pathname, replace(/\/+$/u, ""), replace(/\/api\/v3$/u, ""))}`;
|
|
131
|
+
if (urls.target.origin === "https://uploads.github.com") {
|
|
132
|
+
if (publicApi)
|
|
133
|
+
return request;
|
|
134
|
+
return updateUrl((url) => `${enterprise}/api/uploads${slice(26)(url)}`)(request);
|
|
135
|
+
}
|
|
136
|
+
if (urls.target.origin !== apiBase)
|
|
137
|
+
return request;
|
|
138
|
+
return updateUrl((url) => `${replace(/\/+$/u, "")(urls.base.href)}${slice(22)(url)}`)(request);
|
|
139
|
+
})));
|
|
140
|
+
}
|
|
141
|
+
var sandboxAccess2 = {
|
|
142
|
+
authorize: (request, context) => {
|
|
143
|
+
const binding = context.auth.current;
|
|
144
|
+
if (binding.methodId === "app")
|
|
145
|
+
return none();
|
|
146
|
+
return map(liftPredicate(request, (git) => Plugin_exports.isGitRequest(git) && match3(fromString(git.url), {
|
|
147
|
+
onFailure: () => false,
|
|
148
|
+
onSuccess: (url) => !startsWith("/api/")(url.pathname)
|
|
149
|
+
})), (git) => basicAuth(git, "x-access-token", token(binding)));
|
|
150
|
+
},
|
|
151
|
+
origins: (context) => context.auth.current.methodId === "app" ? [] : [webOrigin(context.auth.current.value.server)]
|
|
152
|
+
};
|
|
153
|
+
export { auth_exports2, authMethods2, authorize2, sandboxAccess2 };
|
|
154
|
+
|
|
155
|
+
//# debugId=35C88FF2FB231D0A64756E2164756E21
|
|
156
|
+
//# sourceMappingURL=plugin-r0m0v72b.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../bundle-input/dist/auth.js"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { __exportAll } from \"./_virtual/_rolldown/runtime.js\";\nimport { gitHubAppAuth } from \"./channel/github-app-definition.js\";\nimport \"./auth.js\";\nimport { Effect, Match, Option, Result, Schema, String, pipe } from \"effect\";\nimport { HttpClient, HttpClientError, HttpClientRequest, Url } from \"effect/http\";\nimport { AuthMethod, Plugin } from \"@dual-os/sdk\";\n//#region src/auth.ts\nvar auth_exports = /* @__PURE__ */ __exportAll({\n\tAuth: () => auth_exports,\n\tauthMethods: () => authMethods,\n\tauthorize: () => authorize,\n\tsandboxAccess: () => sandboxAccess\n});\nconst apiBase = \"https://api.github.com\";\nfunction webOrigin(server) {\n\tif (server === void 0 || server === \"\") return \"https://github.com\";\n\tconst origin = Result.match(Url.fromString(server), {\n\t\tonFailure: () => String.replace(/^(https?:\\/\\/[^/]+).*$/u, \"$1\")(server),\n\t\tonSuccess: (url) => url.origin\n\t});\n\treturn origin === apiBase ? \"https://github.com\" : origin;\n}\nconst authMethods = [...[AuthMethod.make(\"personal-access-token\", {\n\tdescription: \"Authenticate with a GitHub personal access token sent as a bearer token; set server for GitHub Enterprise Server\",\n\tname: \"GitHub personal access token\",\n\tschema: Schema.Struct({\n\t\tserver: Schema.optionalKey(Schema.String),\n\t\ttoken: Schema.NonEmptyString\n\t})\n}), AuthMethod.oauth2(\"oauth2\", {\n\tauthorizationUrl: (context) => `${webOrigin(context.setup.server)}/login/oauth/authorize`,\n\tclient: (options) => ({\n\t\tauthentication: \"post\",\n\t\tclientId: options.setup.clientId,\n\t\tclientSecret: options.setup.clientSecret\n\t}),\n\tdescription: \"Authenticate with a GitHub OAuth app; set server for GitHub Enterprise Server, whose OAuth endpoints are on the same host\",\n\tmaterial: AuthMethod.OAuth2TokenMaterial,\n\tname: \"GitHub OAuth app\",\n\tresolve: (material, context) => ({\n\t\taccessToken: material.accessToken,\n\t\tserver: context.setup.server\n\t}),\n\tscopes: [\n\t\t\"repo\",\n\t\t\"admin:repo_hook\",\n\t\t\"admin:org\",\n\t\t\"admin:org_hook\",\n\t\t\"gist\",\n\t\t\"notifications\",\n\t\t\"user\",\n\t\t\"write:packages\",\n\t\t\"read:packages\",\n\t\t\"delete:packages\",\n\t\t\"workflow\"\n\t],\n\tsetup: Schema.Struct({\n\t\tclientId: Schema.String,\n\t\tclientSecret: Schema.String,\n\t\tserver: Schema.optional(Schema.String)\n\t}),\n\ttokenUrl: (context) => `${webOrigin(context.setup.server)}/login/oauth/access_token`,\n\tvalue: Schema.Struct({\n\t\taccessToken: Schema.String,\n\t\tserver: Schema.optional(Schema.String)\n\t})\n})], gitHubAppAuth];\nfunction token(binding) {\n\treturn pipe(Match.value(binding), Match.discriminatorsExhaustive(\"methodId\")({\n\t\toauth2: (binding) => binding.value.accessToken,\n\t\t\"personal-access-token\": (binding) => binding.value.token\n\t}));\n}\nfunction authorize(client, context) {\n\tconst binding = context.auth.current;\n\tif (binding.methodId === \"app\") return HttpClient.mapRequestEffect(client, (request) => Effect.fail(new HttpClientError.HttpClientError({ reason: new HttpClientError.TransportError({\n\t\trequest,\n\t\tdescription: \"Use a personal access token or OAuth Connection for GitHub API Actions and Triggers; GitHub App credentials serve the Agent Channel.\"\n\t}) })));\n\tconst server = binding.value.server;\n\treturn pipe(client, HttpClient.mapRequest(HttpClientRequest.bearerToken(token(binding))), HttpClient.mapRequest(HttpClientRequest.setHeader(\"X-GitHub-Api-Version\", \"2022-11-28\")), HttpClient.mapRequestEffect(Effect.fnUntraced(function* (request) {\n\t\tif (server === void 0 || server === \"\") return request;\n\t\tconst urls = yield* pipe(Result.all({\n\t\t\tbase: Url.fromString(server),\n\t\t\ttarget: Url.fromString(request.url)\n\t\t}), Result.mapError((cause) => new HttpClientError.HttpClientError({ reason: new HttpClientError.InvalidUrlError({\n\t\t\tcause,\n\t\t\trequest\n\t\t}) })), Effect.fromResult);\n\t\tconst publicApi = urls.base.origin === apiBase && urls.base.pathname === \"/\";\n\t\tconst enterprise = `${urls.base.origin}${pipe(urls.base.pathname, String.replace(/\\/+$/u, \"\"), String.replace(/\\/api\\/v3$/u, \"\"))}`;\n\t\tif (urls.target.origin === \"https://uploads.github.com\") {\n\t\t\tif (publicApi) return request;\n\t\t\treturn HttpClientRequest.updateUrl((url) => `${enterprise}/api/uploads${String.slice(26)(url)}`)(request);\n\t\t}\n\t\tif (urls.target.origin !== apiBase) return request;\n\t\treturn HttpClientRequest.updateUrl((url) => `${String.replace(/\\/+$/u, \"\")(urls.base.href)}${String.slice(22)(url)}`)(request);\n\t})));\n}\nconst sandboxAccess = {\n\tauthorize: (request, context) => {\n\t\tconst binding = context.auth.current;\n\t\tif (binding.methodId === \"app\") return Option.none();\n\t\treturn Option.map(Option.liftPredicate(request, (git) => Plugin.isGitRequest(git) && Result.match(Url.fromString(git.url), {\n\t\t\tonFailure: () => false,\n\t\t\tonSuccess: (url) => !String.startsWith(\"/api/\")(url.pathname)\n\t\t})), (git) => HttpClientRequest.basicAuth(git, \"x-access-token\", token(binding)));\n\t},\n\torigins: (context) => context.auth.current.methodId === \"app\" ? [] : [webOrigin(context.auth.current.value.server)]\n};\n//#endregion\nexport { auth_exports as Auth, authMethods, auth_exports, authorize, sandboxAccess };\n\n//# sourceMappingURL=auth.js.map"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "35C88FF2FB231D0A64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|