diff --git a/oss-migration-guide/coffee-api/.DS_Store b/oss-migration-guide/coffee-api/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/oss-migration-guide/coffee-api/.DS_Store differ diff --git a/oss-migration-guide/coffee-api/main.py b/oss-migration-guide/coffee-api/main.py new file mode 100644 index 0000000..fffdb78 --- /dev/null +++ b/oss-migration-guide/coffee-api/main.py @@ -0,0 +1,329 @@ +from fastapi import FastAPI, HTTPException, Query, status +from pydantic import BaseModel, Field +from typing import List, Optional, Dict, Annotated +from enum import Enum + +app = FastAPI( + title="Coffee Orders API", + description="A CRUD API for managing coffee orders and available coffee types.", + version="1.0.0", + servers=[ + {"url": "http://localhost:8000", "description": "Development server"} + ] +) + +# --- Models --- + +class CoffeeOrder(BaseModel): + """ + Represents a coffee order in the system. + """ + id: int = Field( + ..., + example=1, + description="Unique identifier for the order" + ) + customer_name: str = Field( + ..., + example="Alice", + description="Name of the customer placing the order" + ) + coffee_type: str = Field( + ..., + example="Latte", + description="Type of coffee ordered (must match an existing coffee type)" + ) + size: str = Field( + ..., + example="Medium", + description="Size of the coffee order", + enum=["Small", "Medium", "Large"] + ) + extras: Optional[List[str]] = Field( + default=None, + example=["Extra shot", "Soy milk"], + description="Optional additions to the coffee order" + ) + price: float = Field( + ..., + example=4.50, + description="Total price of the order", + gt=0 + ) + + class Config: + schema_extra = { + "example": { + "id": 1, + "customer_name": "Alice", + "coffee_type": "Latte", + "size": "Medium", + "extras": ["Extra shot", "Soy milk"], + "price": 4.50 + } + } + +# Model for updating a coffee order (all fields optional) +class CoffeeOrderUpdate(BaseModel): + customer_name: Optional[str] = Field(None, example="Alice") + coffee_type: Optional[str] = Field(None, example="Cappuccino") + size: Optional[str] = Field(None, example="Large") + extras: Optional[List[str]] = Field(None, example=["Whipped cream"]) + price: Optional[float] = Field(None, example=5.00) + +class CoffeeType(BaseModel): + """ + Represents a type of coffee available in the system. + """ + id: int = Field( + ..., + example=1, + description="Unique identifier for the coffee type" + ) + name: str = Field( + ..., + example="Latte", + description="Name of the coffee type" + ) + description: Optional[str] = Field( + None, + example="A milk-based espresso coffee", + description="Detailed description of the coffee type" + ) + price_multiplier: Optional[float] = Field( + 1.0, + example=1.2, + description="Price multiplier for this coffee type", + gt=0, + le=5.0 + ) + + class Config: + schema_extra = { + "example": { + "id": 1, + "name": "Latte", + "description": "A milk-based espresso coffee", + "price_multiplier": 1.2 + } + } + +# --- In-memory "databases" --- + +orders_db = {} # key: order id, value: CoffeeOrder + +coffee_types_db = { + 1: CoffeeType(id=1, name="Espresso", description="Strong and bold coffee shot", price_multiplier=1.0), + 2: CoffeeType(id=2, name="Latte", description="Espresso with steamed milk", price_multiplier=1.2), + 3: CoffeeType(id=3, name="Cappuccino", description="Espresso with steamed milk foam", price_multiplier=1.1), + 4: CoffeeType(id=4, name="Americano", description="Espresso diluted with hot water", price_multiplier=1.0), +} + +# --- Endpoints for Coffee Orders --- +@app.get("/", response_model=str) +async def ReadRoot(): + """ + Welcome endpoint for the API. + """ + return "Welcome to the Coffee Orders API! 🚀" + + +@app.get("/orders", response_model=List[CoffeeOrder]) +async def GetOrders(coffee_type: Optional[str] = Query( + None, description="Optional filter by coffee type (case-insensitive)" +)): + """ + Retrieve all coffee orders. + If 'coffee_type' is provided, returns orders matching that coffee type. + + Parameters: + - **coffee_type**: Optional query parameter to filter orders by coffee type + + Returns: + - List of coffee orders matching the filter criteria or all orders if no filter is applied + """ + orders = list(orders_db.values()) + if coffee_type: + orders = [order for order in orders if order.coffee_type.lower() == coffee_type.lower()] + return orders + +@app.get("/orders/{order_id}", response_model=CoffeeOrder) +async def GetOrder(order_id: int): + """ + Retrieve a specific coffee order by its ID. + + Parameters: + - **order_id**: The ID of the order to retrieve + + Returns: + - The coffee order with the specified ID + + Raises: + - **404**: If the order with the specified ID is not found + """ + order = orders_db.get(order_id) + if not order: + raise HTTPException(status_code=404, detail="Order not found") + return order + +@app.post("/orders", response_model=CoffeeOrder, status_code=201) +async def CreateOrder(order: CoffeeOrder): + """ + Create a new coffee order. + + Parameters: + - **order**: The coffee order details including customer name, coffee type, size, and optional extras + + Returns: + - The created coffee order + + Raises: + - **400**: If the order ID already exists or if the coffee type is invalid + """ + if order.id in orders_db: + raise HTTPException( + status_code=400, + detail="Order with this ID already exists" + ) + + if not any(ct.name.lower() == order.coffee_type.lower() + for ct in coffee_types_db.values()): + raise HTTPException( + status_code=400, + detail="Invalid coffee type. Please choose a valid coffee type." + ) + + orders_db[order.id] = order + return order + +@app.put("/orders/{order_id}", response_model=CoffeeOrder) +async def UpdateOrder(order_id: int, order_update: CoffeeOrderUpdate): + """ + Update an existing coffee order. + + Parameters: + - **order_id**: The ID of the order to update + - **order_update**: The updated order information + + Returns: + - The updated coffee order + + Raises: + - **404**: If the order with the specified ID is not found + - **400**: If the coffee type provided is invalid + """ + stored_order = orders_db.get(order_id) + if not stored_order: + raise HTTPException(status_code=404, detail="Order not found") + updated_data = order_update.dict(exclude_unset=True) + if "coffee_type" in updated_data: + if not any(ct.name.lower() == updated_data["coffee_type"].lower() for ct in coffee_types_db.values()): + raise HTTPException(status_code=400, detail="Invalid coffee type. Please choose a valid coffee type.") + updated_order = stored_order.copy(update=updated_data) + orders_db[order_id] = updated_order + return updated_order + +@app.delete("/orders/{order_id}", status_code=204) +async def DeleteOrder(order_id: int): + """ + Delete a coffee order. + + Parameters: + - **order_id**: The ID of the order to delete + + Raises: + - **404**: If the order with the specified ID is not found + """ + if order_id not in orders_db: + raise HTTPException(status_code=404, detail="Order not found") + del orders_db[order_id] + +# --- Endpoints for Coffee Types --- + +@app.get("/coffee-types", response_model=List[CoffeeType]) +async def GetCoffeeTypes(): + """ + Retrieve all available coffee types. + + Returns: + - List of all available coffee types + """ + return list(coffee_types_db.values()) + +@app.get("/coffee-types/{type_id}", response_model=CoffeeType) +async def GetCoffeeType(type_id: int): + """ + Retrieve a specific coffee type by its ID. + + Parameters: + - **type_id**: The ID of the coffee type to retrieve + + Returns: + - The coffee type with the specified ID + + Raises: + - **404**: If the coffee type with the specified ID is not found + """ + coffee_type = coffee_types_db.get(type_id) + if not coffee_type: + raise HTTPException(status_code=404, detail="Coffee type not found") + return coffee_type + +@app.post("/coffee-types", response_model=CoffeeType, status_code=201) +async def CreateCoffeeType(coffee_type: CoffeeType): + """ + Create a new coffee type. + + Parameters: + - **coffee_type**: The coffee type details including name, description, and price multiplier + + Returns: + - The created coffee type + + Raises: + - **400**: If a coffee type with the specified ID already exists + """ + if coffee_type.id in coffee_types_db: + raise HTTPException(status_code=400, detail="Coffee type with this ID already exists") + coffee_types_db[coffee_type.id] = coffee_type + return coffee_type + +@app.put("/coffee-types/{type_id}", response_model=CoffeeType) +async def UpdateCoffeeType(type_id: int, updated_type: CoffeeType): + """ + Update an existing coffee type. + + Parameters: + - **type_id**: The ID of the coffee type to update + - **updated_type**: The updated coffee type information + + Returns: + - The updated coffee type + + Raises: + - **404**: If the coffee type with the specified ID is not found + """ + if type_id not in coffee_types_db: + raise HTTPException(status_code=404, detail="Coffee type not found") + coffee_types_db[type_id] = updated_type + return updated_type + +@app.delete("/coffee-types/{type_id}", status_code=204) +async def DeleteCoffeeType(type_id: int): + """ + Delete a coffee type. + + Parameters: + - **type_id**: The ID of the coffee type to delete + + Raises: + - **404**: If the coffee type with the specified ID is not found + """ + if type_id not in coffee_types_db: + raise HTTPException(status_code=404, detail="Coffee type not found") + del coffee_types_db[type_id] + +if __name__ == "__main__": + import uvicorn + uvicorn.run(app, host="0.0.0.0", port=8000) + diff --git a/oss-migration-guide/coffee-api/pyproject.toml b/oss-migration-guide/coffee-api/pyproject.toml new file mode 100644 index 0000000..0ced975 --- /dev/null +++ b/oss-migration-guide/coffee-api/pyproject.toml @@ -0,0 +1,10 @@ +[project] +name = "oss-migration-example" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "fastapi>=0.115.8", + "uvicorn>=0.34.0", +] diff --git a/oss-migration-guide/coffee-api/uv.lock b/oss-migration-guide/coffee-api/uv.lock new file mode 100644 index 0000000..a4b99fc --- /dev/null +++ b/oss-migration-guide/coffee-api/uv.lock @@ -0,0 +1,189 @@ +version = 1 +requires-python = ">=3.12" + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, +] + +[[package]] +name = "anyio" +version = "4.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, +] + +[[package]] +name = "click" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "fastapi" +version = "0.115.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a2/b2/5a5dc4affdb6661dea100324e19a7721d5dc524b464fe8e366c093fd7d87/fastapi-0.115.8.tar.gz", hash = "sha256:0ce9111231720190473e222cdf0f07f7206ad7e53ea02beb1d2dc36e2f0741e9", size = 295403 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/7d/2d6ce181d7a5f51dedb8c06206cbf0ec026a99bf145edd309f9e17c3282f/fastapi-0.115.8-py3-none-any.whl", hash = "sha256:753a96dd7e036b34eeef8babdfcfe3f28ff79648f86551eb36bfc1b0bf4a8cbf", size = 94814 }, +] + +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "oss-migration-example" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "fastapi" }, + { name = "uvicorn" }, +] + +[package.metadata] +requires-dist = [ + { name = "fastapi", specifier = ">=0.115.8" }, + { name = "uvicorn", specifier = ">=0.34.0" }, +] + +[[package]] +name = "pydantic" +version = "2.10.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, +] + +[[package]] +name = "pydantic-core" +version = "2.27.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, +] + +[[package]] +name = "starlette" +version = "0.45.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/fb/2984a686808b89a6781526129a4b51266f678b2d2b97ab2d325e56116df8/starlette-0.45.3.tar.gz", hash = "sha256:2cbcba2a75806f8a41c722141486f37c28e30a0921c5f6fe4346cb0dcee1302f", size = 2574076 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/61/f2b52e107b1fc8944b33ef56bf6ac4ebbe16d91b94d2b87ce013bf63fb84/starlette-0.45.3-py3-none-any.whl", hash = "sha256:dfb6d332576f136ec740296c7e8bb8c8a7125044e7c6da30744718880cdd059d", size = 71507 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "uvicorn" +version = "0.34.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 }, +] diff --git a/oss-migration-guide/openapi.yaml b/oss-migration-guide/openapi.yaml new file mode 100644 index 0000000..1d2d8a9 --- /dev/null +++ b/oss-migration-guide/openapi.yaml @@ -0,0 +1,690 @@ +openapi: 3.1.0 +info: + title: Coffee Orders API + version: 1.0.0 + description: A CRUD API for managing coffee orders and available coffee types. + license: + name: MIT + url: https://opensource.org/licenses/MIT +security: + - ApiKeyAuth: [] +servers: + - url: http://localhost:8000 + description: Development server +tags: + - name: Orders + description: Operations related to coffee orders + - name: CoffeeTypes + description: Operations related to coffee types +paths: + /orders: + get: + tags: + - Orders + summary: Get Orders + operationId: GetOrders + description: | + Retrieve all coffee orders. + If 'coffee_type' is provided, returns orders matching that coffee type. + parameters: + - examples: + latte: + summary: Filter Latte orders + value: Latte + espresso: + summary: Filter Espresso orders + value: Espresso + name: coffee_type + in: query + required: false + schema: + title: Coffee Type + description: Optional filter by coffee type (case-insensitive) + anyOf: + - type: string + - type: "null" + description: Optional filter by coffee type (case-insensitive) + responses: + 200: + description: Successful Response + content: + application/json: + examples: + multiple_orders: + summary: List of coffee orders + value: + - id: 1 + customer_name: Alice + coffee_type: Latte + size: Medium + extras: + - Extra shot + - Soy milk + price: 4.5 + - id: 2 + customer_name: Bob + coffee_type: Espresso + size: Small + extras: + - Extra shot + price: 3.5 + schema: + type: array + title: Response Get Orders Orders Get + items: + $ref: "#/components/schemas/CoffeeOrder" + 422: + description: Validation Error + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + x-speakeasy-group: orders + x-speakeasy-usage-example: true + post: + tags: + - Orders + summary: Create Order + operationId: CreateOrder + description: | + Create a new coffee order. + Validates that the coffee type exists. + requestBody: + required: true + content: + application/json: + examples: + simple_order: + summary: Basic coffee order + value: + id: 3 + customer_name: Charlie + coffee_type: Americano + size: Large + price: 3.75 + complex_order: + summary: Coffee order with extras + value: + id: 4 + customer_name: Diana + coffee_type: Cappuccino + size: Medium + extras: + - Whipped cream + - Caramel syrup + price: 5.25 + schema: + $ref: "#/components/schemas/CoffeeOrder" + responses: + 201: + description: Successful Response + content: + application/json: + schema: + $ref: "#/components/schemas/CoffeeOrder" + 400: + description: Bad Request - Invalid coffee type or duplicate ID + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + 422: + description: Validation Error + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + x-speakeasy-group: orders + x-speakeasy-usage-example: true + /orders/{order_id}: + parameters: + - examples: + order1: + summary: First order + value: 1 + order2: + summary: Second order + value: 2 + name: order_id + in: path + required: true + description: The ID of the order to operate on + schema: + type: integer + title: Order ID + minimum: 1 + get: + tags: + - Orders + summary: Get Order + operationId: GetOrder + description: Retrieve a specific coffee order by its ID. + responses: + 200: + description: Successful Response + content: + application/json: + schema: + $ref: "#/components/schemas/CoffeeOrder" + 404: + description: Order not found + content: + application/json: + examples: + not_found: + value: + detail: Order not found + schema: + $ref: "#/components/schemas/ErrorResponse" + 422: + description: Validation Error + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + x-speakeasy-group: orders + put: + tags: + - Orders + summary: Update Order + operationId: UpdateOrder + description: Update an existing coffee order. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CoffeeOrderUpdate" + responses: + 200: + description: Successful Response + content: + application/json: + schema: + $ref: "#/components/schemas/CoffeeOrder" + 404: + description: Order not found + content: + application/json: + examples: + not_found: + value: + detail: Order not found + schema: + $ref: "#/components/schemas/ErrorResponse" + 422: + description: Validation Error + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + x-speakeasy-group: orders + delete: + tags: + - Orders + summary: Delete Order + operationId: DeleteOrder + description: Delete a coffee order. + responses: + 204: + description: Order successfully deleted + 404: + description: Order not found + content: + application/json: + examples: + not_found: + value: + detail: Order not found + schema: + $ref: "#/components/schemas/ErrorResponse" + 422: + description: Validation Error + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + x-speakeasy-group: orders + /coffee-types: + get: + tags: + - CoffeeTypes + summary: Get Coffee Types + operationId: GetCoffeeTypes + description: Retrieve all available coffee types. + responses: + 200: + description: Successful Response + content: + application/json: + examples: + coffee_types: + summary: List of available coffee types + value: + - name: Espresso + description: Strong and bold coffee shot + id: 1 + price_multiplier: 1 + - name: Latte + description: Espresso with steamed milk + id: 2 + price_multiplier: 1.2 + - name: Mocha + description: Espresso with chocolate and steamed milk + id: 3 + price_multiplier: 1.3 + schema: + type: array + title: Response Get Coffee Types Coffee Types Get + items: + $ref: "#/components/schemas/CoffeeType" + x-speakeasy-group: coffeeTypes + post: + tags: + - CoffeeTypes + summary: Create Coffee Type + operationId: CreateCoffeeType + description: Create a new coffee type. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CoffeeType" + responses: + 201: + description: Successful Response + content: + application/json: + schema: + $ref: "#/components/schemas/CoffeeType" + 400: + description: Bad Request - Duplicate ID + content: + application/json: + examples: + duplicate_id: + value: + detail: Coffee type with this ID already exists + schema: + $ref: "#/components/schemas/ErrorResponse" + 422: + description: Validation Error + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + x-speakeasy-group: coffeeTypes + /coffee-types/{type_id}: + parameters: + - examples: + espresso: + summary: Espresso type ID + value: 1 + latte: + summary: Latte type ID + value: 2 + name: type_id + in: path + required: true + description: The ID of the coffee type to operate on + schema: + type: integer + title: Type ID + minimum: 1 + get: + tags: + - CoffeeTypes + summary: Get Coffee Type + operationId: GetCoffeeType + description: Retrieve a specific coffee type by its ID. + responses: + 200: + description: Successful Response + content: + application/json: + schema: + $ref: "#/components/schemas/CoffeeType" + 404: + description: Coffee type not found + content: + application/json: + examples: + not_found: + value: + detail: Coffee type not found + schema: + $ref: "#/components/schemas/ErrorResponse" + 422: + description: Validation Error + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + x-speakeasy-group: coffeeTypes + put: + tags: + - CoffeeTypes + summary: Update Coffee Type + operationId: UpdateCoffeeType + description: Update an existing coffee type. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CoffeeType" + responses: + 200: + description: Successful Response + content: + application/json: + schema: + $ref: "#/components/schemas/CoffeeType" + 404: + description: Coffee type not found + content: + application/json: + examples: + not_found: + value: + detail: Coffee type not found + schema: + $ref: "#/components/schemas/ErrorResponse" + 422: + description: Validation Error + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + x-speakeasy-group: coffeeTypes + delete: + tags: + - CoffeeTypes + summary: Delete Coffee Type + operationId: DeleteCoffeeType + description: Delete a coffee type. + responses: + 204: + description: Coffee type successfully deleted + 404: + description: Coffee type not found + content: + application/json: + examples: + not_found: + value: + detail: Coffee type not found + schema: + $ref: "#/components/schemas/ErrorResponse" + 422: + description: Validation Error + content: + application/json: + schema: + $ref: "#/components/schemas/HTTPValidationError" + x-speakeasy-group: coffeeTypes +components: + schemas: + CoffeeOrder: + examples: + - id: 5 + customer_name: Eve + coffee_type: Mocha + size: Large + extras: + - Whipped cream + - Chocolate syrup + price: 6 + - id: 6 + customer_name: Grace + coffee_type: Cold Brew + size: Medium + extras: + - Vanilla syrup + price: 5.5 + properties: + id: + type: integer + title: Id + description: Unique identifier for the order + example: 1 + customer_name: + type: string + title: Customer Name + description: Name of the customer placing the order + example: Alice + coffee_type: + type: string + title: Coffee Type + description: Type of coffee ordered (must match an existing coffee type) + example: Latte + size: + type: string + title: Size + description: Size of the coffee order + enum: + - Small + - Medium + - Large + example: Medium + extras: + title: Extras + description: Optional additions to the coffee order + anyOf: + - type: array + items: + type: string + - type: "null" + example: + - Extra shot + - Soy milk + price: + type: number + title: Price + description: Total price of the order + minimum: 0.01 + example: 4.5 + type: object + required: + - id + - customer_name + - coffee_type + - size + - price + title: CoffeeOrder + description: Represents a coffee order in the system + x-speakeasy-entity: true + CoffeeOrderUpdate: + examples: + - customer_name: Frank + size: Small + extras: + - Sugar-free syrup + - coffee_type: Cappuccino + extras: + - Cinnamon + - Whipped cream + price: 5.75 + properties: + customer_name: + title: Customer Name + description: Updated customer name + anyOf: + - type: string + - type: "null" + example: Alice + coffee_type: + title: Coffee Type + description: Updated coffee type (must match an existing coffee type) + anyOf: + - type: string + - type: "null" + example: Cappuccino + size: + title: Size + description: Updated size of the coffee order + anyOf: + - type: string + - type: "null" + example: Large + enum: + - Small + - Medium + - Large + extras: + title: Extras + description: Updated optional additions to the coffee order + anyOf: + - type: array + items: + type: string + - type: "null" + example: + - Whipped cream + price: + title: Price + description: Updated total price of the order + anyOf: + - type: number + - type: "null" + example: 5 + minimum: 0.01 + type: object + title: CoffeeOrderUpdate + description: Model for updating an existing coffee order (all fields optional) + CoffeeType: + examples: + - name: Cold Brew + description: Smooth, cold-steeped coffee + id: 4 + price_multiplier: 1.4 + - name: Flat White + description: Espresso with steamed whole milk + id: 5 + price_multiplier: 1.25 + properties: + name: + type: string + title: Name + description: Name of the coffee type + example: Latte + description: + title: Description + description: Detailed description of the coffee type + anyOf: + - type: string + - type: "null" + example: A milk-based espresso coffee + id: + type: integer + title: Id + description: Unique identifier for the coffee type + example: 1 + price_multiplier: + title: Price Multiplier + description: Price multiplier for this coffee type + anyOf: + - type: number + - type: "null" + default: 1 + example: 1.2 + minimum: 0.1 + maximum: 5.0 + type: object + required: + - id + - name + title: CoffeeType + description: Represents a type of coffee available in the system + x-speakeasy-entity: true + ErrorResponse: + type: object + title: ErrorResponse + description: Standard error response format + required: + - detail + properties: + detail: + type: string + description: Error detail message + HTTPValidationError: + examples: + - detail: + - type: value_error + loc: + - body + - coffee_type + msg: Invalid coffee type specified + properties: + detail: + type: array + title: Detail + description: List of validation errors + items: + $ref: "#/components/schemas/ValidationError" + type: object + title: HTTPValidationError + description: Error thrown when request validation fails + ValidationError: + examples: + - type: value_error.number.not_gt + loc: + - body + - price + msg: Price must be greater than 0 + properties: + type: + type: string + title: Error Type + description: Type of error + loc: + type: array + title: Location + description: Location of the error in the request + items: + anyOf: + - type: string + - type: integer + msg: + type: string + title: Message + description: Error message + type: object + required: + - loc + - msg + - type + title: ValidationError + description: Detailed information about a validation error + securitySchemes: + ApiKeyAuth: + name: X-API-Key + type: apiKey + description: API key for authentication + in: header + x-speakeasy-example: "your-api-key-here" +x-speakeasy-name-override: + - operationId: ^GetOrder$ + methodNameOverride: getById + - operationId: ^GetOrders$ + methodNameOverride: list + - operationId: ^GetCoffeeType$ + methodNameOverride: getById + - operationId: ^GetCoffeeTypes$ + methodNameOverride: list + - operationId: ^Create(.*) + methodNameOverride: create + - operationId: ^Update(.*) + methodNameOverride: update + - operationId: ^Delete(.*) + methodNameOverride: delete +x-speakeasy-metadata: + sdk: + typescript: + packageName: coffee-api + packageVersion: 1.0.0 + clientName: CoffeeAPI + features: + nativeErrors: true + cacheControl: true diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/.gitignore b/oss-migration-guide/sdks/oss-coffee-client-typescript/.gitignore new file mode 100644 index 0000000..149b576 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/.gitignore @@ -0,0 +1,4 @@ +wwwroot/*.js +node_modules +typings +dist diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/.openapi-generator-ignore b/oss-migration-guide/sdks/oss-coffee-client-typescript/.openapi-generator-ignore new file mode 100644 index 0000000..7484ee5 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/.openapi-generator/FILES b/oss-migration-guide/sdks/oss-coffee-client-typescript/.openapi-generator/FILES new file mode 100644 index 0000000..dd202bc --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/.openapi-generator/FILES @@ -0,0 +1,17 @@ +.gitignore +.openapi-generator-ignore +api.ts +api/apis.ts +api/coffeeTypesApi.ts +api/ordersApi.ts +git_push.sh +model/coffeeOrder.ts +model/coffeeOrderUpdate.ts +model/coffeeType.ts +model/errorResponse.ts +model/hTTPValidationError.ts +model/models.ts +model/validationError.ts +model/validationErrorLocInner.ts +package.json +tsconfig.json diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/.openapi-generator/VERSION b/oss-migration-guide/sdks/oss-coffee-client-typescript/.openapi-generator/VERSION new file mode 100644 index 0000000..b23eb27 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.11.0 diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/api.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/api.ts new file mode 100644 index 0000000..b1119f1 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/api.ts @@ -0,0 +1,3 @@ +// This is the entrypoint for the package +export * from './api/apis'; +export * from './model/models'; diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/api/apis.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/api/apis.ts new file mode 100644 index 0000000..65e3082 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/api/apis.ts @@ -0,0 +1,16 @@ +export * from './coffeeTypesApi'; +import { CoffeeTypesApi } from './coffeeTypesApi'; +export * from './ordersApi'; +import { OrdersApi } from './ordersApi'; +import * as http from 'http'; + +export class HttpError extends Error { + constructor(public response: http.IncomingMessage, public body: any, public statusCode?: number) { + super('HTTP request failed'); + this.name = 'HttpError'; + } +} + +export { RequestFile } from '../model/models'; + +export const APIS = [CoffeeTypesApi, OrdersApi]; diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/api/coffeeTypesApi.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/api/coffeeTypesApi.ts new file mode 100644 index 0000000..7513de4 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/api/coffeeTypesApi.ts @@ -0,0 +1,453 @@ +/** + * Coffee Orders API + * A CRUD API for managing coffee orders and available coffee types. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import localVarRequest from 'request'; +import http from 'http'; + +/* tslint:disable:no-unused-locals */ +import { CoffeeType } from '../model/coffeeType'; +import { ErrorResponse } from '../model/errorResponse'; +import { HTTPValidationError } from '../model/hTTPValidationError'; + +import { ObjectSerializer, Authentication, VoidAuth, Interceptor } from '../model/models'; +import { HttpBasicAuth, HttpBearerAuth, ApiKeyAuth, OAuth } from '../model/models'; + +import { HttpError, RequestFile } from './apis'; + +let defaultBasePath = 'http://localhost:8000'; + +// =============================================== +// This file is autogenerated - Please do not edit +// =============================================== + +export enum CoffeeTypesApiApiKeys { + ApiKeyAuth, +} + +export class CoffeeTypesApi { + protected _basePath = defaultBasePath; + protected _defaultHeaders : any = {}; + protected _useQuerystring : boolean = false; + + protected authentications = { + 'default': new VoidAuth(), + 'ApiKeyAuth': new ApiKeyAuth('header', 'X-API-Key'), + } + + protected interceptors: Interceptor[] = []; + + constructor(basePath?: string); + constructor(basePathOrUsername: string, password?: string, basePath?: string) { + if (password) { + if (basePath) { + this.basePath = basePath; + } + } else { + if (basePathOrUsername) { + this.basePath = basePathOrUsername + } + } + } + + set useQuerystring(value: boolean) { + this._useQuerystring = value; + } + + set basePath(basePath: string) { + this._basePath = basePath; + } + + set defaultHeaders(defaultHeaders: any) { + this._defaultHeaders = defaultHeaders; + } + + get defaultHeaders() { + return this._defaultHeaders; + } + + get basePath() { + return this._basePath; + } + + public setDefaultAuthentication(auth: Authentication) { + this.authentications.default = auth; + } + + public setApiKey(key: CoffeeTypesApiApiKeys, value: string) { + (this.authentications as any)[CoffeeTypesApiApiKeys[key]].apiKey = value; + } + + public addInterceptor(interceptor: Interceptor) { + this.interceptors.push(interceptor); + } + + /** + * Create a new coffee type. + * @summary Create Coffee Type + * @param coffeeType + */ + public async createCoffeeType (coffeeType: CoffeeType, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body: CoffeeType; }> { + const localVarPath = this.basePath + '/coffee-types'; + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + // verify required parameter 'coffeeType' is not null or undefined + if (coffeeType === null || coffeeType === undefined) { + throw new Error('Required parameter coffeeType was null or undefined when calling createCoffeeType.'); + } + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'POST', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + body: ObjectSerializer.serialize(coffeeType, "CoffeeType") + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body: CoffeeType; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + body = ObjectSerializer.deserialize(body, "CoffeeType"); + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } + /** + * Delete a coffee type. + * @summary Delete Coffee Type + * @param typeId The ID of the coffee type to operate on + */ + public async deleteCoffeeType (typeId: number, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body?: any; }> { + const localVarPath = this.basePath + '/coffee-types/{type_id}' + .replace('{' + 'type_id' + '}', encodeURIComponent(String(typeId))); + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + // verify required parameter 'typeId' is not null or undefined + if (typeId === null || typeId === undefined) { + throw new Error('Required parameter typeId was null or undefined when calling deleteCoffeeType.'); + } + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'DELETE', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } + /** + * Retrieve a specific coffee type by its ID. + * @summary Get Coffee Type + * @param typeId The ID of the coffee type to operate on + */ + public async getCoffeeType (typeId: number, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body: CoffeeType; }> { + const localVarPath = this.basePath + '/coffee-types/{type_id}' + .replace('{' + 'type_id' + '}', encodeURIComponent(String(typeId))); + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + // verify required parameter 'typeId' is not null or undefined + if (typeId === null || typeId === undefined) { + throw new Error('Required parameter typeId was null or undefined when calling getCoffeeType.'); + } + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'GET', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body: CoffeeType; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + body = ObjectSerializer.deserialize(body, "CoffeeType"); + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } + /** + * Retrieve all available coffee types. + * @summary Get Coffee Types + */ + public async getCoffeeTypes (options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body: Array; }> { + const localVarPath = this.basePath + '/coffee-types'; + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'GET', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body: Array; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + body = ObjectSerializer.deserialize(body, "Array"); + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } + /** + * Update an existing coffee type. + * @summary Update Coffee Type + * @param typeId The ID of the coffee type to operate on + * @param coffeeType + */ + public async updateCoffeeType (typeId: number, coffeeType: CoffeeType, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body: CoffeeType; }> { + const localVarPath = this.basePath + '/coffee-types/{type_id}' + .replace('{' + 'type_id' + '}', encodeURIComponent(String(typeId))); + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + // verify required parameter 'typeId' is not null or undefined + if (typeId === null || typeId === undefined) { + throw new Error('Required parameter typeId was null or undefined when calling updateCoffeeType.'); + } + + // verify required parameter 'coffeeType' is not null or undefined + if (coffeeType === null || coffeeType === undefined) { + throw new Error('Required parameter coffeeType was null or undefined when calling updateCoffeeType.'); + } + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'PUT', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + body: ObjectSerializer.serialize(coffeeType, "CoffeeType") + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body: CoffeeType; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + body = ObjectSerializer.deserialize(body, "CoffeeType"); + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } +} diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/api/ordersApi.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/api/ordersApi.ts new file mode 100644 index 0000000..b1d0b9a --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/api/ordersApi.ts @@ -0,0 +1,459 @@ +/** + * Coffee Orders API + * A CRUD API for managing coffee orders and available coffee types. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import localVarRequest from 'request'; +import http from 'http'; + +/* tslint:disable:no-unused-locals */ +import { CoffeeOrder } from '../model/coffeeOrder'; +import { CoffeeOrderUpdate } from '../model/coffeeOrderUpdate'; +import { ErrorResponse } from '../model/errorResponse'; +import { HTTPValidationError } from '../model/hTTPValidationError'; + +import { ObjectSerializer, Authentication, VoidAuth, Interceptor } from '../model/models'; +import { HttpBasicAuth, HttpBearerAuth, ApiKeyAuth, OAuth } from '../model/models'; + +import { HttpError, RequestFile } from './apis'; + +let defaultBasePath = 'http://localhost:8000'; + +// =============================================== +// This file is autogenerated - Please do not edit +// =============================================== + +export enum OrdersApiApiKeys { + ApiKeyAuth, +} + +export class OrdersApi { + protected _basePath = defaultBasePath; + protected _defaultHeaders : any = {}; + protected _useQuerystring : boolean = false; + + protected authentications = { + 'default': new VoidAuth(), + 'ApiKeyAuth': new ApiKeyAuth('header', 'X-API-Key'), + } + + protected interceptors: Interceptor[] = []; + + constructor(basePath?: string); + constructor(basePathOrUsername: string, password?: string, basePath?: string) { + if (password) { + if (basePath) { + this.basePath = basePath; + } + } else { + if (basePathOrUsername) { + this.basePath = basePathOrUsername + } + } + } + + set useQuerystring(value: boolean) { + this._useQuerystring = value; + } + + set basePath(basePath: string) { + this._basePath = basePath; + } + + set defaultHeaders(defaultHeaders: any) { + this._defaultHeaders = defaultHeaders; + } + + get defaultHeaders() { + return this._defaultHeaders; + } + + get basePath() { + return this._basePath; + } + + public setDefaultAuthentication(auth: Authentication) { + this.authentications.default = auth; + } + + public setApiKey(key: OrdersApiApiKeys, value: string) { + (this.authentications as any)[OrdersApiApiKeys[key]].apiKey = value; + } + + public addInterceptor(interceptor: Interceptor) { + this.interceptors.push(interceptor); + } + + /** + * Create a new coffee order. Validates that the coffee type exists. + * @summary Create Order + * @param coffeeOrder + */ + public async createOrder (coffeeOrder: CoffeeOrder, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body: CoffeeOrder; }> { + const localVarPath = this.basePath + '/orders'; + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + // verify required parameter 'coffeeOrder' is not null or undefined + if (coffeeOrder === null || coffeeOrder === undefined) { + throw new Error('Required parameter coffeeOrder was null or undefined when calling createOrder.'); + } + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'POST', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + body: ObjectSerializer.serialize(coffeeOrder, "CoffeeOrder") + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body: CoffeeOrder; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + body = ObjectSerializer.deserialize(body, "CoffeeOrder"); + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } + /** + * Delete a coffee order. + * @summary Delete Order + * @param orderId The ID of the order to operate on + */ + public async deleteOrder (orderId: number, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body?: any; }> { + const localVarPath = this.basePath + '/orders/{order_id}' + .replace('{' + 'order_id' + '}', encodeURIComponent(String(orderId))); + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + // verify required parameter 'orderId' is not null or undefined + if (orderId === null || orderId === undefined) { + throw new Error('Required parameter orderId was null or undefined when calling deleteOrder.'); + } + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'DELETE', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body?: any; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } + /** + * Retrieve a specific coffee order by its ID. + * @summary Get Order + * @param orderId The ID of the order to operate on + */ + public async getOrder (orderId: number, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body: CoffeeOrder; }> { + const localVarPath = this.basePath + '/orders/{order_id}' + .replace('{' + 'order_id' + '}', encodeURIComponent(String(orderId))); + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + // verify required parameter 'orderId' is not null or undefined + if (orderId === null || orderId === undefined) { + throw new Error('Required parameter orderId was null or undefined when calling getOrder.'); + } + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'GET', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body: CoffeeOrder; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + body = ObjectSerializer.deserialize(body, "CoffeeOrder"); + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } + /** + * Retrieve all coffee orders. If \'coffee_type\' is provided, returns orders matching that coffee type. + * @summary Get Orders + * @param coffeeType Optional filter by coffee type (case-insensitive) + */ + public async getOrders (coffeeType?: string, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body: Array; }> { + const localVarPath = this.basePath + '/orders'; + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + if (coffeeType !== undefined) { + localVarQueryParameters['coffee_type'] = ObjectSerializer.serialize(coffeeType, "string"); + } + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'GET', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body: Array; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + body = ObjectSerializer.deserialize(body, "Array"); + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } + /** + * Update an existing coffee order. + * @summary Update Order + * @param orderId The ID of the order to operate on + * @param coffeeOrderUpdate + */ + public async updateOrder (orderId: number, coffeeOrderUpdate: CoffeeOrderUpdate, options: {headers: {[name: string]: string}} = {headers: {}}) : Promise<{ response: http.IncomingMessage; body: CoffeeOrder; }> { + const localVarPath = this.basePath + '/orders/{order_id}' + .replace('{' + 'order_id' + '}', encodeURIComponent(String(orderId))); + let localVarQueryParameters: any = {}; + let localVarHeaderParams: any = (Object).assign({}, this._defaultHeaders); + const produces = ['application/json']; + // give precedence to 'application/json' + if (produces.indexOf('application/json') >= 0) { + localVarHeaderParams.Accept = 'application/json'; + } else { + localVarHeaderParams.Accept = produces.join(','); + } + let localVarFormParams: any = {}; + + // verify required parameter 'orderId' is not null or undefined + if (orderId === null || orderId === undefined) { + throw new Error('Required parameter orderId was null or undefined when calling updateOrder.'); + } + + // verify required parameter 'coffeeOrderUpdate' is not null or undefined + if (coffeeOrderUpdate === null || coffeeOrderUpdate === undefined) { + throw new Error('Required parameter coffeeOrderUpdate was null or undefined when calling updateOrder.'); + } + + (Object).assign(localVarHeaderParams, options.headers); + + let localVarUseFormData = false; + + let localVarRequestOptions: localVarRequest.Options = { + method: 'PUT', + qs: localVarQueryParameters, + headers: localVarHeaderParams, + uri: localVarPath, + useQuerystring: this._useQuerystring, + json: true, + body: ObjectSerializer.serialize(coffeeOrderUpdate, "CoffeeOrderUpdate") + }; + + let authenticationPromise = Promise.resolve(); + if (this.authentications.ApiKeyAuth.apiKey) { + authenticationPromise = authenticationPromise.then(() => this.authentications.ApiKeyAuth.applyToRequest(localVarRequestOptions)); + } + authenticationPromise = authenticationPromise.then(() => this.authentications.default.applyToRequest(localVarRequestOptions)); + + let interceptorPromise = authenticationPromise; + for (const interceptor of this.interceptors) { + interceptorPromise = interceptorPromise.then(() => interceptor(localVarRequestOptions)); + } + + return interceptorPromise.then(() => { + if (Object.keys(localVarFormParams).length) { + if (localVarUseFormData) { + (localVarRequestOptions).formData = localVarFormParams; + } else { + localVarRequestOptions.form = localVarFormParams; + } + } + return new Promise<{ response: http.IncomingMessage; body: CoffeeOrder; }>((resolve, reject) => { + localVarRequest(localVarRequestOptions, (error, response, body) => { + if (error) { + reject(error); + } else { + if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) { + body = ObjectSerializer.deserialize(body, "CoffeeOrder"); + resolve({ response: response, body: body }); + } else { + reject(new HttpError(response, body, response.statusCode)); + } + } + }); + }); + }); + } +} diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/git_push.sh b/oss-migration-guide/sdks/oss-coffee-client-typescript/git_push.sh new file mode 100644 index 0000000..f53a75d --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/git_push.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="github.com" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/model/coffeeOrder.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/coffeeOrder.ts new file mode 100644 index 0000000..547d99a --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/coffeeOrder.ts @@ -0,0 +1,86 @@ +/** + * Coffee Orders API + * A CRUD API for managing coffee orders and available coffee types. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { RequestFile } from './models'; + +/** +* Represents a coffee order in the system +*/ +export class CoffeeOrder { + /** + * Unique identifier for the order + */ + 'id': number; + /** + * Name of the customer placing the order + */ + 'customerName': string; + /** + * Type of coffee ordered (must match an existing coffee type) + */ + 'coffeeType': string; + /** + * Size of the coffee order + */ + 'size': CoffeeOrder.SizeEnum; + 'extras'?: Array | null; + /** + * Total price of the order + */ + 'price': number; + + static discriminator: string | undefined = undefined; + + static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [ + { + "name": "id", + "baseName": "id", + "type": "number" + }, + { + "name": "customerName", + "baseName": "customer_name", + "type": "string" + }, + { + "name": "coffeeType", + "baseName": "coffee_type", + "type": "string" + }, + { + "name": "size", + "baseName": "size", + "type": "CoffeeOrder.SizeEnum" + }, + { + "name": "extras", + "baseName": "extras", + "type": "Array" + }, + { + "name": "price", + "baseName": "price", + "type": "number" + } ]; + + static getAttributeTypeMap() { + return CoffeeOrder.attributeTypeMap; + } +} + +export namespace CoffeeOrder { + export enum SizeEnum { + Small = 'Small', + Medium = 'Medium', + Large = 'Large' + } +} diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/model/coffeeOrderUpdate.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/coffeeOrderUpdate.ts new file mode 100644 index 0000000..bf51c92 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/coffeeOrderUpdate.ts @@ -0,0 +1,58 @@ +/** + * Coffee Orders API + * A CRUD API for managing coffee orders and available coffee types. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { RequestFile } from './models'; + +/** +* Model for updating an existing coffee order (all fields optional) +*/ +export class CoffeeOrderUpdate { + 'customerName'?: string | null; + 'coffeeType'?: string | null; + 'size'?: string | null; + 'extras'?: Array | null; + 'price'?: number | null; + + static discriminator: string | undefined = undefined; + + static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [ + { + "name": "customerName", + "baseName": "customer_name", + "type": "string" + }, + { + "name": "coffeeType", + "baseName": "coffee_type", + "type": "string" + }, + { + "name": "size", + "baseName": "size", + "type": "string" + }, + { + "name": "extras", + "baseName": "extras", + "type": "Array" + }, + { + "name": "price", + "baseName": "price", + "type": "number" + } ]; + + static getAttributeTypeMap() { + return CoffeeOrderUpdate.attributeTypeMap; + } +} + diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/model/coffeeType.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/coffeeType.ts new file mode 100644 index 0000000..10ea1ad --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/coffeeType.ts @@ -0,0 +1,58 @@ +/** + * Coffee Orders API + * A CRUD API for managing coffee orders and available coffee types. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { RequestFile } from './models'; + +/** +* Represents a type of coffee available in the system +*/ +export class CoffeeType { + /** + * Name of the coffee type + */ + 'name': string; + 'description'?: string | null; + /** + * Unique identifier for the coffee type + */ + 'id': number; + 'priceMultiplier'?: number | null; + + static discriminator: string | undefined = undefined; + + static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [ + { + "name": "name", + "baseName": "name", + "type": "string" + }, + { + "name": "description", + "baseName": "description", + "type": "string" + }, + { + "name": "id", + "baseName": "id", + "type": "number" + }, + { + "name": "priceMultiplier", + "baseName": "price_multiplier", + "type": "number" + } ]; + + static getAttributeTypeMap() { + return CoffeeType.attributeTypeMap; + } +} + diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/model/errorResponse.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/errorResponse.ts new file mode 100644 index 0000000..d705417 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/errorResponse.ts @@ -0,0 +1,37 @@ +/** + * Coffee Orders API + * A CRUD API for managing coffee orders and available coffee types. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { RequestFile } from './models'; + +/** +* Standard error response format +*/ +export class ErrorResponse { + /** + * Error detail message + */ + 'detail': string; + + static discriminator: string | undefined = undefined; + + static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [ + { + "name": "detail", + "baseName": "detail", + "type": "string" + } ]; + + static getAttributeTypeMap() { + return ErrorResponse.attributeTypeMap; + } +} + diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/model/hTTPValidationError.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/hTTPValidationError.ts new file mode 100644 index 0000000..b0e8e5d --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/hTTPValidationError.ts @@ -0,0 +1,38 @@ +/** + * Coffee Orders API + * A CRUD API for managing coffee orders and available coffee types. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { RequestFile } from './models'; +import { ValidationError } from './validationError'; + +/** +* Error thrown when request validation fails +*/ +export class HTTPValidationError { + /** + * List of validation errors + */ + 'detail'?: Array; + + static discriminator: string | undefined = undefined; + + static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [ + { + "name": "detail", + "baseName": "detail", + "type": "Array" + } ]; + + static getAttributeTypeMap() { + return HTTPValidationError.attributeTypeMap; + } +} + diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/model/models.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/models.ts new file mode 100644 index 0000000..2fb4791 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/models.ts @@ -0,0 +1,288 @@ +import localVarRequest from 'request'; + +export * from './coffeeOrder'; +export * from './coffeeOrderUpdate'; +export * from './coffeeType'; +export * from './errorResponse'; +export * from './hTTPValidationError'; +export * from './validationError'; +export * from './validationErrorLocInner'; + +import * as fs from 'fs'; + +export interface RequestDetailedFile { + value: Buffer; + options?: { + filename?: string; + contentType?: string; + } +} + +export type RequestFile = string | Buffer | fs.ReadStream | RequestDetailedFile; + + +import { CoffeeOrder } from './coffeeOrder'; +import { CoffeeOrderUpdate } from './coffeeOrderUpdate'; +import { CoffeeType } from './coffeeType'; +import { ErrorResponse } from './errorResponse'; +import { HTTPValidationError } from './hTTPValidationError'; +import { ValidationError } from './validationError'; +import { ValidationErrorLocInner } from './validationErrorLocInner'; + +/* tslint:disable:no-unused-variable */ +let primitives = [ + "string", + "boolean", + "double", + "integer", + "long", + "float", + "number", + "any" + ]; + +let enumsMap: {[index: string]: any} = { + "CoffeeOrder.SizeEnum": CoffeeOrder.SizeEnum, +} + +let typeMap: {[index: string]: any} = { + "CoffeeOrder": CoffeeOrder, + "CoffeeOrderUpdate": CoffeeOrderUpdate, + "CoffeeType": CoffeeType, + "ErrorResponse": ErrorResponse, + "HTTPValidationError": HTTPValidationError, + "ValidationError": ValidationError, + "ValidationErrorLocInner": ValidationErrorLocInner, +} + +// Check if a string starts with another string without using es6 features +function startsWith(str: string, match: string): boolean { + return str.substring(0, match.length) === match; +} + +// Check if a string ends with another string without using es6 features +function endsWith(str: string, match: string): boolean { + return str.length >= match.length && str.substring(str.length - match.length) === match; +} + +const nullableSuffix = " | null"; +const optionalSuffix = " | undefined"; +const arrayPrefix = "Array<"; +const arraySuffix = ">"; +const mapPrefix = "{ [key: string]: "; +const mapSuffix = "; }"; + +export class ObjectSerializer { + public static findCorrectType(data: any, expectedType: string) { + if (data == undefined) { + return expectedType; + } else if (primitives.indexOf(expectedType.toLowerCase()) !== -1) { + return expectedType; + } else if (expectedType === "Date") { + return expectedType; + } else { + if (enumsMap[expectedType]) { + return expectedType; + } + + if (!typeMap[expectedType]) { + return expectedType; // w/e we don't know the type + } + + // Check the discriminator + let discriminatorProperty = typeMap[expectedType].discriminator; + if (discriminatorProperty == null) { + return expectedType; // the type does not have a discriminator. use it. + } else { + if (data[discriminatorProperty]) { + var discriminatorType = data[discriminatorProperty]; + if(typeMap[discriminatorType]){ + return discriminatorType; // use the type given in the discriminator + } else { + return expectedType; // discriminator did not map to a type + } + } else { + return expectedType; // discriminator was not present (or an empty string) + } + } + } + } + + public static serialize(data: any, type: string): any { + if (data == undefined) { + return data; + } else if (primitives.indexOf(type.toLowerCase()) !== -1) { + return data; + } else if (endsWith(type, nullableSuffix)) { + let subType: string = type.slice(0, -nullableSuffix.length); // Type | null => Type + return ObjectSerializer.serialize(data, subType); + } else if (endsWith(type, optionalSuffix)) { + let subType: string = type.slice(0, -optionalSuffix.length); // Type | undefined => Type + return ObjectSerializer.serialize(data, subType); + } else if (startsWith(type, arrayPrefix)) { + let subType: string = type.slice(arrayPrefix.length, -arraySuffix.length); // Array => Type + let transformedData: any[] = []; + for (let index = 0; index < data.length; index++) { + let datum = data[index]; + transformedData.push(ObjectSerializer.serialize(datum, subType)); + } + return transformedData; + } else if (startsWith(type, mapPrefix)) { + let subType: string = type.slice(mapPrefix.length, -mapSuffix.length); // { [key: string]: Type; } => Type + let transformedData: { [key: string]: any } = {}; + for (let key in data) { + transformedData[key] = ObjectSerializer.serialize( + data[key], + subType, + ); + } + return transformedData; + } else if (type === "Date") { + return data.toISOString(); + } else { + if (enumsMap[type]) { + return data; + } + if (!typeMap[type]) { // in case we dont know the type + return data; + } + + // Get the actual type of this object + type = this.findCorrectType(data, type); + + // get the map for the correct type. + let attributeTypes = typeMap[type].getAttributeTypeMap(); + let instance: {[index: string]: any} = {}; + for (let index = 0; index < attributeTypes.length; index++) { + let attributeType = attributeTypes[index]; + instance[attributeType.baseName] = ObjectSerializer.serialize(data[attributeType.name], attributeType.type); + } + return instance; + } + } + + public static deserialize(data: any, type: string): any { + // polymorphism may change the actual type. + type = ObjectSerializer.findCorrectType(data, type); + if (data == undefined) { + return data; + } else if (primitives.indexOf(type.toLowerCase()) !== -1) { + return data; + } else if (endsWith(type, nullableSuffix)) { + let subType: string = type.slice(0, -nullableSuffix.length); // Type | null => Type + return ObjectSerializer.deserialize(data, subType); + } else if (endsWith(type, optionalSuffix)) { + let subType: string = type.slice(0, -optionalSuffix.length); // Type | undefined => Type + return ObjectSerializer.deserialize(data, subType); + } else if (startsWith(type, arrayPrefix)) { + let subType: string = type.slice(arrayPrefix.length, -arraySuffix.length); // Array => Type + let transformedData: any[] = []; + for (let index = 0; index < data.length; index++) { + let datum = data[index]; + transformedData.push(ObjectSerializer.deserialize(datum, subType)); + } + return transformedData; + } else if (startsWith(type, mapPrefix)) { + let subType: string = type.slice(mapPrefix.length, -mapSuffix.length); // { [key: string]: Type; } => Type + let transformedData: { [key: string]: any } = {}; + for (let key in data) { + transformedData[key] = ObjectSerializer.deserialize( + data[key], + subType, + ); + } + return transformedData; + } else if (type === "Date") { + return new Date(data); + } else { + if (enumsMap[type]) {// is Enum + return data; + } + + if (!typeMap[type]) { // dont know the type + return data; + } + let instance = new typeMap[type](); + let attributeTypes = typeMap[type].getAttributeTypeMap(); + for (let index = 0; index < attributeTypes.length; index++) { + let attributeType = attributeTypes[index]; + instance[attributeType.name] = ObjectSerializer.deserialize(data[attributeType.baseName], attributeType.type); + } + return instance; + } + } +} + +export interface Authentication { + /** + * Apply authentication settings to header and query params. + */ + applyToRequest(requestOptions: localVarRequest.Options): Promise | void; +} + +export class HttpBasicAuth implements Authentication { + public username: string = ''; + public password: string = ''; + + applyToRequest(requestOptions: localVarRequest.Options): void { + requestOptions.auth = { + username: this.username, password: this.password + } + } +} + +export class HttpBearerAuth implements Authentication { + public accessToken: string | (() => string) = ''; + + applyToRequest(requestOptions: localVarRequest.Options): void { + if (requestOptions && requestOptions.headers) { + const accessToken = typeof this.accessToken === 'function' + ? this.accessToken() + : this.accessToken; + requestOptions.headers["Authorization"] = "Bearer " + accessToken; + } + } +} + +export class ApiKeyAuth implements Authentication { + public apiKey: string = ''; + + constructor(private location: string, private paramName: string) { + } + + applyToRequest(requestOptions: localVarRequest.Options): void { + if (this.location == "query") { + (requestOptions.qs)[this.paramName] = this.apiKey; + } else if (this.location == "header" && requestOptions && requestOptions.headers) { + requestOptions.headers[this.paramName] = this.apiKey; + } else if (this.location == 'cookie' && requestOptions && requestOptions.headers) { + if (requestOptions.headers['Cookie']) { + requestOptions.headers['Cookie'] += '; ' + this.paramName + '=' + encodeURIComponent(this.apiKey); + } + else { + requestOptions.headers['Cookie'] = this.paramName + '=' + encodeURIComponent(this.apiKey); + } + } + } +} + +export class OAuth implements Authentication { + public accessToken: string = ''; + + applyToRequest(requestOptions: localVarRequest.Options): void { + if (requestOptions && requestOptions.headers) { + requestOptions.headers["Authorization"] = "Bearer " + this.accessToken; + } + } +} + +export class VoidAuth implements Authentication { + public username: string = ''; + public password: string = ''; + + applyToRequest(_: localVarRequest.Options): void { + // Do nothing + } +} + +export type Interceptor = (requestOptions: localVarRequest.Options) => (Promise | void); diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/model/validationError.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/validationError.ts new file mode 100644 index 0000000..7d15ecf --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/validationError.ts @@ -0,0 +1,56 @@ +/** + * Coffee Orders API + * A CRUD API for managing coffee orders and available coffee types. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { RequestFile } from './models'; +import { ValidationErrorLocInner } from './validationErrorLocInner'; + +/** +* Detailed information about a validation error +*/ +export class ValidationError { + /** + * Type of error + */ + 'type': string; + /** + * Location of the error in the request + */ + 'loc': Array; + /** + * Error message + */ + 'msg': string; + + static discriminator: string | undefined = undefined; + + static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [ + { + "name": "type", + "baseName": "type", + "type": "string" + }, + { + "name": "loc", + "baseName": "loc", + "type": "Array" + }, + { + "name": "msg", + "baseName": "msg", + "type": "string" + } ]; + + static getAttributeTypeMap() { + return ValidationError.attributeTypeMap; + } +} + diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/model/validationErrorLocInner.ts b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/validationErrorLocInner.ts new file mode 100644 index 0000000..7ef8509 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/model/validationErrorLocInner.ts @@ -0,0 +1,26 @@ +/** + * Coffee Orders API + * A CRUD API for managing coffee orders and available coffee types. + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { RequestFile } from './models'; + +export class ValidationErrorLocInner { + + static discriminator: string | undefined = undefined; + + static attributeTypeMap: Array<{name: string, baseName: string, type: string}> = [ + ]; + + static getAttributeTypeMap() { + return ValidationErrorLocInner.attributeTypeMap; + } +} + diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/package-lock.json b/oss-migration-guide/sdks/oss-coffee-client-typescript/package-lock.json new file mode 100644 index 0000000..4ca3878 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/package-lock.json @@ -0,0 +1,773 @@ +{ + "name": "oss-coffee-client", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "oss-coffee-client", + "version": "1.0.0", + "license": "Unlicense", + "dependencies": { + "bluebird": "^3.7.2", + "request": "^2.88.2" + }, + "devDependencies": { + "@types/bluebird": "^3.5.33", + "@types/node": "^12", + "@types/request": "^2.48.8", + "typescript": "^4.0 || ^5.0" + } + }, + "node_modules/@types/bluebird": { + "version": "3.5.42", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.42.tgz", + "integrity": "sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "license": "MIT" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "license": "Apache-2.0" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.3.tgz", + "integrity": "sha512-XHIrMD0NpDrNM/Ckf7XJiBbLl57KEhT3+i3yY+eWm+cqYZJQTZrKo8Y8AWKnuV5GT4scfuUGt9LzNoIx3dU1nQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.35", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "license": "MIT" + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, + "node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + } + } +} diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/package.json b/oss-migration-guide/sdks/oss-coffee-client-typescript/package.json new file mode 100644 index 0000000..f473cde --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/package.json @@ -0,0 +1,28 @@ +{ + "name": "oss-coffee-client", + "version": "1.0.0", + "description": "NodeJS client for oss-coffee-client", + "repository": { + "type": "git", + "url": "https://github.com/GIT_USER_ID/GIT_REPO_ID.git" + }, + "main": "dist/api.js", + "types": "dist/api.d.ts", + "scripts": { + "clean": "rm -Rf node_modules/ *.js", + "build": "tsc", + "test": "npm run build && node dist/client.js" + }, + "author": "OpenAPI-Generator Contributors", + "license": "Unlicense", + "dependencies": { + "bluebird": "^3.7.2", + "request": "^2.88.2" + }, + "devDependencies": { + "@types/bluebird": "^3.5.33", + "@types/node": "^12", + "@types/request": "^2.48.8", + "typescript": "^4.0 || ^5.0" + } +} diff --git a/oss-migration-guide/sdks/oss-coffee-client-typescript/tsconfig.json b/oss-migration-guide/sdks/oss-coffee-client-typescript/tsconfig.json new file mode 100644 index 0000000..ea90786 --- /dev/null +++ b/oss-migration-guide/sdks/oss-coffee-client-typescript/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "noImplicitAny": false, + "target": "ES5", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "strict": true, + "moduleResolution": "node", + "removeComments": true, + "sourceMap": true, + "noLib": false, + "declaration": true, + "lib": ["dom", "es6", "es5", "dom.iterable", "scripthost"], + "outDir": "dist", + "typeRoots": [ + "node_modules/@types" + ] + }, + "exclude": [ + "dist", + "node_modules" + ] +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.devcontainer/README.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.devcontainer/README.md new file mode 100644 index 0000000..6edb968 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.devcontainer/README.md @@ -0,0 +1,30 @@ + +> **Remember to shutdown a GitHub Codespace when it is not in use!** + +# Dev Containers Quick Start + +The default location for usage snippets is the `samples` directory. + +## Running a Usage Sample + +A sample usage example has been provided in a `root.ts` file. As you work with the SDK, it's expected that you will modify these samples to fit your needs. To execute this particular snippet, use the command below. + +``` +ts-node root.ts +``` + +## Generating Additional Usage Samples + +The speakeasy CLI allows you to generate more usage snippets. Here's how: + +- To generate a sample for a specific operation by providing an operation ID, use: + +``` +speakeasy generate usage -s openapi-formatted.yaml -l typescript -i {INPUT_OPERATION_ID} -o ./samples +``` + +- To generate samples for an entire namespace (like a tag or group name), use: + +``` +speakeasy generate usage -s openapi-formatted.yaml -l typescript -n {INPUT_TAG_NAME} -o ./samples +``` diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.devcontainer/devcontainer.json b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.devcontainer/devcontainer.json new file mode 100644 index 0000000..4d560dd --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.devcontainer/devcontainer.json @@ -0,0 +1,45 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/images/tree/main/src/typescript-node +{ + "name": "TypeScript", + "image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye", + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "sudo chmod +x ./.devcontainer/setup.sh && ./.devcontainer/setup.sh", + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.vscode-typescript-tslint-plugin", + "esbenp.prettier-vscode", + "github.vscode-pull-request-github" + ], + "settings": { + "files.eol": "\n", + "editor.formatOnSave": true, + "typescript.tsc.autoDetect": "on", + "typescript.updateImportsOnFileMove.enabled": "always", + "typescript.preferences.importModuleSpecifier": "relative", + "[typescript]": { + "editor.codeActionsOnSave": { + "source.organizeImports": true + } + }, + "[typescriptreact]": { + "editor.codeActionsOnSave": { + "source.organizeImports": true + } + } + } + }, + "codespaces": { + "openFiles": [ + ".devcontainer/README.md" + ] + } + } + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.devcontainer/setup.sh b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.devcontainer/setup.sh new file mode 100644 index 0000000..e0d801b --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.devcontainer/setup.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Install the speakeasy CLI +curl -fsSL https://raw.githubusercontent.com/speakeasy-api/speakeasy/main/install.sh | sh + +# Setup samples directory +rmdir samples || true +mkdir samples + +npm install +npm install -g ts-node +npm link +npm link speakeasy-coffee-client +TS_CONFIG_CONTENT=$(cat < samples/tsconfig.json + +# Generate starter usage sample with speakeasy +speakeasy generate usage -s openapi-formatted.yaml -l typescript -o samples/root.ts \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.gitattributes b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.gitattributes new file mode 100644 index 0000000..113eead --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.gitattributes @@ -0,0 +1,2 @@ +# This allows generated code to be indexed correctly +*.ts linguist-generated=false \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.github/workflows/sdk_generation.yaml b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.github/workflows/sdk_generation.yaml new file mode 100644 index 0000000..65342d7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.github/workflows/sdk_generation.yaml @@ -0,0 +1,29 @@ +name: Generate +permissions: + checks: write + contents: write + pull-requests: write + statuses: write + id-token: write +"on": + workflow_dispatch: + inputs: + force: + description: Force generation of SDKs + type: boolean + default: false + set_version: + description: optionally set a specific SDK version + type: string + schedule: + - cron: 0 0 * * * +jobs: + generate: + uses: speakeasy-api/sdk-generation-action/.github/workflows/workflow-executor.yaml@v15 + with: + force: ${{ github.event.inputs.force }} + mode: pr + set_version: ${{ github.event.inputs.set_version }} + secrets: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + speakeasy_api_key: ${{ secrets.SPEAKEASY_API_KEY }} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.gitignore b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.gitignore new file mode 100644 index 0000000..4829686 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.gitignore @@ -0,0 +1,22 @@ +/models +/models/errors +/types +/node_modules +/lib +/sdk +/funcs +/react-query +/mcp-server +/hooks +/index.* +/core.* +/bin +/cjs +/esm +/dist +/.tsbuildinfo +/.eslintcache +/.tshy +/.tshy-* +/__tests__ +/.speakeasy/reports diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.npmignore b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.npmignore new file mode 100644 index 0000000..cf98a6b --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.npmignore @@ -0,0 +1,15 @@ +**/* +!/FUNCTIONS.md +!/RUNTIMES.md +!/REACT_QUERY.md +!/**/*.ts +!/**/*.js +!/**/*.mjs +!/**/*.json +!/**/*.map + +/eslint.config.mjs +/cjs +/.tshy +/.tshy-* +/__tests__ diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/gen.lock b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/gen.lock new file mode 100644 index 0000000..017faa1 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/gen.lock @@ -0,0 +1,473 @@ +lockVersion: 2.0.0 +id: 0b747e6e-134e-43e9-bf8b-a26d6c1a43f2 +management: + docChecksum: 707abb4f274567bd52d627c21da4523a + docVersion: 1.0.0 + speakeasyVersion: 1.509.1 + generationVersion: 2.539.1 + releaseVersion: 0.1.0 + configChecksum: 556a42e2fee9cff1009a6a956ee29eac +features: + typescript: + additionalDependencies: 0.1.0 + core: 3.21.3 + defaultEnabledRetries: 0.1.0 + devContainers: 2.90.0 + enumUnions: 0.1.0 + envVarSecurityUsage: 0.1.2 + examples: 2.81.5 + globalSecurity: 2.82.13 + globalSecurityCallbacks: 0.1.0 + globalSecurityFlattening: 0.1.0 + globalServerURLs: 2.82.4 + groups: 2.81.2 + mcpServer: 0.4.1 + mockServer: 0.1.0 + nameOverrides: 2.81.2 + nullables: 0.1.1 + responseFormat: 0.2.3 + retries: 2.83.0 + sdkHooks: 0.2.0 + tests: 0.15.0 + unions: 2.85.8 +generatedFiles: + - .devcontainer/README.md + - .devcontainer/devcontainer.json + - .devcontainer/setup.sh + - .gitattributes + - .npmignore + - FUNCTIONS.md + - RUNTIMES.md + - USAGE.md + - docs/lib/utils/retryconfig.md + - docs/models/components/coffeeorder.md + - docs/models/components/coffeeordersize.md + - docs/models/components/coffeeorderupdate.md + - docs/models/components/coffeeorderupdatesize.md + - docs/models/components/coffeetype.md + - docs/models/components/loc.md + - docs/models/components/security.md + - docs/models/components/validationerror.md + - docs/models/errors/errorresponse.md + - docs/models/errors/httpvalidationerror.md + - docs/models/operations/deletecoffeetyperequest.md + - docs/models/operations/deleteorderrequest.md + - docs/models/operations/getcoffeetyperequest.md + - docs/models/operations/getorderrequest.md + - docs/models/operations/getordersrequest.md + - docs/models/operations/updatecoffeetyperequest.md + - docs/models/operations/updateorderrequest.md + - docs/sdks/coffeetypes/README.md + - docs/sdks/orders/README.md + - docs/sdks/speakeasycoffeeclient/README.md + - eslint.config.mjs + - jsr.json + - package.json + - src/__tests__/assertions.ts + - src/__tests__/coffeetypes.test.ts + - src/__tests__/files.ts + - src/__tests__/mockserver/Dockerfile + - src/__tests__/mockserver/Makefile + - src/__tests__/mockserver/README.md + - src/__tests__/mockserver/go.mod + - src/__tests__/mockserver/go.sum + - src/__tests__/mockserver/internal/handler/assert/contenttype.go + - src/__tests__/mockserver/internal/handler/assert/header.go + - src/__tests__/mockserver/internal/handler/assert/parameter.go + - src/__tests__/mockserver/internal/handler/assert/pointer.go + - src/__tests__/mockserver/internal/handler/assert/security.go + - src/__tests__/mockserver/internal/handler/doc.go + - src/__tests__/mockserver/internal/handler/generated_handler.go + - src/__tests__/mockserver/internal/handler/generated_handlers.go + - src/__tests__/mockserver/internal/handler/pathdeletecoffeetypestypeid.go + - src/__tests__/mockserver/internal/handler/pathdeleteordersorderid.go + - src/__tests__/mockserver/internal/handler/pathgetcoffeetypes.go + - src/__tests__/mockserver/internal/handler/pathgetcoffeetypestypeid.go + - src/__tests__/mockserver/internal/handler/pathgetorders.go + - src/__tests__/mockserver/internal/handler/pathgetordersorderid.go + - src/__tests__/mockserver/internal/handler/pathpostcoffeetypes.go + - src/__tests__/mockserver/internal/handler/pathpostorders.go + - src/__tests__/mockserver/internal/handler/pathputcoffeetypestypeid.go + - src/__tests__/mockserver/internal/handler/pathputordersorderid.go + - src/__tests__/mockserver/internal/handler/values/files.go + - src/__tests__/mockserver/internal/logging/doc.go + - src/__tests__/mockserver/internal/logging/formats.go + - src/__tests__/mockserver/internal/logging/http_file.go + - src/__tests__/mockserver/internal/logging/http_logger.go + - src/__tests__/mockserver/internal/logging/levels.go + - src/__tests__/mockserver/internal/logging/logger.go + - src/__tests__/mockserver/internal/logging/oas_operation.go + - src/__tests__/mockserver/internal/logging/oas_operation_call.go + - src/__tests__/mockserver/internal/sdk/models/components/coffeeorder.go + - src/__tests__/mockserver/internal/sdk/models/components/coffeeorderupdate.go + - src/__tests__/mockserver/internal/sdk/models/components/coffeetype.go + - src/__tests__/mockserver/internal/sdk/models/components/httpmetadata.go + - src/__tests__/mockserver/internal/sdk/models/components/security.go + - src/__tests__/mockserver/internal/sdk/models/components/validationerror.go + - src/__tests__/mockserver/internal/sdk/models/operations/createcoffeetype.go + - src/__tests__/mockserver/internal/sdk/models/operations/createorder.go + - src/__tests__/mockserver/internal/sdk/models/operations/deletecoffeetype.go + - src/__tests__/mockserver/internal/sdk/models/operations/deleteorder.go + - src/__tests__/mockserver/internal/sdk/models/operations/getcoffeetype.go + - src/__tests__/mockserver/internal/sdk/models/operations/getcoffeetypes.go + - src/__tests__/mockserver/internal/sdk/models/operations/getorder.go + - src/__tests__/mockserver/internal/sdk/models/operations/getorders.go + - src/__tests__/mockserver/internal/sdk/models/operations/updatecoffeetype.go + - src/__tests__/mockserver/internal/sdk/models/operations/updateorder.go + - src/__tests__/mockserver/internal/sdk/models/sdkerrors/errorresponse.go + - src/__tests__/mockserver/internal/sdk/models/sdkerrors/httpvalidationerror.go + - src/__tests__/mockserver/internal/sdk/types/bigint.go + - src/__tests__/mockserver/internal/sdk/types/date.go + - src/__tests__/mockserver/internal/sdk/types/datetime.go + - src/__tests__/mockserver/internal/sdk/types/decimal.go + - src/__tests__/mockserver/internal/sdk/types/pointers.go + - src/__tests__/mockserver/internal/sdk/utils/json.go + - src/__tests__/mockserver/internal/sdk/utils/reflect.go + - src/__tests__/mockserver/internal/sdk/utils/sort.go + - src/__tests__/mockserver/internal/server/doc.go + - src/__tests__/mockserver/internal/server/generated_handlers.go + - src/__tests__/mockserver/internal/server/internal_handlers.go + - src/__tests__/mockserver/internal/server/server.go + - src/__tests__/mockserver/internal/server/server_option.go + - src/__tests__/mockserver/internal/server/templates/log/index.html.tmpl + - src/__tests__/mockserver/internal/server/templates/log/operation.html.tmpl + - src/__tests__/mockserver/internal/server/templates/log/style.css.tmpl + - src/__tests__/mockserver/internal/tracking/requesttracker.go + - src/__tests__/mockserver/main.go + - src/__tests__/orders.test.ts + - src/__tests__/testclient.ts + - src/core.ts + - src/funcs/coffeeTypesCreate.ts + - src/funcs/coffeeTypesDelete.ts + - src/funcs/coffeeTypesGetById.ts + - src/funcs/coffeeTypesList.ts + - src/funcs/coffeeTypesUpdate.ts + - src/funcs/ordersCreate.ts + - src/funcs/ordersDelete.ts + - src/funcs/ordersGetById.ts + - src/funcs/ordersList.ts + - src/funcs/ordersUpdate.ts + - src/hooks/hooks.ts + - src/hooks/index.ts + - src/hooks/types.ts + - src/index.ts + - src/lib/base64.ts + - src/lib/config.ts + - src/lib/dlv.ts + - src/lib/encodings.ts + - src/lib/env.ts + - src/lib/files.ts + - src/lib/http.ts + - src/lib/is-plain-object.ts + - src/lib/logger.ts + - src/lib/matchers.ts + - src/lib/primitives.ts + - src/lib/retries.ts + - src/lib/schemas.ts + - src/lib/sdks.ts + - src/lib/security.ts + - src/lib/url.ts + - src/mcp-server/build.mts + - src/mcp-server/cli.ts + - src/mcp-server/cli/start/command.ts + - src/mcp-server/cli/start/impl.ts + - src/mcp-server/console-logger.ts + - src/mcp-server/mcp-server.ts + - src/mcp-server/resources.ts + - src/mcp-server/scopes.ts + - src/mcp-server/server.ts + - src/mcp-server/shared.ts + - src/mcp-server/tools.ts + - src/mcp-server/tools/coffeeTypesCreate.ts + - src/mcp-server/tools/coffeeTypesDelete.ts + - src/mcp-server/tools/coffeeTypesGetById.ts + - src/mcp-server/tools/coffeeTypesList.ts + - src/mcp-server/tools/coffeeTypesUpdate.ts + - src/mcp-server/tools/ordersCreate.ts + - src/mcp-server/tools/ordersDelete.ts + - src/mcp-server/tools/ordersGetById.ts + - src/mcp-server/tools/ordersList.ts + - src/mcp-server/tools/ordersUpdate.ts + - src/models/components/coffeeorder.ts + - src/models/components/coffeeorderupdate.ts + - src/models/components/coffeetype.ts + - src/models/components/index.ts + - src/models/components/security.ts + - src/models/components/validationerror.ts + - src/models/errors/apierror.ts + - src/models/errors/errorresponse.ts + - src/models/errors/httpclienterrors.ts + - src/models/errors/httpvalidationerror.ts + - src/models/errors/index.ts + - src/models/errors/sdkvalidationerror.ts + - src/models/operations/deletecoffeetype.ts + - src/models/operations/deleteorder.ts + - src/models/operations/getcoffeetype.ts + - src/models/operations/getorder.ts + - src/models/operations/getorders.ts + - src/models/operations/index.ts + - src/models/operations/updatecoffeetype.ts + - src/models/operations/updateorder.ts + - src/sdk/coffeetypes.ts + - src/sdk/index.ts + - src/sdk/orders.ts + - src/sdk/sdk.ts + - src/types/async.ts + - src/types/blobs.ts + - src/types/constdatetime.ts + - src/types/enums.ts + - src/types/fp.ts + - src/types/index.ts + - src/types/operations.ts + - src/types/rfcdate.ts + - src/types/streams.ts + - tsconfig.json +examples: + GetOrders: + latte: + parameters: + query: + coffee_type: "Latte" + responses: + "200": + application/json: [{"id": 5, "customer_name": "Eve", "coffee_type": "Mocha", "size": "Large", "extras": ["Whipped cream", "Chocolate syrup"], "price": 6}, {"id": 6, "customer_name": "Grace", "coffee_type": "Cold Brew", "size": "Medium", "extras": ["Vanilla syrup"], "price": 5.5}] + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + espresso: + parameters: + query: + coffee_type: "Espresso" + responses: + "200": + application/json: [{"id": 5, "customer_name": "Eve", "coffee_type": "Mocha", "size": "Large", "extras": ["Whipped cream", "Chocolate syrup"], "price": 6}, {"id": 6, "customer_name": "Grace", "coffee_type": "Cold Brew", "size": "Medium", "extras": ["Vanilla syrup"], "price": 5.5}] + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + multiple_orders: + responses: + "200": + application/json: [{"id": 1, "customer_name": "Alice", "coffee_type": "Latte", "size": "Medium", "extras": ["Extra shot", "Soy milk"], "price": 4.5}, {"id": 2, "customer_name": "Bob", "coffee_type": "Espresso", "size": "Small", "extras": ["Extra shot"], "price": 3.5}] + CreateOrder: + simple_order: + requestBody: + application/json: {"id": 3, "customer_name": "Charlie", "coffee_type": "Americano", "size": "Large", "price": 3.75} + responses: + "201": + application/json: {"id": 5, "customer_name": "Eve", "coffee_type": "Mocha", "size": "Large", "extras": ["Whipped cream", "Chocolate syrup"], "price": 6} + "400": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + complex_order: + requestBody: + application/json: {"id": 4, "customer_name": "Diana", "coffee_type": "Cappuccino", "size": "Medium", "extras": ["Whipped cream", "Caramel syrup"], "price": 5.25} + responses: + "201": + application/json: {"id": 6, "customer_name": "Grace", "coffee_type": "Cold Brew", "size": "Medium", "extras": ["Vanilla syrup"], "price": 5.5} + "400": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + GetOrder: + order1: + parameters: + path: + order_id: 1 + responses: + "200": + application/json: {"id": 5, "customer_name": "Eve", "coffee_type": "Mocha", "size": "Large", "extras": ["Whipped cream", "Chocolate syrup"], "price": 6} + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + order2: + parameters: + path: + order_id: 2 + responses: + "200": + application/json: {"id": 6, "customer_name": "Grace", "coffee_type": "Cold Brew", "size": "Medium", "extras": ["Vanilla syrup"], "price": 5.5} + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + not_found: + parameters: + path: + order_id: 257133 + responses: + "404": + application/json: {"detail": "Order not found"} + UpdateOrder: + order1: + parameters: + path: + order_id: 1 + requestBody: + application/json: {"coffee_type": "Cappuccino", "extras": ["Cinnamon", "Whipped cream"], "price": 5.75} + responses: + "200": + application/json: {"id": 6, "customer_name": "Grace", "coffee_type": "Cold Brew", "size": "Medium", "extras": ["Vanilla syrup"], "price": 5.5} + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + order2: + parameters: + path: + order_id: 2 + requestBody: + application/json: {"customer_name": "Frank", "size": "Small", "extras": ["Sugar-free syrup"]} + responses: + "200": + application/json: {"id": 6, "customer_name": "Grace", "coffee_type": "Cold Brew", "size": "Medium", "extras": ["Vanilla syrup"], "price": 5.5} + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + not_found: + parameters: + path: + order_id: 488852 + requestBody: + application/json: {"coffee_type": "Cappuccino", "extras": ["Cinnamon", "Whipped cream"], "price": 5.75} + responses: + "404": + application/json: {"detail": "Order not found"} + DeleteOrder: + order1: + parameters: + path: + order_id: 1 + responses: + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + order2: + parameters: + path: + order_id: 2 + responses: + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + not_found: + parameters: + path: + order_id: 545907 + responses: + "404": + application/json: {"detail": "Order not found"} + GetCoffeeTypes: + coffee_types: + responses: + "200": + application/json: [{"name": "Espresso", "description": "Strong and bold coffee shot", "id": 1, "price_multiplier": 1}, {"name": "Latte", "description": "Espresso with steamed milk", "id": 2, "price_multiplier": 1.2}, {"name": "Mocha", "description": "Espresso with chocolate and steamed milk", "id": 3, "price_multiplier": 1.3}] + CreateCoffeeType: + duplicate_id: + requestBody: + application/json: {"name": "Cold Brew", "description": "Smooth, cold-steeped coffee", "id": 4, "price_multiplier": 1.4} + responses: + "400": + application/json: {"detail": "Coffee type with this ID already exists"} + GetCoffeeType: + espresso: + parameters: + path: + type_id: 1 + responses: + "200": + application/json: {"name": "Cold Brew", "description": "Smooth, cold-steeped coffee", "id": 4, "price_multiplier": 1.4} + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + latte: + parameters: + path: + type_id: 2 + responses: + "200": + application/json: {"name": "Flat White", "description": "Espresso with steamed whole milk", "id": 5, "price_multiplier": 1.25} + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + not_found: + parameters: + path: + type_id: 257133 + responses: + "404": + application/json: {"detail": "Coffee type not found"} + UpdateCoffeeType: + espresso: + parameters: + path: + type_id: 1 + requestBody: + application/json: {"name": "Flat White", "description": "Espresso with steamed whole milk", "id": 5, "price_multiplier": 1.25} + responses: + "200": + application/json: {"name": "Flat White", "description": "Espresso with steamed whole milk", "id": 5, "price_multiplier": 1.25} + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + latte: + parameters: + path: + type_id: 2 + requestBody: + application/json: {"name": "Cold Brew", "description": "Smooth, cold-steeped coffee", "id": 4, "price_multiplier": 1.4} + responses: + "200": + application/json: {"name": "Flat White", "description": "Espresso with steamed whole milk", "id": 5, "price_multiplier": 1.25} + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + not_found: + parameters: + path: + type_id: 488852 + requestBody: + application/json: {"name": "Flat White", "description": "Espresso with steamed whole milk", "id": 5, "price_multiplier": 1.25} + responses: + "404": + application/json: {"detail": "Coffee type not found"} + DeleteCoffeeType: + espresso: + parameters: + path: + type_id: 1 + responses: + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + latte: + parameters: + path: + type_id: 2 + responses: + "404": + application/json: {"detail": ""} + "422": + application/json: {"detail": [{"type": "value_error", "loc": ["body", "coffee_type"], "msg": "Invalid coffee type specified"}]} + not_found: + parameters: + path: + type_id: 545907 + responses: + "404": + application/json: {"detail": "Coffee type not found"} +examplesVersion: 1.0.0 +generatedTests: + GetOrders: "2025-03-05T00:06:49+02:00" + CreateOrder: "2025-03-05T00:06:49+02:00" + GetOrder: "2025-03-05T00:06:49+02:00" + UpdateOrder: "2025-03-05T00:06:49+02:00" + DeleteOrder: "2025-03-05T00:06:49+02:00" + GetCoffeeTypes: "2025-03-05T00:06:49+02:00" + CreateCoffeeType: "2025-03-05T00:06:49+02:00" + GetCoffeeType: "2025-03-05T00:06:49+02:00" + UpdateCoffeeType: "2025-03-05T00:06:49+02:00" + DeleteCoffeeType: "2025-03-05T00:06:49+02:00" diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/gen.yaml b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/gen.yaml new file mode 100644 index 0000000..890b105 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/gen.yaml @@ -0,0 +1,56 @@ +configVersion: 2.0.0 +generation: + devContainers: + enabled: true + schemaPath: openapi-formatted.yaml + sdkClassName: SpeakeasyCoffeeClient + maintainOpenAPIOrder: true + usageSnippets: + optionalPropertyRendering: withExample + useClassNamesForArrayFields: true + fixes: + nameResolutionDec2023: true + nameResolutionFeb2025: true + parameterOrderingFeb2024: true + requestResponseComponentNamesFeb2024: true + securityFeb2025: true + auth: + oAuth2ClientCredentialsEnabled: true + oAuth2PasswordEnabled: true + tests: + generateNewTests: true +typescript: + version: 0.1.0 + additionalDependencies: + dependencies: {} + devDependencies: {} + peerDependencies: {} + additionalPackageJSON: {} + author: Speakeasy + clientServerStatusCodesAsErrors: true + defaultErrorName: APIError + enableCustomCodeRegions: false + enableMCPServer: true + enableReactQuery: false + enumFormat: union + envVarPrefix: SPEAKEASYCOFFEECLIENT + flattenGlobalSecurity: true + flatteningOrder: parameters-first + imports: + option: openapi + paths: + callbacks: models/callbacks + errors: models/errors + operations: models/operations + shared: models/components + webhooks: models/webhooks + inputModelSuffix: input + jsonpath: rfc9535 + maxMethodParams: 0 + methodArguments: require-security-and-request + moduleFormat: dual + outputModelSuffix: output + packageName: speakeasy-coffee-client + responseFormat: flat + templateVersion: v2 + useIndexModules: true diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/testfiles/example.file b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/testfiles/example.file new file mode 100644 index 0000000..3b18e51 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/testfiles/example.file @@ -0,0 +1 @@ +hello world diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/tests.arazzo.yaml b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/tests.arazzo.yaml new file mode 100644 index 0000000..4af7f1a --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/tests.arazzo.yaml @@ -0,0 +1,566 @@ +arazzo: 1.0.0 +info: + title: Test Suite + summary: Created from ../openapi-formatted.yaml + version: 0.0.1 +sourceDescriptions: + - name: ../openapi-formatted.yaml + url: https://TBD.com + type: openapi +workflows: + - workflowId: GetOrders-multiple_orders + steps: + - stepId: test + operationId: GetOrders + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + [ + { + "id": 1, + "customer_name": "Alice", + "coffee_type": "Latte", + "size": "Medium", + "extras": [ + "Extra shot", + "Soy milk" + ], + "price": 4.5 + }, + { + "id": 2, + "customer_name": "Bob", + "coffee_type": "Espresso", + "size": "Small", + "extras": [ + "Extra shot" + ], + "price": 3.5 + } + ] + type: simple + x-speakeasy-test-group: orders + - workflowId: GetOrders-latte + steps: + - stepId: test + operationId: GetOrders + parameters: + - name: coffee_type + in: query + value: Latte + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + [ + { + "id": 5, + "customer_name": "Eve", + "coffee_type": "Mocha", + "size": "Large", + "extras": [ + "Whipped cream", + "Chocolate syrup" + ], + "price": 6 + }, + { + "id": 6, + "customer_name": "Grace", + "coffee_type": "Cold Brew", + "size": "Medium", + "extras": [ + "Vanilla syrup" + ], + "price": 5.5 + } + ] + type: simple + x-speakeasy-test-group: orders + - workflowId: GetOrders-espresso + steps: + - stepId: test + operationId: GetOrders + parameters: + - name: coffee_type + in: query + value: Espresso + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + [ + { + "id": 5, + "customer_name": "Eve", + "coffee_type": "Mocha", + "size": "Large", + "extras": [ + "Whipped cream", + "Chocolate syrup" + ], + "price": 6 + }, + { + "id": 6, + "customer_name": "Grace", + "coffee_type": "Cold Brew", + "size": "Medium", + "extras": [ + "Vanilla syrup" + ], + "price": 5.5 + } + ] + type: simple + x-speakeasy-test-group: orders + - workflowId: CreateOrder-simple_order + steps: + - stepId: test + operationId: CreateOrder + requestBody: + contentType: application/json + payload: + coffee_type: Americano + customer_name: Charlie + id: 3 + price: 3.75 + size: Large + successCriteria: + - condition: $statusCode == 201 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "id": 5, + "customer_name": "Eve", + "coffee_type": "Mocha", + "size": "Large", + "extras": [ + "Whipped cream", + "Chocolate syrup" + ], + "price": 6 + } + type: simple + x-speakeasy-test-group: orders + - workflowId: CreateOrder-complex_order + steps: + - stepId: test + operationId: CreateOrder + requestBody: + contentType: application/json + payload: + coffee_type: Cappuccino + customer_name: Diana + extras: + - Whipped cream + - Caramel syrup + id: 4 + price: 5.25 + size: Medium + successCriteria: + - condition: $statusCode == 201 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "id": 6, + "customer_name": "Grace", + "coffee_type": "Cold Brew", + "size": "Medium", + "extras": [ + "Vanilla syrup" + ], + "price": 5.5 + } + type: simple + x-speakeasy-test-group: orders + - workflowId: GetOrder-order1 + steps: + - stepId: test + operationId: GetOrder + parameters: + - name: order_id + in: path + value: 1 + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "id": 5, + "customer_name": "Eve", + "coffee_type": "Mocha", + "size": "Large", + "extras": [ + "Whipped cream", + "Chocolate syrup" + ], + "price": 6 + } + type: simple + x-speakeasy-test-group: orders + - workflowId: GetOrder-order2 + steps: + - stepId: test + operationId: GetOrder + parameters: + - name: order_id + in: path + value: 2 + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "id": 6, + "customer_name": "Grace", + "coffee_type": "Cold Brew", + "size": "Medium", + "extras": [ + "Vanilla syrup" + ], + "price": 5.5 + } + type: simple + x-speakeasy-test-group: orders + - workflowId: GetOrder-not_found + steps: + - stepId: test + operationId: GetOrder + parameters: + - name: order_id + in: path + value: 257133 + successCriteria: + - condition: $statusCode == 200 + x-speakeasy-test-group: orders + - workflowId: UpdateOrder-order1 + steps: + - stepId: test + operationId: UpdateOrder + parameters: + - name: order_id + in: path + value: 1 + requestBody: + contentType: application/json + payload: + coffee_type: Cappuccino + extras: + - Cinnamon + - Whipped cream + price: 5.75 + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "id": 6, + "customer_name": "Grace", + "coffee_type": "Cold Brew", + "size": "Medium", + "extras": [ + "Vanilla syrup" + ], + "price": 5.5 + } + type: simple + x-speakeasy-test-group: orders + - workflowId: UpdateOrder-order2 + steps: + - stepId: test + operationId: UpdateOrder + parameters: + - name: order_id + in: path + value: 2 + requestBody: + contentType: application/json + payload: + customer_name: Frank + extras: + - Sugar-free syrup + size: Small + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "id": 6, + "customer_name": "Grace", + "coffee_type": "Cold Brew", + "size": "Medium", + "extras": [ + "Vanilla syrup" + ], + "price": 5.5 + } + type: simple + x-speakeasy-test-group: orders + - workflowId: UpdateOrder-not_found + steps: + - stepId: test + operationId: UpdateOrder + parameters: + - name: order_id + in: path + value: 488852 + requestBody: + contentType: application/json + payload: + coffee_type: Cappuccino + extras: + - Cinnamon + - Whipped cream + price: 5.75 + successCriteria: + - condition: $statusCode == 200 + x-speakeasy-test-group: orders + - workflowId: DeleteOrder-order1 + steps: + - stepId: test + operationId: DeleteOrder + parameters: + - name: order_id + in: path + value: 1 + successCriteria: + - condition: $statusCode == 204 + x-speakeasy-test-group: orders + - workflowId: DeleteOrder-order2 + steps: + - stepId: test + operationId: DeleteOrder + parameters: + - name: order_id + in: path + value: 2 + successCriteria: + - condition: $statusCode == 204 + x-speakeasy-test-group: orders + - workflowId: DeleteOrder-not_found + steps: + - stepId: test + operationId: DeleteOrder + parameters: + - name: order_id + in: path + value: 545907 + successCriteria: + - condition: $statusCode == 204 + x-speakeasy-test-group: orders + - workflowId: GetCoffeeTypes-coffee_types + steps: + - stepId: test + operationId: GetCoffeeTypes + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + [ + { + "name": "Espresso", + "description": "Strong and bold coffee shot", + "id": 1, + "price_multiplier": 1 + }, + { + "name": "Latte", + "description": "Espresso with steamed milk", + "id": 2, + "price_multiplier": 1.2 + }, + { + "name": "Mocha", + "description": "Espresso with chocolate and steamed milk", + "id": 3, + "price_multiplier": 1.3 + } + ] + type: simple + x-speakeasy-test-group: coffeeTypes + - workflowId: CreateCoffeeType-duplicate_id + steps: + - stepId: test + operationId: CreateCoffeeType + requestBody: + contentType: application/json + payload: + description: Smooth, cold-steeped coffee + id: 4 + name: Cold Brew + price_multiplier: 1.4 + successCriteria: + - condition: $statusCode == 201 + x-speakeasy-test-group: coffeeTypes + - workflowId: GetCoffeeType-espresso + steps: + - stepId: test + operationId: GetCoffeeType + parameters: + - name: type_id + in: path + value: 1 + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "name": "Cold Brew", + "description": "Smooth, cold-steeped coffee", + "id": 4, + "price_multiplier": 1.4 + } + type: simple + x-speakeasy-test-group: coffeeTypes + - workflowId: GetCoffeeType-latte + steps: + - stepId: test + operationId: GetCoffeeType + parameters: + - name: type_id + in: path + value: 2 + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "name": "Flat White", + "description": "Espresso with steamed whole milk", + "id": 5, + "price_multiplier": 1.25 + } + type: simple + x-speakeasy-test-group: coffeeTypes + - workflowId: GetCoffeeType-not_found + steps: + - stepId: test + operationId: GetCoffeeType + parameters: + - name: type_id + in: path + value: 257133 + successCriteria: + - condition: $statusCode == 200 + x-speakeasy-test-group: coffeeTypes + - workflowId: UpdateCoffeeType-espresso + steps: + - stepId: test + operationId: UpdateCoffeeType + parameters: + - name: type_id + in: path + value: 1 + requestBody: + contentType: application/json + payload: + description: Espresso with steamed whole milk + id: 5 + name: Flat White + price_multiplier: 1.25 + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "name": "Flat White", + "description": "Espresso with steamed whole milk", + "id": 5, + "price_multiplier": 1.25 + } + type: simple + x-speakeasy-test-group: coffeeTypes + - workflowId: UpdateCoffeeType-latte + steps: + - stepId: test + operationId: UpdateCoffeeType + parameters: + - name: type_id + in: path + value: 2 + requestBody: + contentType: application/json + payload: + description: Smooth, cold-steeped coffee + id: 4 + name: Cold Brew + price_multiplier: 1.4 + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + { + "name": "Flat White", + "description": "Espresso with steamed whole milk", + "id": 5, + "price_multiplier": 1.25 + } + type: simple + x-speakeasy-test-group: coffeeTypes + - workflowId: UpdateCoffeeType-not_found + steps: + - stepId: test + operationId: UpdateCoffeeType + parameters: + - name: type_id + in: path + value: 488852 + requestBody: + contentType: application/json + payload: + description: Espresso with steamed whole milk + id: 5 + name: Flat White + price_multiplier: 1.25 + successCriteria: + - condition: $statusCode == 200 + x-speakeasy-test-group: coffeeTypes + - workflowId: DeleteCoffeeType-espresso + steps: + - stepId: test + operationId: DeleteCoffeeType + parameters: + - name: type_id + in: path + value: 1 + successCriteria: + - condition: $statusCode == 204 + x-speakeasy-test-group: coffeeTypes + - workflowId: DeleteCoffeeType-latte + steps: + - stepId: test + operationId: DeleteCoffeeType + parameters: + - name: type_id + in: path + value: 2 + successCriteria: + - condition: $statusCode == 204 + x-speakeasy-test-group: coffeeTypes + - workflowId: DeleteCoffeeType-not_found + steps: + - stepId: test + operationId: DeleteCoffeeType + parameters: + - name: type_id + in: path + value: 545907 + successCriteria: + - condition: $statusCode == 204 + x-speakeasy-test-group: coffeeTypes diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/workflow.lock b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/workflow.lock new file mode 100644 index 0000000..425cea9 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/workflow.lock @@ -0,0 +1,38 @@ +speakeasyVersion: 1.509.1 +sources: + Coffee Orders API: + sourceNamespace: coffee-orders-api + sourceRevisionDigest: sha256:f894ed4498bf450c62d25daddce29450276d82c26066fee1304039cc0984e133 + sourceBlobDigest: sha256:349becf1b143a60f925b15491b2eac56aef0b8cd87e5b1900c19f3813192b112 + tags: + - latest + - 1.0.0 +targets: + speakeasy-coffee-client: + source: Coffee Orders API + sourceNamespace: coffee-orders-api + sourceRevisionDigest: sha256:f894ed4498bf450c62d25daddce29450276d82c26066fee1304039cc0984e133 + sourceBlobDigest: sha256:349becf1b143a60f925b15491b2eac56aef0b8cd87e5b1900c19f3813192b112 + codeSamplesNamespace: coffee-orders-api-typescript-code-samples + codeSamplesRevisionDigest: sha256:9280bc77faee28ca8d8894bca02df9984905ce8804f9f88598f638682b381b59 +workflow: + workflowVersion: 1.0.0 + speakeasyVersion: latest + sources: + Coffee Orders API: + inputs: + - location: ../openapi-formatted.yaml + registry: + location: registry.speakeasyapi.dev/ritza-rzx/ritza/coffee-orders-api + targets: + speakeasy-coffee-client: + target: typescript + source: Coffee Orders API + codeSamples: + registry: + location: registry.speakeasyapi.dev/ritza-rzx/ritza/coffee-orders-api-typescript-code-samples + labelOverride: + fixedValue: Typescript (SDK) + blocking: false + testing: + enabled: true diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/workflow.yaml b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/workflow.yaml new file mode 100644 index 0000000..fa7f1ba --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/.speakeasy/workflow.yaml @@ -0,0 +1,20 @@ +workflowVersion: 1.0.0 +speakeasyVersion: latest +sources: + Coffee Orders API: + inputs: + - location: ../openapi-formatted.yaml + registry: + location: registry.speakeasyapi.dev/ritza-rzx/ritza/coffee-orders-api +targets: + speakeasy-coffee-client: + target: typescript + source: Coffee Orders API + codeSamples: + registry: + location: registry.speakeasyapi.dev/ritza-rzx/ritza/coffee-orders-api-typescript-code-samples + labelOverride: + fixedValue: Typescript (SDK) + blocking: false + testing: + enabled: true diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/CONTRIBUTING.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/CONTRIBUTING.md new file mode 100644 index 0000000..d585717 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/CONTRIBUTING.md @@ -0,0 +1,26 @@ +# Contributing to This Repository + +Thank you for your interest in contributing to this repository. Please note that this repository contains generated code. As such, we do not accept direct changes or pull requests. Instead, we encourage you to follow the guidelines below to report issues and suggest improvements. + +## How to Report Issues + +If you encounter any bugs or have suggestions for improvements, please open an issue on GitHub. When reporting an issue, please provide as much detail as possible to help us reproduce the problem. This includes: + +- A clear and descriptive title +- Steps to reproduce the issue +- Expected and actual behavior +- Any relevant logs, screenshots, or error messages +- Information about your environment (e.g., operating system, software versions) + - For example can be collected using the `npx envinfo` command from your terminal if you have Node.js installed + +## Issue Triage and Upstream Fixes + +We will review and triage issues as quickly as possible. Our goal is to address bugs and incorporate improvements in the upstream source code. Fixes will be included in the next generation of the generated code. + +## Contact + +If you have any questions or need further assistance, please feel free to reach out by opening an issue. + +Thank you for your understanding and cooperation! + +The Maintainers diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/FUNCTIONS.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/FUNCTIONS.md new file mode 100644 index 0000000..a7b381b --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/FUNCTIONS.md @@ -0,0 +1,106 @@ +# Standalone Functions + +> [!NOTE] +> This section is useful if you are using a bundler and targetting browsers and +> runtimes where the size of an application affects performance and load times. + +Every method in this SDK is also available as a standalone function. This +alternative API is suitable when targetting the browser or serverless runtimes +and using a bundler to build your application since all unused functionality +will be tree-shaken away. This includes code for unused methods, Zod schemas, +encoding helpers and response handlers. The result is dramatically smaller +impact on the application's final bundle size which grows very slowly as you use +more and more functionality from this SDK. + +Calling methods through the main SDK class remains a valid and generally more +more ergonomic option. Standalone functions represent an optimisation for a +specific category of applications. + +## Example + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { ordersList } from "speakeasy-coffee-client/funcs/ordersList.js"; +import { SDKValidationError } from "speakeasy-coffee-client/models/errors/sdkvalidationerror.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await ordersList(speakeasyCoffeeClient, { + coffeeType: "Latte", + }); + + switch (true) { + case res.ok: + // The success case will be handled outside of the switch block + break; + case res.error instanceof SDKValidationError: + // Pretty-print validation errors. + return console.log(res.error.pretty()); + case res.error instanceof Error: + return console.log(res.error); + default: + // TypeScript's type checking will fail on the following line if the above + // cases were not exhaustive. + res.error satisfies never; + throw new Error("Assertion failed: expected error checks to be exhaustive: " + res.error); + } + + + const { value: result } = res; + + // Handle the result + console.log(result); +} + +run(); +``` + +## Result types + +Standalone functions differ from SDK methods in that they return a +`Result` type to capture _known errors_ and document them using +the type system. By avoiding throwing errors, application code maintains clear +control flow and error-handling become part of the regular flow of application +code. + +> We use the term "known errors" because standalone functions, and JavaScript +> code in general, can still throw unexpected errors such as `TypeError`s, +> `RangeError`s and `DOMException`s. Exhaustively catching all errors may be +> something this SDK addresses in the future. Nevertheless, there is still a lot +> of benefit from capturing most errors and turning them into values. + +The second reason for this style of programming is because these functions will +typically be used in front-end applications where exception throwing is +sometimes discouraged or considered unidiomatic. React and similar ecosystems +and libraries tend to promote this style of programming so that components +render useful content under all states (loading, success, error and so on). + +The general pattern when calling standalone functions looks like this: + +```typescript +import { Core } from ""; +import { fetchSomething } from "/funcs/fetchSomething.js"; + +const client = new Core(); + +async function run() { + const result = await fetchSomething(client, { id: "123" }); + if (!result.ok) { + // You can throw the error or handle it. It's your choice now. + throw result.error; + } + + console.log(result.value); +} + +run(); +``` + +Notably, `result.error` above will have an explicit type compared to a try-catch +variation where the error in the catch block can only be of type `unknown` (or +`any` depending on your TypeScript settings). \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/README.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/README.md new file mode 100644 index 0000000..d7e5598 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/README.md @@ -0,0 +1,533 @@ +# speakeasy-coffee-client + +Developer-friendly & type-safe Typescript SDK specifically catered to leverage *speakeasy-coffee-client* API. + +
+ + + + +
+ + +

+> [!IMPORTANT] +> This SDK is not yet ready for production use. To complete setup please follow the steps outlined in your [workspace](https://app.speakeasy.com/org/ritza-rzx/ritza). Delete this section before > publishing to a package manager. + + +## Summary + +Coffee Orders API: A CRUD API for managing coffee orders and available coffee types. + + + +## Table of Contents + +* [speakeasy-coffee-client](#speakeasy-coffee-client) + * [SDK Installation](#sdk-installation) + * [Requirements](#requirements) + * [SDK Example Usage](#sdk-example-usage) + * [Authentication](#authentication) + * [Available Resources and Operations](#available-resources-and-operations) + * [Standalone functions](#standalone-functions) + * [Retries](#retries) + * [Error Handling](#error-handling) + * [Server Selection](#server-selection) + * [Custom HTTP Client](#custom-http-client) + * [Debugging](#debugging) +* [Development](#development) + * [Maturity](#maturity) + * [Contributions](#contributions) + + + + +## SDK Installation + +> [!TIP] +> To finish publishing your SDK to npm and others you must [run your first generation action](https://www.speakeasy.com/docs/github-setup#step-by-step-guide). + + +The SDK can be installed with either [npm](https://www.npmjs.com/), [pnpm](https://pnpm.io/), [bun](https://bun.sh/) or [yarn](https://classic.yarnpkg.com/en/) package managers. + +### NPM + +```bash +npm add +``` + +### PNPM + +```bash +pnpm add +``` + +### Bun + +```bash +bun add +``` + +### Yarn + +```bash +yarn add zod + +# Note that Yarn does not install peer dependencies automatically. You will need +# to install zod as shown above. +``` + +> [!NOTE] +> This package is published with CommonJS and ES Modules (ESM) support. + + +### Model Context Protocol (MCP) Server + +This SDK is also an installable MCP server where the various SDK methods are +exposed as tools that can be invoked by AI applications. + +> Node.js v20 or greater is required to run the MCP server. + +
+Claude installation steps + +Add the following server definition to your `claude_desktop_config.json` file: + +```json +{ + "mcpServers": { + "SpeakeasyCoffeeClient": { + "command": "npx", + "args": [ + "-y", "--package", "speakeasy-coffee-client", + "--", + "mcp", "start", + "--api-key-auth", "..." + ] + } + } +} +``` + +
+ +
+Cursor installation steps + +Go to `Cursor Settings > Features > MCP Servers > Add new MCP server` and use the following settings: + +- Name: SpeakeasyCoffeeClient +- Type: `command` +- Command: +```sh +npx -y --package speakeasy-coffee-client -- mcp start --api-key-auth ... +``` + +
+ +For a full list of server arguments, run: + +```sh +npx -y --package speakeasy-coffee-client -- mcp start --help +``` + + + +## Requirements + +For supported JavaScript runtimes, please consult [RUNTIMES.md](RUNTIMES.md). + + + +## SDK Example Usage + +### Example 1 + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Latte", + }); + + // Handle the result + console.log(result); +} + +run(); + +``` + +### Example 2 + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.create({ + id: 3, + customerName: "Charlie", + coffeeType: "Americano", + size: "Large", + price: 3.75, + }); + + // Handle the result + console.log(result); +} + +run(); + +``` + + + +## Authentication + +### Per-Client Security Schemes + +This SDK supports the following security scheme globally: + +| Name | Type | Scheme | Environment Variable | +| ------------ | ------ | ------- | ------------------------------------ | +| `apiKeyAuth` | apiKey | API key | `SPEAKEASYCOFFEECLIENT_API_KEY_AUTH` | + +To authenticate with the API the `apiKeyAuth` parameter must be set when initializing the SDK client instance. For example: +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Latte", + }); + + // Handle the result + console.log(result); +} + +run(); + +``` + + + +## Available Resources and Operations + +
+Available methods + +### [coffeeTypes](docs/sdks/coffeetypes/README.md) + +* [list](docs/sdks/coffeetypes/README.md#list) - Get Coffee Types +* [create](docs/sdks/coffeetypes/README.md#create) - Create Coffee Type +* [getById](docs/sdks/coffeetypes/README.md#getbyid) - Get Coffee Type +* [update](docs/sdks/coffeetypes/README.md#update) - Update Coffee Type +* [delete](docs/sdks/coffeetypes/README.md#delete) - Delete Coffee Type + +### [orders](docs/sdks/orders/README.md) + +* [list](docs/sdks/orders/README.md#list) - Get Orders +* [create](docs/sdks/orders/README.md#create) - Create Order +* [getById](docs/sdks/orders/README.md#getbyid) - Get Order +* [update](docs/sdks/orders/README.md#update) - Update Order +* [delete](docs/sdks/orders/README.md#delete) - Delete Order + + +
+ + + +## Standalone functions + +All the methods listed above are available as standalone functions. These +functions are ideal for use in applications running in the browser, serverless +runtimes or other environments where application bundle size is a primary +concern. When using a bundler to build your application, all unused +functionality will be either excluded from the final bundle or tree-shaken away. + +To read more about standalone functions, check [FUNCTIONS.md](./FUNCTIONS.md). + +
+ +Available standalone functions + +- [`coffeeTypesCreate`](docs/sdks/coffeetypes/README.md#create) - Create Coffee Type +- [`coffeeTypesDelete`](docs/sdks/coffeetypes/README.md#delete) - Delete Coffee Type +- [`coffeeTypesGetById`](docs/sdks/coffeetypes/README.md#getbyid) - Get Coffee Type +- [`coffeeTypesList`](docs/sdks/coffeetypes/README.md#list) - Get Coffee Types +- [`coffeeTypesUpdate`](docs/sdks/coffeetypes/README.md#update) - Update Coffee Type +- [`ordersCreate`](docs/sdks/orders/README.md#create) - Create Order +- [`ordersDelete`](docs/sdks/orders/README.md#delete) - Delete Order +- [`ordersGetById`](docs/sdks/orders/README.md#getbyid) - Get Order +- [`ordersList`](docs/sdks/orders/README.md#list) - Get Orders +- [`ordersUpdate`](docs/sdks/orders/README.md#update) - Update Order + +
+ + + +## Retries + +Some of the endpoints in this SDK support retries. If you use the SDK without any configuration, it will fall back to the default retry strategy provided by the API. However, the default retry strategy can be overridden on a per-operation basis, or across the entire SDK. + +To change the default retry strategy for a single API call, simply provide a retryConfig object to the call: +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Latte", + }, { + retries: { + strategy: "backoff", + backoff: { + initialInterval: 1, + maxInterval: 50, + exponent: 1.1, + maxElapsedTime: 100, + }, + retryConnectionErrors: false, + }, + }); + + // Handle the result + console.log(result); +} + +run(); + +``` + +If you'd like to override the default retry strategy for all operations that support retries, you can provide a retryConfig at SDK initialization: +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + retryConfig: { + strategy: "backoff", + backoff: { + initialInterval: 1, + maxInterval: 50, + exponent: 1.1, + maxElapsedTime: 100, + }, + retryConnectionErrors: false, + }, + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Latte", + }); + + // Handle the result + console.log(result); +} + +run(); + +``` + + + +## Error Handling + +Some methods specify known errors which can be thrown. All the known errors are enumerated in the `models/errors/errors.ts` module. The known errors for a method are documented under the *Errors* tables in SDK docs. For example, the `list` method may throw the following errors: + +| Error Type | Status Code | Content Type | +| -------------------------- | ----------- | ---------------- | +| errors.HTTPValidationError | 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | + +If the method throws an error and it is not captured by the known errors, it will default to throwing a `APIError`. + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; +import { + HTTPValidationError, + SDKValidationError, +} from "speakeasy-coffee-client/models/errors"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + let result; + try { + result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Latte", + }); + + // Handle the result + console.log(result); + } catch (err) { + switch (true) { + // The server response does not match the expected SDK schema + case (err instanceof SDKValidationError): { + // Pretty-print will provide a human-readable multi-line error message + console.error(err.pretty()); + // Raw value may also be inspected + console.error(err.rawValue); + return; + } + case (err instanceof HTTPValidationError): { + // Handle err.data$: HTTPValidationErrorData + console.error(err); + return; + } + default: { + // Other errors such as network errors, see HTTPClientErrors for more details + throw err; + } + } + } +} + +run(); + +``` + +Validation errors can also occur when either method arguments or data returned from the server do not match the expected format. The `SDKValidationError` that is thrown as a result will capture the raw value that failed validation in an attribute called `rawValue`. Additionally, a `pretty()` method is available on this error that can be used to log a nicely formatted multi-line string since validation errors can list many issues and the plain error string may be difficult read when debugging. + +In some rare cases, the SDK can fail to get a response from the server or even make the request due to unexpected circumstances such as network conditions. These types of errors are captured in the `models/errors/httpclienterrors.ts` module: + +| HTTP Client Error | Description | +| ---------------------------------------------------- | ---------------------------------------------------- | +| RequestAbortedError | HTTP request was aborted by the client | +| RequestTimeoutError | HTTP request timed out due to an AbortSignal signal | +| ConnectionError | HTTP client was unable to make a request to a server | +| InvalidRequestError | Any input used to create a request is invalid | +| UnexpectedClientError | Unrecognised or unexpected error | + + + +## Server Selection + +### Override Server URL Per-Client + +The default server can be overridden globally by passing a URL to the `serverURL: string` optional parameter when initializing the SDK client instance. For example: +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: "http://localhost:8000", + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Latte", + }); + + // Handle the result + console.log(result); +} + +run(); + +``` + + + +## Custom HTTP Client + +The TypeScript SDK makes API calls using an `HTTPClient` that wraps the native +[Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). This +client is a thin wrapper around `fetch` and provides the ability to attach hooks +around the request lifecycle that can be used to modify the request or handle +errors and response. + +The `HTTPClient` constructor takes an optional `fetcher` argument that can be +used to integrate a third-party HTTP client or when writing tests to mock out +the HTTP client and feed in fixtures. + +The following example shows how to use the `"beforeRequest"` hook to to add a +custom header and a timeout to requests and how to use the `"requestError"` hook +to log errors: + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; +import { HTTPClient } from "speakeasy-coffee-client/lib/http"; + +const httpClient = new HTTPClient({ + // fetcher takes a function that has the same signature as native `fetch`. + fetcher: (request) => { + return fetch(request); + } +}); + +httpClient.addHook("beforeRequest", (request) => { + const nextRequest = new Request(request, { + signal: request.signal || AbortSignal.timeout(5000) + }); + + nextRequest.headers.set("x-custom-header", "custom value"); + + return nextRequest; +}); + +httpClient.addHook("requestError", (error, request) => { + console.group("Request Error"); + console.log("Reason:", `${error}`); + console.log("Endpoint:", `${request.method} ${request.url}`); + console.groupEnd(); +}); + +const sdk = new SpeakeasyCoffeeClient({ httpClient }); +``` + + + +## Debugging + +You can setup your SDK to emit debug logs for SDK requests and responses. + +You can pass a logger that matches `console`'s interface as an SDK option. + +> [!WARNING] +> Beware that debug logging will reveal secrets, like API tokens in headers, in log messages printed to a console or files. It's recommended to use this feature only during local development and not in production. + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const sdk = new SpeakeasyCoffeeClient({ debugLogger: console }); +``` + +You can also enable a default debug logger by setting an environment variable `SPEAKEASYCOFFEECLIENT_DEBUG` to true. + + + + +# Development + +## Maturity + +This SDK is in beta, and there may be breaking changes between versions without a major version update. Therefore, we recommend pinning usage +to a specific package version. This way, you can install the same version each time without breaking changes unless you are intentionally +looking for the latest version. + +## Contributions + +While we value open-source contributions to this SDK, this library is generated programmatically. Any manual changes added to internal files will be overwritten on the next generation. +We look forward to hearing your feedback. Feel free to open a PR or an issue with a proof of concept and we'll do our best to include it in a future release. + +### SDK Created by [Speakeasy](https://www.speakeasy.com/?utm_source=speakeasy-coffee-client&utm_campaign=typescript) diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/RUNTIMES.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/RUNTIMES.md new file mode 100644 index 0000000..db7ea94 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/RUNTIMES.md @@ -0,0 +1,48 @@ +# Supported JavaScript runtimes + +This SDK is intended to be used in JavaScript runtimes that support ECMAScript 2020 or newer. The SDK uses the following features: + +* [Web Fetch API][web-fetch] +* [Web Streams API][web-streams] and in particular `ReadableStream` +* [Async iterables][async-iter] using `Symbol.asyncIterator` + +[web-fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API +[web-streams]: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API +[async-iter]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols + +Runtime environments that are explicitly supported are: + +- Evergreen browsers which include: Chrome, Safari, Edge, Firefox +- Node.js active and maintenance LTS releases + - Currently, this is v18 and v20 +- Bun v1 and above +- Deno v1.39 + - Note that Deno does not currently have native support for streaming file uploads backed by the filesystem ([issue link][deno-file-streaming]) + +[deno-file-streaming]: https://github.com/denoland/deno/issues/11018 + +## Recommended TypeScript compiler options + +The following `tsconfig.json` options are recommended for projects using this +SDK in order to get static type support for features like async iterables, +streams and `fetch`-related APIs ([`for await...of`][for-await-of], +[`AbortSignal`][abort-signal], [`Request`][request], [`Response`][response] and +so on): + +[for-await-of]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of +[abort-signal]: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal +[request]: https://developer.mozilla.org/en-US/docs/Web/API/Request +[response]: https://developer.mozilla.org/en-US/docs/Web/API/Response + +```jsonc +{ + "compilerOptions": { + "target": "es2020", // or higher + "lib": ["es2020", "dom", "dom.iterable"], + } +} +``` + +While `target` can be set to older ECMAScript versions, it may result in extra, +unnecessary compatibility code being generated if you are not targeting old +runtimes. \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/USAGE.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/USAGE.md new file mode 100644 index 0000000..400fbdb --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/USAGE.md @@ -0,0 +1,45 @@ + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Latte", + }); + + // Handle the result + console.log(result); +} + +run(); + +``` + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.create({ + id: 3, + customerName: "Charlie", + coffeeType: "Americano", + size: "Large", + price: 3.75, + }); + + // Handle the result + console.log(result); +} + +run(); + +``` + \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/lib/utils/retryconfig.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/lib/utils/retryconfig.md new file mode 100644 index 0000000..08f95f4 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/lib/utils/retryconfig.md @@ -0,0 +1,24 @@ +# RetryConfig + +Allows customizing the default retry configuration. It is only permitted in methods that accept retry policies. + +## Fields + +| Name | Type | Description | Example | +| ------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------ | ----------- | +| `strategy` | `"backoff" | "none"` | The retry strategy to use. | `"backoff"` | +| `backoff` | [BackoffStrategy](#backoffstrategy) | When strategy is "backoff", this configurates for the backoff parameters. | | +| `retryConnectionErrors` | `*boolean*` | When strategy is "backoff", this determines whether or not to retry on connection errors. | `true` | + +## BackoffStrategy + +The backoff strategy allows retrying a request with an exponential backoff between each retry. + +### Fields + +| Name | Type | Description | Example | +| ------------------ | ------------ | ----------------------------------------- | -------- | +| `initialInterval` | `*number*` | The initial interval in milliseconds. | `500` | +| `maxInterval` | `*number*` | The maximum interval in milliseconds. | `60000` | +| `exponent` | `*number*` | The exponent to use for the backoff. | `1.5` | +| `maxElapsedTime` | `*number*` | The maximum elapsed time in milliseconds. | `300000` | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeorder.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeorder.md new file mode 100644 index 0000000..9dce523 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeorder.md @@ -0,0 +1,31 @@ +# CoffeeOrder + +Represents a coffee order in the system + +## Example Usage + +```typescript +import { CoffeeOrder } from "speakeasy-coffee-client/models/components"; + +let value: CoffeeOrder = { + id: 6, + customerName: "Grace", + coffeeType: "Cold Brew", + size: "Medium", + extras: [ + "Vanilla syrup", + ], + price: 5.5, +}; +``` + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `id` | *number* | :heavy_check_mark: | Unique identifier for the order | 1 | +| `customerName` | *string* | :heavy_check_mark: | Name of the customer placing the order | Alice | +| `coffeeType` | *string* | :heavy_check_mark: | Type of coffee ordered (must match an existing coffee type) | Latte | +| `size` | [components.CoffeeOrderSize](../../models/components/coffeeordersize.md) | :heavy_check_mark: | Size of the coffee order | Medium | +| `extras` | *string*[] | :heavy_minus_sign: | Optional additions to the coffee order | [
"Extra shot",
"Soy milk"
] | +| `price` | *number* | :heavy_check_mark: | Total price of the order | 4.5 | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeordersize.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeordersize.md new file mode 100644 index 0000000..93cf41c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeordersize.md @@ -0,0 +1,17 @@ +# CoffeeOrderSize + +Size of the coffee order + +## Example Usage + +```typescript +import { CoffeeOrderSize } from "speakeasy-coffee-client/models/components"; + +let value: CoffeeOrderSize = "Medium"; +``` + +## Values + +```typescript +"Small" | "Medium" | "Large" +``` \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeorderupdate.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeorderupdate.md new file mode 100644 index 0000000..aea3081 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeorderupdate.md @@ -0,0 +1,28 @@ +# CoffeeOrderUpdate + +Model for updating an existing coffee order (all fields optional) + +## Example Usage + +```typescript +import { CoffeeOrderUpdate } from "speakeasy-coffee-client/models/components"; + +let value: CoffeeOrderUpdate = { + coffeeType: "Cappuccino", + extras: [ + "Cinnamon", + "Whipped cream", + ], + price: 5.75, +}; +``` + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | +| `customerName` | *string* | :heavy_minus_sign: | Updated customer name | Alice | +| `coffeeType` | *string* | :heavy_minus_sign: | Updated coffee type (must match an existing coffee type) | Cappuccino | +| `size` | [components.CoffeeOrderUpdateSize](../../models/components/coffeeorderupdatesize.md) | :heavy_minus_sign: | Updated size of the coffee order | Large | +| `extras` | *string*[] | :heavy_minus_sign: | Updated optional additions to the coffee order | [
"Whipped cream"
] | +| `price` | *number* | :heavy_minus_sign: | Updated total price of the order | 5 | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeorderupdatesize.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeorderupdatesize.md new file mode 100644 index 0000000..4a84f92 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeeorderupdatesize.md @@ -0,0 +1,15 @@ +# CoffeeOrderUpdateSize + +## Example Usage + +```typescript +import { CoffeeOrderUpdateSize } from "speakeasy-coffee-client/models/components"; + +let value: CoffeeOrderUpdateSize = "Large"; +``` + +## Values + +```typescript +"Small" | "Medium" | "Large" +``` \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeetype.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeetype.md new file mode 100644 index 0000000..2c19d94 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/coffeetype.md @@ -0,0 +1,25 @@ +# CoffeeType + +Represents a type of coffee available in the system + +## Example Usage + +```typescript +import { CoffeeType } from "speakeasy-coffee-client/models/components"; + +let value: CoffeeType = { + name: "Flat White", + description: "Espresso with steamed whole milk", + id: 5, + priceMultiplier: 1.25, +}; +``` + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | +| `name` | *string* | :heavy_check_mark: | Name of the coffee type | Latte | +| `description` | *string* | :heavy_minus_sign: | Detailed description of the coffee type | A milk-based espresso coffee | +| `id` | *number* | :heavy_check_mark: | Unique identifier for the coffee type | 1 | +| `priceMultiplier` | *number* | :heavy_minus_sign: | Price multiplier for this coffee type | 1.2 | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/loc.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/loc.md new file mode 100644 index 0000000..53f29ca --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/loc.md @@ -0,0 +1,17 @@ +# Loc + + +## Supported Types + +### `string` + +```typescript +const value: string = ""; +``` + +### `number` + +```typescript +const value: number = 715190; +``` + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/security.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/security.md new file mode 100644 index 0000000..2a487d7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/security.md @@ -0,0 +1,17 @@ +# Security + +## Example Usage + +```typescript +import { Security } from "speakeasy-coffee-client/models/components"; + +let value: Security = { + apiKeyAuth: "your-api-key-here", +}; +``` + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `apiKeyAuth` | *string* | :heavy_minus_sign: | N/A | your-api-key-here | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/validationerror.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/validationerror.md new file mode 100644 index 0000000..5704421 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/components/validationerror.md @@ -0,0 +1,26 @@ +# ValidationError + +Detailed information about a validation error + +## Example Usage + +```typescript +import { ValidationError } from "speakeasy-coffee-client/models/components"; + +let value: ValidationError = { + type: "value_error.number.not_gt", + loc: [ + "body", + "price", + ], + msg: "Price must be greater than 0", +}; +``` + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ | +| `type` | *string* | :heavy_check_mark: | Type of error | +| `loc` | *components.Loc*[] | :heavy_check_mark: | Location of the error in the request | +| `msg` | *string* | :heavy_check_mark: | Error message | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/errors/errorresponse.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/errors/errorresponse.md new file mode 100644 index 0000000..544bfd5 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/errors/errorresponse.md @@ -0,0 +1,17 @@ +# ErrorResponse + +Standard error response format + +## Example Usage + +```typescript +import { ErrorResponse } from "speakeasy-coffee-client/models/errors"; + +// No examples available for this model +``` + +## Fields + +| Field | Type | Required | Description | +| -------------------- | -------------------- | -------------------- | -------------------- | +| `detail` | *string* | :heavy_check_mark: | Error detail message | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/errors/httpvalidationerror.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/errors/httpvalidationerror.md new file mode 100644 index 0000000..9e378e3 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/errors/httpvalidationerror.md @@ -0,0 +1,17 @@ +# HTTPValidationError + +Error thrown when request validation fails + +## Example Usage + +```typescript +import { HTTPValidationError } from "speakeasy-coffee-client/models/errors"; + +// No examples available for this model +``` + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `detail` | [components.ValidationError](../../models/components/validationerror.md)[] | :heavy_minus_sign: | List of validation errors | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/deletecoffeetyperequest.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/deletecoffeetyperequest.md new file mode 100644 index 0000000..d93502f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/deletecoffeetyperequest.md @@ -0,0 +1,17 @@ +# DeleteCoffeeTypeRequest + +## Example Usage + +```typescript +import { DeleteCoffeeTypeRequest } from "speakeasy-coffee-client/models/operations"; + +let value: DeleteCoffeeTypeRequest = { + typeId: 528895, +}; +``` + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | +| `typeId` | *number* | :heavy_check_mark: | The ID of the coffee type to operate on | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/deleteorderrequest.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/deleteorderrequest.md new file mode 100644 index 0000000..36cbd86 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/deleteorderrequest.md @@ -0,0 +1,17 @@ +# DeleteOrderRequest + +## Example Usage + +```typescript +import { DeleteOrderRequest } from "speakeasy-coffee-client/models/operations"; + +let value: DeleteOrderRequest = { + orderId: 891773, +}; +``` + +## Fields + +| Field | Type | Required | Description | +| --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | +| `orderId` | *number* | :heavy_check_mark: | The ID of the order to operate on | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/getcoffeetyperequest.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/getcoffeetyperequest.md new file mode 100644 index 0000000..0d73b68 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/getcoffeetyperequest.md @@ -0,0 +1,17 @@ +# GetCoffeeTypeRequest + +## Example Usage + +```typescript +import { GetCoffeeTypeRequest } from "speakeasy-coffee-client/models/operations"; + +let value: GetCoffeeTypeRequest = { + typeId: 963663, +}; +``` + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------- | --------------------------------------- | --------------------------------------- | --------------------------------------- | +| `typeId` | *number* | :heavy_check_mark: | The ID of the coffee type to operate on | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/getorderrequest.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/getorderrequest.md new file mode 100644 index 0000000..61c07e8 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/getorderrequest.md @@ -0,0 +1,17 @@ +# GetOrderRequest + +## Example Usage + +```typescript +import { GetOrderRequest } from "speakeasy-coffee-client/models/operations"; + +let value: GetOrderRequest = { + orderId: 423655, +}; +``` + +## Fields + +| Field | Type | Required | Description | +| --------------------------------- | --------------------------------- | --------------------------------- | --------------------------------- | +| `orderId` | *number* | :heavy_check_mark: | The ID of the order to operate on | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/getordersrequest.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/getordersrequest.md new file mode 100644 index 0000000..8b26054 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/getordersrequest.md @@ -0,0 +1,15 @@ +# GetOrdersRequest + +## Example Usage + +```typescript +import { GetOrdersRequest } from "speakeasy-coffee-client/models/operations"; + +let value: GetOrdersRequest = {}; +``` + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- | +| `coffeeType` | *string* | :heavy_minus_sign: | Optional filter by coffee type (case-insensitive) | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/updatecoffeetyperequest.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/updatecoffeetyperequest.md new file mode 100644 index 0000000..b8fc6a5 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/updatecoffeetyperequest.md @@ -0,0 +1,24 @@ +# UpdateCoffeeTypeRequest + +## Example Usage + +```typescript +import { UpdateCoffeeTypeRequest } from "speakeasy-coffee-client/models/operations"; + +let value: UpdateCoffeeTypeRequest = { + typeId: 383441, + coffeeType: { + name: "Flat White", + description: "Espresso with steamed whole milk", + id: 5, + priceMultiplier: 1.25, + }, +}; +``` + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | +| `typeId` | *number* | :heavy_check_mark: | The ID of the coffee type to operate on | | +| `coffeeType` | [components.CoffeeType](../../models/components/coffeetype.md) | :heavy_check_mark: | N/A | {
"name": "Cold Brew",
"description": "Smooth, cold-steeped coffee",
"id": 4,
"price_multiplier": 1.4
} | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/updateorderrequest.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/updateorderrequest.md new file mode 100644 index 0000000..cc3bdc2 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/models/operations/updateorderrequest.md @@ -0,0 +1,25 @@ +# UpdateOrderRequest + +## Example Usage + +```typescript +import { UpdateOrderRequest } from "speakeasy-coffee-client/models/operations"; + +let value: UpdateOrderRequest = { + orderId: 645894, + coffeeOrderUpdate: { + customerName: "Frank", + size: "Small", + extras: [ + "Sugar-free syrup", + ], + }, +}; +``` + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| `orderId` | *number* | :heavy_check_mark: | The ID of the order to operate on | | +| `coffeeOrderUpdate` | [components.CoffeeOrderUpdate](../../models/components/coffeeorderupdate.md) | :heavy_check_mark: | N/A | {
"customer_name": "Frank",
"size": "Small",
"extras": [
"Sugar-free syrup"
]
} | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/sdks/coffeetypes/README.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/sdks/coffeetypes/README.md new file mode 100644 index 0000000..73c049c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/sdks/coffeetypes/README.md @@ -0,0 +1,411 @@ +# CoffeeTypes +(*coffeeTypes*) + +## Overview + +### Available Operations + +* [list](#list) - Get Coffee Types +* [create](#create) - Create Coffee Type +* [getById](#getbyid) - Get Coffee Type +* [update](#update) - Update Coffee Type +* [delete](#delete) - Delete Coffee Type + +## list + +Retrieve all available coffee types. + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.coffeeTypes.list(); + + // Handle the result + console.log(result); +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { coffeeTypesList } from "speakeasy-coffee-client/funcs/coffeeTypesList.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await coffeeTypesList(speakeasyCoffeeClient); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + // Handle the result + console.log(result); +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\<[components.CoffeeType[]](../../models/.md)\>** + +### Errors + +| Error Type | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| errors.APIError | 4XX, 5XX | \*/\* | + +## create + +Create a new coffee type. + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.coffeeTypes.create({ + name: "Cold Brew", + description: "Smooth, cold-steeped coffee", + id: 4, + priceMultiplier: 1.4, + }); + + // Handle the result + console.log(result); +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { coffeeTypesCreate } from "speakeasy-coffee-client/funcs/coffeeTypesCreate.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await coffeeTypesCreate(speakeasyCoffeeClient, { + name: "Cold Brew", + description: "Smooth, cold-steeped coffee", + id: 4, + priceMultiplier: 1.4, + }); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + // Handle the result + console.log(result); +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request` | [components.CoffeeType](../../models/components/coffeetype.md) | :heavy_check_mark: | The request object to use for the request. | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\<[components.CoffeeType](../../models/components/coffeetype.md)\>** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| errors.ErrorResponse | 400 | application/json | +| errors.HTTPValidationError | 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | + +## getById + +Retrieve a specific coffee type by its ID. + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.coffeeTypes.getById({ + typeId: 1, + }); + + // Handle the result + console.log(result); +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { coffeeTypesGetById } from "speakeasy-coffee-client/funcs/coffeeTypesGetById.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await coffeeTypesGetById(speakeasyCoffeeClient, { + typeId: 1, + }); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + // Handle the result + console.log(result); +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request` | [operations.GetCoffeeTypeRequest](../../models/operations/getcoffeetyperequest.md) | :heavy_check_mark: | The request object to use for the request. | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\<[components.CoffeeType](../../models/components/coffeetype.md)\>** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| errors.ErrorResponse | 404 | application/json | +| errors.HTTPValidationError | 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | + +## update + +Update an existing coffee type. + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.coffeeTypes.update({ + typeId: 1, + coffeeType: { + name: "Flat White", + description: "Espresso with steamed whole milk", + id: 5, + priceMultiplier: 1.25, + }, + }); + + // Handle the result + console.log(result); +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { coffeeTypesUpdate } from "speakeasy-coffee-client/funcs/coffeeTypesUpdate.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await coffeeTypesUpdate(speakeasyCoffeeClient, { + typeId: 1, + coffeeType: { + name: "Flat White", + description: "Espresso with steamed whole milk", + id: 5, + priceMultiplier: 1.25, + }, + }); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + // Handle the result + console.log(result); +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request` | [operations.UpdateCoffeeTypeRequest](../../models/operations/updatecoffeetyperequest.md) | :heavy_check_mark: | The request object to use for the request. | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\<[components.CoffeeType](../../models/components/coffeetype.md)\>** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| errors.ErrorResponse | 404 | application/json | +| errors.HTTPValidationError | 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | + +## delete + +Delete a coffee type. + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + await speakeasyCoffeeClient.coffeeTypes.delete({ + typeId: 1, + }); + + +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { coffeeTypesDelete } from "speakeasy-coffee-client/funcs/coffeeTypesDelete.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await coffeeTypesDelete(speakeasyCoffeeClient, { + typeId: 1, + }); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request` | [operations.DeleteCoffeeTypeRequest](../../models/operations/deletecoffeetyperequest.md) | :heavy_check_mark: | The request object to use for the request. | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| errors.ErrorResponse | 404 | application/json | +| errors.HTTPValidationError | 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/sdks/orders/README.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/sdks/orders/README.md new file mode 100644 index 0000000..4aaed3f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/sdks/orders/README.md @@ -0,0 +1,426 @@ +# Orders +(*orders*) + +## Overview + +### Available Operations + +* [list](#list) - Get Orders +* [create](#create) - Create Order +* [getById](#getbyid) - Get Order +* [update](#update) - Update Order +* [delete](#delete) - Delete Order + +## list + +Retrieve all coffee orders. +If 'coffee_type' is provided, returns orders matching that coffee type. + + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Latte", + }); + + // Handle the result + console.log(result); +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { ordersList } from "speakeasy-coffee-client/funcs/ordersList.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await ordersList(speakeasyCoffeeClient, { + coffeeType: "Latte", + }); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + // Handle the result + console.log(result); +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request` | [operations.GetOrdersRequest](../../models/operations/getordersrequest.md) | :heavy_check_mark: | The request object to use for the request. | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\<[components.CoffeeOrder[]](../../models/.md)\>** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| errors.HTTPValidationError | 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | + +## create + +Create a new coffee order. +Validates that the coffee type exists. + + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.create({ + id: 3, + customerName: "Charlie", + coffeeType: "Americano", + size: "Large", + price: 3.75, + }); + + // Handle the result + console.log(result); +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { ordersCreate } from "speakeasy-coffee-client/funcs/ordersCreate.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await ordersCreate(speakeasyCoffeeClient, { + id: 3, + customerName: "Charlie", + coffeeType: "Americano", + size: "Large", + price: 3.75, + }); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + // Handle the result + console.log(result); +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request` | [components.CoffeeOrder](../../models/components/coffeeorder.md) | :heavy_check_mark: | The request object to use for the request. | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\<[components.CoffeeOrder](../../models/components/coffeeorder.md)\>** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| errors.HTTPValidationError | 400, 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | + +## getById + +Retrieve a specific coffee order by its ID. + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.getById({ + orderId: 1, + }); + + // Handle the result + console.log(result); +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { ordersGetById } from "speakeasy-coffee-client/funcs/ordersGetById.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await ordersGetById(speakeasyCoffeeClient, { + orderId: 1, + }); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + // Handle the result + console.log(result); +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request` | [operations.GetOrderRequest](../../models/operations/getorderrequest.md) | :heavy_check_mark: | The request object to use for the request. | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\<[components.CoffeeOrder](../../models/components/coffeeorder.md)\>** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| errors.ErrorResponse | 404 | application/json | +| errors.HTTPValidationError | 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | + +## update + +Update an existing coffee order. + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const result = await speakeasyCoffeeClient.orders.update({ + orderId: 1, + coffeeOrderUpdate: { + coffeeType: "Cappuccino", + extras: [ + "Cinnamon", + "Whipped cream", + ], + price: 5.75, + }, + }); + + // Handle the result + console.log(result); +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { ordersUpdate } from "speakeasy-coffee-client/funcs/ordersUpdate.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await ordersUpdate(speakeasyCoffeeClient, { + orderId: 1, + coffeeOrderUpdate: { + coffeeType: "Cappuccino", + extras: [ + "Cinnamon", + "Whipped cream", + ], + price: 5.75, + }, + }); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + // Handle the result + console.log(result); +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request` | [operations.UpdateOrderRequest](../../models/operations/updateorderrequest.md) | :heavy_check_mark: | The request object to use for the request. | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\<[components.CoffeeOrder](../../models/components/coffeeorder.md)\>** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| errors.ErrorResponse | 404 | application/json | +| errors.HTTPValidationError | 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | + +## delete + +Delete a coffee order. + +### Example Usage + +```typescript +import { SpeakeasyCoffeeClient } from "speakeasy-coffee-client"; + +const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + await speakeasyCoffeeClient.orders.delete({ + orderId: 1, + }); + + +} + +run(); +``` + +### Standalone function + +The standalone function version of this method: + +```typescript +import { SpeakeasyCoffeeClientCore } from "speakeasy-coffee-client/core.js"; +import { ordersDelete } from "speakeasy-coffee-client/funcs/ordersDelete.js"; + +// Use `SpeakeasyCoffeeClientCore` for best tree-shaking performance. +// You can create one instance of it to use across an application. +const speakeasyCoffeeClient = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: "your-api-key-here", +}); + +async function run() { + const res = await ordersDelete(speakeasyCoffeeClient, { + orderId: 1, + }); + + if (!res.ok) { + throw res.error; + } + + const { value: result } = res; + + +} + +run(); +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `request` | [operations.DeleteOrderRequest](../../models/operations/deleteorderrequest.md) | :heavy_check_mark: | The request object to use for the request. | +| `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | +| `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | +| `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | + +### Response + +**Promise\** + +### Errors + +| Error Type | Status Code | Content Type | +| -------------------------- | -------------------------- | -------------------------- | +| errors.ErrorResponse | 404 | application/json | +| errors.HTTPValidationError | 422 | application/json | +| errors.APIError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/sdks/speakeasycoffeeclient/README.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/sdks/speakeasycoffeeclient/README.md new file mode 100644 index 0000000..65db071 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/docs/sdks/speakeasycoffeeclient/README.md @@ -0,0 +1,7 @@ +# SpeakeasyCoffeeClient SDK + +## Overview + +Coffee Orders API: A CRUD API for managing coffee orders and available coffee types. + +### Available Operations diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/eslint.config.mjs b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/eslint.config.mjs new file mode 100644 index 0000000..3483f71 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/eslint.config.mjs @@ -0,0 +1,21 @@ +import globals from "globals"; +import pluginJs from "@eslint/js"; +import tseslint from "typescript-eslint"; + +/** @type {import('eslint').Linter.Config[]} */ +export default [ + { files: ["**/*.{js,mjs,cjs,ts}"] }, + { languageOptions: { globals: globals.browser } }, + pluginJs.configs.recommended, + ...tseslint.configs.recommended, + { + rules: { + "no-constant-condition": "off", + // Handled by typescript compiler + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-empty-object-type": "off", + "@typescript-eslint/no-namespace": "off", + }, + }, +]; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/jsr.json b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/jsr.json new file mode 100644 index 0000000..01cafc3 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/jsr.json @@ -0,0 +1,27 @@ + + +{ + "name": "speakeasy-coffee-client", + "version": "0.1.0", + "exports": { + ".": "./src/index.ts", + "./models/errors": "./src/models/errors/index.ts", + "./models/components": "./src/models/components/index.ts", + "./models/operations": "./src/models/operations/index.ts", + "./lib/config": "./src/lib/config.ts", + "./lib/http": "./src/lib/http.ts", + "./lib/retries": "./src/lib/retries.ts", + "./lib/sdks": "./src/lib/sdks.ts", + "./types": "./src/types/index.ts" + }, + "publish": { + "include": [ + "LICENSE", + "README.md", + "RUNTIMES.md", + "USAGE.md", + "jsr.json", + "src/**/*.ts" + ] + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/package-lock.json b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/package-lock.json new file mode 100644 index 0000000..f50779e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/package-lock.json @@ -0,0 +1,5409 @@ +{ + "name": "speakeasy-coffee-client", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "speakeasy-coffee-client", + "version": "0.1.0", + "bin": { + "mcp": "bin/mcp-server.js" + }, + "devDependencies": { + "@eslint/js": "^9.19.0", + "@modelcontextprotocol/sdk": "^1.5.0", + "@stricli/core": "^1.1.1", + "@types/express": "^4.17.21", + "@types/node": "^18.19.3", + "bun": "^1.2.2", + "bun-types": "^1.2.2", + "eslint": "^9.19.0", + "express": "^4.21.2", + "globals": "^15.14.0", + "tshy": "^2.0.0", + "typescript": "^5.4.5", + "typescript-eslint": "^8.22.0", + "vitest": "^3.0.2", + "zod": "^3.23.4" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.5.0", + "zod": ">= 3" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", + "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", + "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", + "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", + "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", + "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", + "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", + "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", + "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", + "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", + "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", + "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", + "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", + "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", + "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", + "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", + "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", + "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", + "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", + "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", + "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", + "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", + "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", + "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", + "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", + "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz", + "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.12.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.6.1.tgz", + "integrity": "sha512-oxzMzYCkZHMntzuyerehK3fV6A2Kwh5BD6CGEJSVDU2QNEhfLOptf2X7esQgaHZXHZY0oHmMsOtIDLP71UJXgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "cors": "^2.8.5", + "eventsource": "^3.0.2", + "express": "^5.0.1", + "express-rate-limit": "^7.5.0", + "pkce-challenge": "^4.1.0", + "raw-body": "^3.0.0", + "zod": "^3.23.8", + "zod-to-json-schema": "^3.24.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.1.0.tgz", + "integrity": "sha512-/hPxh61E+ll0Ujp24Ilm64cykicul1ypfwjVttduAiEdtnJFvLePSrIPk+HMImtNv5270wOGCb1Tns2rybMkoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.5.2", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/express": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.0.1.tgz", + "integrity": "sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.0.1", + "content-disposition": "^1.0.0", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "^1.2.1", + "debug": "4.3.6", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "^2.0.0", + "fresh": "2.0.0", + "http-errors": "2.0.0", + "merge-descriptors": "^2.0.0", + "methods": "~1.1.2", + "mime-types": "^3.0.0", + "on-finished": "2.4.1", + "once": "1.4.0", + "parseurl": "~1.3.3", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "router": "^2.0.0", + "safe-buffer": "5.2.1", + "send": "^1.1.0", + "serve-static": "^2.1.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "^2.0.0", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/express/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.0.0.tgz", + "integrity": "sha512-MX6Zo2adDViYh+GcxxB1dpO43eypOGUOL12rLCOTMQv/DfIbpSJUy4oQIIZhVZkH9e+bZWKMon0XHFEju16tkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", + "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/mime-db": { + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz", + "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.53.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/send": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", + "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "destroy": "^1.2.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "http-errors": "^2.0.0", + "mime-types": "^2.1.35", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/send/node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/send/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/send/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.1.0.tgz", + "integrity": "sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.0.tgz", + "integrity": "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@oven/bun-darwin-aarch64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.2.4.tgz", + "integrity": "sha512-xBz/Q7X6AFwMg7MXtBemjjt5uB+tvEYBmi9Zbm1r8qnI2V8m/Smuhma0EARhiVfLuIAYj2EM5qjzxeAFV4TBJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oven/bun-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.2.4.tgz", + "integrity": "sha512-ufyty+2754QCFDhq447H39JiqabMlFRItLn1YFp+2hdpKak7KCYLGOUuHnlr1pmImKJzDHURjnvTTq1QRlUWAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oven/bun-darwin-x64-baseline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.2.4.tgz", + "integrity": "sha512-stsq8vBiYgfGunBGlf2M7ST7Ymyw3WnwrxEeJ04vkKmMEEE2LpX8Rkol6UPRvZawab9s9/scFIRgFi6hu9H4SQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oven/bun-linux-aarch64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.2.4.tgz", + "integrity": "sha512-OhVpzme2vvLA7w8GYeJg2SQ2h2CwJQN9oYDiGeoML4EwE+DEoYHdxgaBZsQySOwZtFIr8ufpc/8iD4hssJ50qg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oven/bun-linux-aarch64-musl": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64-musl/-/bun-linux-aarch64-musl-1.2.4.tgz", + "integrity": "sha512-+lxWF7up9MuB1ZdGxXCH3AH3XmYtdBC6soQ38+yg3+y3iOPrAlSG+wytHEkypN/UU2mGvCuaEED3cMvejrGdDw==", + "cpu": [ + "aarch64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oven/bun-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.2.4.tgz", + "integrity": "sha512-oof3ii92Cz2yIOZRbVFHMHmffCutRPFITIdXLZ2/rkqVuKUe0ZdqWjHPhxJFm31AL9MlJ/dSqDbPb51SaLI7tw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oven/bun-linux-x64-baseline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.2.4.tgz", + "integrity": "sha512-3nmDDZJH73MzhBg2sRYioj4CE8wgaz0w24OieMqj4/c44BbNr3X5RewrldsMD2cU6DtVbi52FuD5WpTw3N8nmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oven/bun-linux-x64-musl": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl/-/bun-linux-x64-musl-1.2.4.tgz", + "integrity": "sha512-cLdMbK7srNoUbYSG3Tp4GYdPAO0+5mgUhdbU053GZs0DLQmQ8h1JQhALp+ZjrUWstmQe7ddcNu7l7EAu6E76XA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oven/bun-linux-x64-musl-baseline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl-baseline/-/bun-linux-x64-musl-baseline-1.2.4.tgz", + "integrity": "sha512-qDsUvKCW0WUlVOt6Yx5eEzxgCbvzuSJBsu0sXtr6uGt8TnMKghmliRO5FmiMLQ0k/PUDA8vPJCtuv5k14bDi6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oven/bun-windows-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.2.4.tgz", + "integrity": "sha512-4YRJd4pdaTWEM+uawYmchOeNv874RGAFpIZQubWnN4SBf6HfcDm0OMMZcm0f0I70Wd5gbPg1+rvCRtDZWVmZog==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oven/bun-windows-x64-baseline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.2.4.tgz", + "integrity": "sha512-j/G4bnfsRAiCvpTADda40m29iSGvueIaF9Kc9hBu4jN8dTS9fEXdNNXuf8c30/z7/npxw2dhzsAn8jbc5QvD1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz", + "integrity": "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz", + "integrity": "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", + "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", + "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz", + "integrity": "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz", + "integrity": "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz", + "integrity": "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz", + "integrity": "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", + "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", + "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz", + "integrity": "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz", + "integrity": "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz", + "integrity": "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz", + "integrity": "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz", + "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz", + "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz", + "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz", + "integrity": "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz", + "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@stricli/core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@stricli/core/-/core-1.1.1.tgz", + "integrity": "sha512-pobySbkEtm1x/Kx42EqS9pDi/7ewSfIV3l6P7pPLp1b2ehWyIqfNoLKdWb9nrwnhwrfYwYaCGQMWZgWcgj4UFg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "18.19.79", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.79.tgz", + "integrity": "sha512-90K8Oayimbctc5zTPHPfZloc/lGVs7f3phUAAMcTgEPtg8kKquGZDERC8K4vkBYkQQh48msiYUslYtxTWvqcAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/qs": { + "version": "6.9.18", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", + "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz", + "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.0.tgz", + "integrity": "sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/type-utils": "8.26.0", + "@typescript-eslint/utils": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.0.tgz", + "integrity": "sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.0.tgz", + "integrity": "sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.0.tgz", + "integrity": "sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/utils": "8.26.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.0.tgz", + "integrity": "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.0.tgz", + "integrity": "sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.0.tgz", + "integrity": "sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.0.tgz", + "integrity": "sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.26.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitest/expect": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.7.tgz", + "integrity": "sha512-QP25f+YJhzPfHrHfYHtvRn+uvkCFCqFtW9CktfBxmB+25QqWsx7VB2As6f4GmwllHLDhXNHvqedwhvMmSnNmjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.0.7", + "@vitest/utils": "3.0.7", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.7.tgz", + "integrity": "sha512-qui+3BLz9Eonx4EAuR/i+QlCX6AUZ35taDQgwGkK/Tw6/WgwodSrjN1X2xf69IA/643ZX5zNKIn2svvtZDrs4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.0.7", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.7.tgz", + "integrity": "sha512-CiRY0BViD/V8uwuEzz9Yapyao+M9M008/9oMOSQydwbwb+CMokEq3XVaF3XK/VWaOK0Jm9z7ENhybg70Gtxsmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.7.tgz", + "integrity": "sha512-WeEl38Z0S2ZcuRTeyYqaZtm4e26tq6ZFqh5y8YD9YxfWuu0OFiGFUbnxNynwLjNRHPsXyee2M9tV7YxOTPZl2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.0.7", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.7.tgz", + "integrity": "sha512-eqTUryJWQN0Rtf5yqCGTQWsCFOQe4eNz5Twsu21xYEcnFJtMU5XvmG0vgebhdLlrHQTSq5p8vWHJIeJQV8ovsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.0.7", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.7.tgz", + "integrity": "sha512-4T4WcsibB0B6hrKdAZTM37ekuyFZt2cGbEGd2+L0P8ov15J1/HUsUaqkXEQPNAWr4BtPPe1gI+FYfMHhEKfR8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.7.tgz", + "integrity": "sha512-xePVpCRfooFX3rANQjwoditoXgWb1MaFbzmGuPP59MK6i13mrnDw/yEIyJudLeW6/38mCNcwCiJIGmpDPibAIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.0.7", + "loupe": "^3.1.3", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/body-parser/node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bun": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/bun/-/bun-1.2.4.tgz", + "integrity": "sha512-ZY0EZ/UKqheaLeAtMsfJA6jWoWvV9HAtfFaOJSmS3LrNpFKs1Sg5fZLSsczN1h3a+Dtheo4O3p3ZYWrf40kRGw==", + "cpu": [ + "arm64", + "x64", + "aarch64" + ], + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "os": [ + "darwin", + "linux", + "win32" + ], + "bin": { + "bun": "bin/bun.exe", + "bunx": "bin/bun.exe" + }, + "optionalDependencies": { + "@oven/bun-darwin-aarch64": "1.2.4", + "@oven/bun-darwin-x64": "1.2.4", + "@oven/bun-darwin-x64-baseline": "1.2.4", + "@oven/bun-linux-aarch64": "1.2.4", + "@oven/bun-linux-aarch64-musl": "1.2.4", + "@oven/bun-linux-x64": "1.2.4", + "@oven/bun-linux-x64-baseline": "1.2.4", + "@oven/bun-linux-x64-musl": "1.2.4", + "@oven/bun-linux-x64-musl-baseline": "1.2.4", + "@oven/bun-windows-x64": "1.2.4", + "@oven/bun-windows-x64-baseline": "1.2.4" + } + }, + "node_modules/bun-types": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/bun-types/-/bun-types-1.2.4.tgz", + "integrity": "sha512-nDPymR207ZZEoWD4AavvEaa/KZe/qlrbMSchqpQwovPZCKc7pwMoENjEtHgMKaAjJhy+x6vfqSBA1QU3bJgs0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/ws": "~8.5.10" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", + "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", + "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.0", + "@esbuild/android-arm": "0.25.0", + "@esbuild/android-arm64": "0.25.0", + "@esbuild/android-x64": "0.25.0", + "@esbuild/darwin-arm64": "0.25.0", + "@esbuild/darwin-x64": "0.25.0", + "@esbuild/freebsd-arm64": "0.25.0", + "@esbuild/freebsd-x64": "0.25.0", + "@esbuild/linux-arm": "0.25.0", + "@esbuild/linux-arm64": "0.25.0", + "@esbuild/linux-ia32": "0.25.0", + "@esbuild/linux-loong64": "0.25.0", + "@esbuild/linux-mips64el": "0.25.0", + "@esbuild/linux-ppc64": "0.25.0", + "@esbuild/linux-riscv64": "0.25.0", + "@esbuild/linux-s390x": "0.25.0", + "@esbuild/linux-x64": "0.25.0", + "@esbuild/netbsd-arm64": "0.25.0", + "@esbuild/netbsd-x64": "0.25.0", + "@esbuild/openbsd-arm64": "0.25.0", + "@esbuild/openbsd-x64": "0.25.0", + "@esbuild/sunos-x64": "0.25.0", + "@esbuild/win32-arm64": "0.25.0", + "@esbuild/win32-ia32": "0.25.0", + "@esbuild/win32-x64": "0.25.0" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.21.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz", + "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.21.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventsource": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.5.tgz", + "integrity": "sha512-LT/5J605bx5SNyE+ITBDiM3FxffBiq9un7Vx0EwMDM3vg8sWKx/tO2zC+LMqZ+smAM0F2hblaDZUVZF0te2pSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.0.tgz", + "integrity": "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz", + "integrity": "sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", + "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": "^4.11 || 5 || ^5.0.0-beta.1" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", + "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkce-challenge": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-4.1.0.tgz", + "integrity": "sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/polite-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/polite-json/-/polite-json-5.0.0.tgz", + "integrity": "sha512-OLS/0XeUAcE8a2fdwemNja+udKgXNnY6yKVIXqAD2zVRx1KvY6Ato/rZ2vdzbxqYwPW0u6SCNC/bAMPNzpzxbw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", + "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.6.3", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-import": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/resolve-import/-/resolve-import-1.4.6.tgz", + "integrity": "sha512-CIw9e64QcKcCFUj9+KxUCJPy8hYofv6eVfo3U9wdhCm2E4IjvFnZ6G4/yIC4yP3f11+h6uU5b3LdS7O64LgqrA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^10.3.3", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz", + "integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.34.9", + "@rollup/rollup-android-arm64": "4.34.9", + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-freebsd-arm64": "4.34.9", + "@rollup/rollup-freebsd-x64": "4.34.9", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.9", + "@rollup/rollup-linux-arm-musleabihf": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.9", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", + "@rollup/rollup-linux-riscv64-gnu": "4.34.9", + "@rollup/rollup-linux-s390x-gnu": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-ia32-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9", + "fsevents": "~2.3.2" + } + }, + "node_modules/router": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.1.0.tgz", + "integrity": "sha512-/m/NSLxeYEgWNtyC+WtNHCF7jbGxOibVWKnn+1Psff4dJGOfoXP+MuC/f2CwSmyiHdOIzYnYFp4W6GxWfekaLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/router/node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz", + "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sync-content": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/sync-content/-/sync-content-1.0.2.tgz", + "integrity": "sha512-znd3rYiiSxU3WteWyS9a6FXkTA/Wjk8WQsOyzHbineeL837dLn3DA4MRhsIX3qGcxDMH6+uuFV4axztssk7wEQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^10.2.6", + "mkdirp": "^3.0.1", + "path-scurry": "^1.9.2", + "rimraf": "^5.0.1" + }, + "bin": { + "sync-content": "dist/mjs/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-api-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tshy": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tshy/-/tshy-2.0.1.tgz", + "integrity": "sha512-U5fC+3pMaGfmULhPTVpxKMd62AcX13yfsFrjhAP/daTLG6LFRLIuxqYOmkejJ4MT/s5bEa29+1Jy/9mXkMiMfA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "chalk": "^5.3.0", + "chokidar": "^3.6.0", + "foreground-child": "^3.1.1", + "minimatch": "^9.0.4", + "mkdirp": "^3.0.1", + "polite-json": "^5.0.0", + "resolve-import": "^1.4.5", + "rimraf": "^5.0.1", + "sync-content": "^1.0.2", + "typescript": "5", + "walk-up-path": "^3.0.1" + }, + "bin": { + "tshy": "dist/esm/index.js" + }, + "engines": { + "node": "16 >=16.17 || 18 >=18.15.0 || >=20.6.1" + } + }, + "node_modules/tshy/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/tshy/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/tshy/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.26.0.tgz", + "integrity": "sha512-PtVz9nAnuNJuAVeUFvwztjuUgSnJInODAUx47VDwWPXzd5vismPOtPtt83tzNXyOjVQbPRp786D6WFW/M2koIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.26.0", + "@typescript-eslint/parser": "8.26.0", + "@typescript-eslint/utils": "8.26.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz", + "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "postcss": "^8.5.3", + "rollup": "^4.30.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.7.tgz", + "integrity": "sha512-2fX0QwX4GkkkpULXdT1Pf4q0tC1i1lFOyseKoonavXUNlQ77KpW2XqBGGNIm/J4Ows4KxgGJzDguYVPKwG/n5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.0", + "es-module-lexer": "^1.6.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.7.tgz", + "integrity": "sha512-IP7gPK3LS3Fvn44x30X1dM9vtawm0aesAa2yBIZ9vQf+qB69NXC5776+Qmcr7ohUXIQuLhk7xQR0aSUIDPqavg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "3.0.7", + "@vitest/mocker": "3.0.7", + "@vitest/pretty-format": "^3.0.7", + "@vitest/runner": "3.0.7", + "@vitest/snapshot": "3.0.7", + "@vitest/spy": "3.0.7", + "@vitest/utils": "3.0.7", + "chai": "^5.2.0", + "debug": "^4.4.0", + "expect-type": "^1.1.0", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.0.7", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.0.7", + "@vitest/ui": "3.0.7", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/walk-up-path": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", + "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", + "dev": true, + "license": "ISC" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.24.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", + "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.24.3", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.3.tgz", + "integrity": "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } + } + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/package.json b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/package.json new file mode 100644 index 0000000..cd85e3b --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/package.json @@ -0,0 +1,143 @@ +{ + "name": "speakeasy-coffee-client", + "version": "0.1.0", + "author": "Speakeasy", + "type": "module", + "bin": { + "mcp": "bin/mcp-server.js" + }, + "tshy": { + "sourceDialects": [ + "speakeasy-coffee-client/source" + ], + "exports": { + ".": "./src/index.ts", + "./package.json": "./package.json", + "./types": "./src/types/index.ts", + "./models/errors": "./src/models/errors/index.ts", + "./models/components": "./src/models/components/index.ts", + "./models/operations": "./src/models/operations/index.ts", + "./*.js": "./src/*.ts", + "./*": "./src/*.ts" + } + }, + "sideEffects": false, + "scripts": { + "test": "vitest run src --reporter=junit --outputFile=.speakeasy/reports/tests.xml --reporter=default", + "check": "npm run test && npm run lint", + "lint": "eslint --cache --max-warnings=0 src", + "build:mcp": "bun src/mcp-server/build.mts", + "build": "npm run build:mcp && tshy", + "prepublishOnly": "npm run build" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.5.0", + "zod": ">= 3" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + }, + "devDependencies": { + "@eslint/js": "^9.19.0", + "@modelcontextprotocol/sdk": "^1.5.0", + "@stricli/core": "^1.1.1", + "@types/express": "^4.17.21", + "@types/node": "^18.19.3", + "bun": "^1.2.2", + "bun-types": "^1.2.2", + "eslint": "^9.19.0", + "express": "^4.21.2", + "globals": "^15.14.0", + "tshy": "^2.0.0", + "typescript": "^5.4.5", + "typescript-eslint": "^8.22.0", + "vitest": "^3.0.2", + "zod": "^3.23.4" + }, + "dependencies": {}, + "exports": { + ".": { + "import": { + "speakeasy-coffee-client/source": "./src/index.ts", + "types": "./dist/esm/index.d.ts", + "default": "./dist/esm/index.js" + }, + "require": { + "types": "./dist/commonjs/index.d.ts", + "default": "./dist/commonjs/index.js" + } + }, + "./package.json": "./package.json", + "./types": { + "import": { + "speakeasy-coffee-client/source": "./src/types/index.ts", + "types": "./dist/esm/types/index.d.ts", + "default": "./dist/esm/types/index.js" + }, + "require": { + "types": "./dist/commonjs/types/index.d.ts", + "default": "./dist/commonjs/types/index.js" + } + }, + "./models/errors": { + "import": { + "speakeasy-coffee-client/source": "./src/models/errors/index.ts", + "types": "./dist/esm/models/errors/index.d.ts", + "default": "./dist/esm/models/errors/index.js" + }, + "require": { + "types": "./dist/commonjs/models/errors/index.d.ts", + "default": "./dist/commonjs/models/errors/index.js" + } + }, + "./models/components": { + "import": { + "speakeasy-coffee-client/source": "./src/models/components/index.ts", + "types": "./dist/esm/models/components/index.d.ts", + "default": "./dist/esm/models/components/index.js" + }, + "require": { + "types": "./dist/commonjs/models/components/index.d.ts", + "default": "./dist/commonjs/models/components/index.js" + } + }, + "./models/operations": { + "import": { + "speakeasy-coffee-client/source": "./src/models/operations/index.ts", + "types": "./dist/esm/models/operations/index.d.ts", + "default": "./dist/esm/models/operations/index.js" + }, + "require": { + "types": "./dist/commonjs/models/operations/index.d.ts", + "default": "./dist/commonjs/models/operations/index.js" + } + }, + "./*.js": { + "import": { + "speakeasy-coffee-client/source": "./src/*.ts", + "types": "./dist/esm/*.d.ts", + "default": "./dist/esm/*.js" + }, + "require": { + "types": "./dist/commonjs/*.d.ts", + "default": "./dist/commonjs/*.js" + } + }, + "./*": { + "import": { + "speakeasy-coffee-client/source": "./src/*.ts", + "types": "./dist/esm/*.d.ts", + "default": "./dist/esm/*.js" + }, + "require": { + "types": "./dist/commonjs/*.d.ts", + "default": "./dist/commonjs/*.js" + } + } + }, + "main": "./dist/commonjs/index.js", + "types": "./dist/commonjs/index.d.ts", + "module": "./dist/esm/index.js" +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/assertions.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/assertions.ts new file mode 100644 index 0000000..c05351d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/assertions.ts @@ -0,0 +1,13 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { fail } from "assert"; + +export function assertDefined(value: any): any { + if (value === undefined) { + fail("value is undefined"); + } + + return value; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/coffeetypes.test.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/coffeetypes.test.ts new file mode 100644 index 0000000..a52d1d0 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/coffeetypes.test.ts @@ -0,0 +1,232 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { SpeakeasyCoffeeClient } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Coffeetypes Get Coffee Types Coffee Types", async () => { + const testHttpClient = createTestHTTPClient("GetCoffeeTypes-coffee_types"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.coffeeTypes.list(); + expect(result).toBeDefined(); + expect(result).toEqual([ + { + name: "Espresso", + description: "Strong and bold coffee shot", + id: 1, + priceMultiplier: 1, + }, + { + name: "Latte", + description: "Espresso with steamed milk", + id: 2, + priceMultiplier: 1.2, + }, + { + name: "Mocha", + description: "Espresso with chocolate and steamed milk", + id: 3, + priceMultiplier: 1.3, + }, + ]); +}); + +test("Coffeetypes Create Coffee Type Duplicate Id", async () => { + const testHttpClient = createTestHTTPClient("CreateCoffeeType-duplicate_id"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.coffeeTypes.create({ + name: "Cold Brew", + description: "Smooth, cold-steeped coffee", + id: 4, + priceMultiplier: 1.4, + }); + expect(result).toBeDefined(); +}); + +test("Coffeetypes Get Coffee Type Espresso", async () => { + const testHttpClient = createTestHTTPClient("GetCoffeeType-espresso"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.coffeeTypes.getById({ + typeId: 1, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + name: "Cold Brew", + description: "Smooth, cold-steeped coffee", + id: 4, + priceMultiplier: 1.4, + }); +}); + +test("Coffeetypes Get Coffee Type Latte", async () => { + const testHttpClient = createTestHTTPClient("GetCoffeeType-latte"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.coffeeTypes.getById({ + typeId: 2, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + name: "Flat White", + description: "Espresso with steamed whole milk", + id: 5, + priceMultiplier: 1.25, + }); +}); + +test("Coffeetypes Get Coffee Type Not Found", async () => { + const testHttpClient = createTestHTTPClient("GetCoffeeType-not_found"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.coffeeTypes.getById({ + typeId: 257133, + }); + expect(result).toBeDefined(); +}); + +test("Coffeetypes Update Coffee Type Espresso", async () => { + const testHttpClient = createTestHTTPClient("UpdateCoffeeType-espresso"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.coffeeTypes.update({ + typeId: 1, + coffeeType: { + name: "Flat White", + description: "Espresso with steamed whole milk", + id: 5, + priceMultiplier: 1.25, + }, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + name: "Flat White", + description: "Espresso with steamed whole milk", + id: 5, + priceMultiplier: 1.25, + }); +}); + +test("Coffeetypes Update Coffee Type Latte", async () => { + const testHttpClient = createTestHTTPClient("UpdateCoffeeType-latte"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.coffeeTypes.update({ + typeId: 2, + coffeeType: { + name: "Cold Brew", + description: "Smooth, cold-steeped coffee", + id: 4, + priceMultiplier: 1.4, + }, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + name: "Flat White", + description: "Espresso with steamed whole milk", + id: 5, + priceMultiplier: 1.25, + }); +}); + +test("Coffeetypes Update Coffee Type Not Found", async () => { + const testHttpClient = createTestHTTPClient("UpdateCoffeeType-not_found"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.coffeeTypes.update({ + typeId: 488852, + coffeeType: { + name: "Flat White", + description: "Espresso with steamed whole milk", + id: 5, + priceMultiplier: 1.25, + }, + }); + expect(result).toBeDefined(); +}); + +test("Coffeetypes Delete Coffee Type Espresso", async () => { + const testHttpClient = createTestHTTPClient("DeleteCoffeeType-espresso"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + await speakeasyCoffeeClient.coffeeTypes.delete({ + typeId: 1, + }); +}); + +test("Coffeetypes Delete Coffee Type Latte", async () => { + const testHttpClient = createTestHTTPClient("DeleteCoffeeType-latte"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + await speakeasyCoffeeClient.coffeeTypes.delete({ + typeId: 2, + }); +}); + +test("Coffeetypes Delete Coffee Type Not Found", async () => { + const testHttpClient = createTestHTTPClient("DeleteCoffeeType-not_found"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + await speakeasyCoffeeClient.coffeeTypes.delete({ + typeId: 545907, + }); +}); diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/files.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/files.ts new file mode 100644 index 0000000..f1df32f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/files.ts @@ -0,0 +1,56 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { createReadStream } from "node:fs"; +import { readFile } from "node:fs/promises"; +import { Readable } from "node:stream"; + +export function filesToStream(filePath: string): ReadableStream { + return Readable.toWeb( + createReadStream(filePath), + ) as unknown as ReadableStream; +} + +export async function filesToByteArray(filePath: string): Promise { + return new Uint8Array(await readFile(filePath)); +} + +export async function filesToString(filePath: string): Promise { + return readFile(filePath, "utf8"); +} + +export async function streamToByteArray( + stream?: ReadableStream, +): Promise { + if (!stream) { + return Buffer.from(""); + } + + const chunks = []; + const reader = stream.getReader(); + + let done = false; + while (!done) { + const res = await reader.read(); + done = res.done; + if (res.value) { + chunks.push(res.value); + } + } + + return Buffer.concat(chunks); +} + +export function bytesToStream(bytes: Uint8Array): ReadableStream { + return new ReadableStream({ + start(controller) { + controller.enqueue(bytes); + }, + pull(controller) { + controller.close(); + }, + cancel() { + }, + }); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/Dockerfile b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/Dockerfile new file mode 100644 index 0000000..efdea18 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/Dockerfile @@ -0,0 +1,11 @@ +FROM golang:1.23 + +WORKDIR /usr/src/app + +COPY go.mod go.sum ./ +RUN go mod download && go mod verify +COPY . . +COPY *testdata /usr/local/bin/testdata +RUN go build -v -o /usr/local/bin/mockserver . +EXPOSE 18080 +ENTRYPOINT ["mockserver"] diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/Makefile b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/Makefile new file mode 100644 index 0000000..2ae6a36 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/Makefile @@ -0,0 +1,18 @@ +.PHONY: start + +start: + @if command -v docker >/dev/null 2>&1; then \ + echo "Starting mock server with Docker..."; \ + docker build -t mockserver . && \ + docker run -i -p 18080:18080 -t --rm mockserver; \ + elif command -v go >/dev/null 2>&1; then \ + echo "Docker not found. Starting mock server with Go..."; \ + go run .; \ + else \ + echo "Neither Docker nor Go found. To run the mock server:"; \ + echo "\nOption 1 - Using Docker:"; \ + echo " docker build -t mockserver ."; \ + echo " docker run -i -p 18080:18080 -t --rm mockserver"; \ + echo "\nOption 2 - Using Go:"; \ + echo " go run ."; \ + fi diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/README.md b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/README.md new file mode 100644 index 0000000..c8424fd --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/README.md @@ -0,0 +1,52 @@ +# Mock Server + +A generated HTTP mock server based on your OpenAPI Specification (OAS). Use this mock server for integration and contract testing. + +## Usage + +The server can be built and started via the [Go programming language toolchain](https://go.dev/) or [Docker](https://www.docker.com/). + +If you have Go installed, start the server directly via: + +```shell +go run . +``` + +Otherwise, if you have Docker installed, build and run the server via: + +```shell +docker build -t mockserver . +docker run -i -p 18080:18080 -t --rm mockserver +``` + +By default, the server runs on port `18080`. + +### Server Paths + +The server contains generated paths from the OAS and the following additional built-in paths. + +| Path | Description | +|---|---| +| [`/_mockserver/health`](https://localhost:18080/_mockserver/health) | verify server is running | +| [`/_mockserver/log`](https://localhost:18080/_mockserver/log) | view per-OAS-operation logs | + +Any request outside the generated and built-in paths will return a `404 Not Found` response. + +### Server Customization + +The server supports the following flags for customization. + +| Flag | Default | Description | +|---|---|---| +| `-address` | `:18080` | server listen address | +| `-log-format` | `text` | logging format (supported: `JSON`, `text`) | +| `-log-level` | `INFO` | logging level (supported: `DEBUG`, `INFO`, `WARN`, `ERROR`) | + +For example, enabling server debug logging: + +```shell +# via `go run` +go run . -log-level=DEBUG +# via `docker run` +docker run -i -p 18080:18080 -t --rm mockserver -log-level=DEBUG +``` diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateCoffeeType_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateCoffeeType_1_request new file mode 100644 index 0000000..0956df1 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateCoffeeType_1_request @@ -0,0 +1,16 @@ +POST /coffee-types HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Content-Length: 94 +Content-Type: application/json +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 3CBFC7A5-A291-4B50-6B03-D785F0662EC1 +X-Speakeasy-Test-Name: CreateCoffeeType-duplicate_id + +{"name":"Cold Brew","description":"Smooth, cold-steeped coffee","id":4,"price_multiplier":1.4} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateCoffeeType_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateCoffeeType_1_response new file mode 100644 index 0000000..fb29c97 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateCoffeeType_1_response @@ -0,0 +1,5 @@ +HTTP/1.1 201 Created +Connection: close +Content-Type: application/json + +{"name":"Flat White","description":"Espresso with steamed whole milk","id":5,"price_multiplier":1.25} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_1_request new file mode 100644 index 0000000..7c860cb --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_1_request @@ -0,0 +1,16 @@ +POST /orders HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Content-Length: 88 +Content-Type: application/json +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 16875373-B361-2521-CA6C-047C9121916F +X-Speakeasy-Test-Name: CreateOrder-simple_order + +{"id":3,"customer_name":"Charlie","coffee_type":"Americano","size":"Large","price":3.75} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_1_response new file mode 100644 index 0000000..6028aa0 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_1_response @@ -0,0 +1,5 @@ +HTTP/1.1 201 Created +Connection: close +Content-Type: application/json + +{"id":5,"customer_name":"Eve","coffee_type":"Mocha","size":"Large","extras":["Whipped cream","Chocolate syrup"],"price":6} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_2_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_2_request new file mode 100644 index 0000000..90c42c0 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_2_request @@ -0,0 +1,16 @@ +POST /orders HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Content-Length: 131 +Content-Type: application/json +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: F789EFD4-00B1-8AC7-D606-4D1816691BA5 +X-Speakeasy-Test-Name: CreateOrder-complex_order + +{"id":4,"customer_name":"Diana","coffee_type":"Cappuccino","size":"Medium","extras":["Whipped cream","Caramel syrup"],"price":5.25} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_2_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_2_response new file mode 100644 index 0000000..30f94dd --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/CreateOrder_2_response @@ -0,0 +1,5 @@ +HTTP/1.1 201 Created +Connection: close +Content-Type: application/json + +{"id":6,"customer_name":"Grace","coffee_type":"Cold Brew","size":"Medium","extras":["Vanilla syrup"],"price":5.5} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_1_request new file mode 100644 index 0000000..f19b512 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_1_request @@ -0,0 +1,13 @@ +DELETE /coffee-types/1 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 109114C6-221F-42DA-4AE6-223404F723D2 +X-Speakeasy-Test-Name: DeleteCoffeeType-espresso + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_1_response new file mode 100644 index 0000000..ce45b87 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_1_response @@ -0,0 +1,3 @@ +HTTP/1.1 204 No Content +Connection: close + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_2_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_2_request new file mode 100644 index 0000000..7fa51b0 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_2_request @@ -0,0 +1,13 @@ +DELETE /coffee-types/2 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 01E570A2-A9CF-EF4D-8B65-F117B3D62811 +X-Speakeasy-Test-Name: DeleteCoffeeType-latte + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_2_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_2_response new file mode 100644 index 0000000..ce45b87 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_2_response @@ -0,0 +1,3 @@ +HTTP/1.1 204 No Content +Connection: close + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_3_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_3_request new file mode 100644 index 0000000..74c4abc --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_3_request @@ -0,0 +1,13 @@ +DELETE /coffee-types/545907 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 44B94A41-1212-06E3-0777-DB747C82CC72 +X-Speakeasy-Test-Name: DeleteCoffeeType-not_found + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_3_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_3_response new file mode 100644 index 0000000..ce45b87 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteCoffeeType_3_response @@ -0,0 +1,3 @@ +HTTP/1.1 204 No Content +Connection: close + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_1_request new file mode 100644 index 0000000..073fbed --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_1_request @@ -0,0 +1,13 @@ +DELETE /orders/1 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 069F0A4E-D29E-1940-3445-3F42017C9EB4 +X-Speakeasy-Test-Name: DeleteOrder-order1 + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_1_response new file mode 100644 index 0000000..ce45b87 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_1_response @@ -0,0 +1,3 @@ +HTTP/1.1 204 No Content +Connection: close + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_2_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_2_request new file mode 100644 index 0000000..e6af1df --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_2_request @@ -0,0 +1,13 @@ +DELETE /orders/2 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 88DAC22F-69E3-0FEE-113F-08514B9E28AD +X-Speakeasy-Test-Name: DeleteOrder-order2 + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_2_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_2_response new file mode 100644 index 0000000..ce45b87 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_2_response @@ -0,0 +1,3 @@ +HTTP/1.1 204 No Content +Connection: close + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_3_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_3_request new file mode 100644 index 0000000..bc9fb98 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_3_request @@ -0,0 +1,13 @@ +DELETE /orders/545907 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 5CA24A37-2860-FB9F-B067-57E67C82465A +X-Speakeasy-Test-Name: DeleteOrder-not_found + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_3_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_3_response new file mode 100644 index 0000000..ce45b87 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/DeleteOrder_3_response @@ -0,0 +1,3 @@ +HTTP/1.1 204 No Content +Connection: close + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_1_request new file mode 100644 index 0000000..8b5c4ab --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_1_request @@ -0,0 +1,13 @@ +GET /coffee-types/1 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: BA816281-7BD2-8F12-885A-C02690D81E4D +X-Speakeasy-Test-Name: GetCoffeeType-espresso + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_1_response new file mode 100644 index 0000000..55538b3 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_1_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"name":"Cold Brew","description":"Smooth, cold-steeped coffee","id":4,"price_multiplier":1.4} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_2_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_2_request new file mode 100644 index 0000000..208eb7e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_2_request @@ -0,0 +1,13 @@ +GET /coffee-types/2 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: E85F5D8A-2BB4-E57D-9F26-CECE2561ED17 +X-Speakeasy-Test-Name: GetCoffeeType-latte + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_2_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_2_response new file mode 100644 index 0000000..788788a --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_2_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"name":"Flat White","description":"Espresso with steamed whole milk","id":5,"price_multiplier":1.25} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_3_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_3_request new file mode 100644 index 0000000..9f0cb74 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_3_request @@ -0,0 +1,13 @@ +GET /coffee-types/257133 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 55612313-BA05-9913-FAFF-4358A217212D +X-Speakeasy-Test-Name: GetCoffeeType-not_found + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_3_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_3_response new file mode 100644 index 0000000..55538b3 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeType_3_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"name":"Cold Brew","description":"Smooth, cold-steeped coffee","id":4,"price_multiplier":1.4} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeTypes_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeTypes_1_request new file mode 100644 index 0000000..e1d7569 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeTypes_1_request @@ -0,0 +1,13 @@ +GET /coffee-types HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 7E829A1F-F9FE-76E2-34AB-A4EC217E226A +X-Speakeasy-Test-Name: GetCoffeeTypes-coffee_types + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeTypes_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeTypes_1_response new file mode 100644 index 0000000..3c9a2fb --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetCoffeeTypes_1_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +[{"name":"Espresso","description":"Strong and bold coffee shot","id":1,"price_multiplier":1},{"name":"Latte","description":"Espresso with steamed milk","id":2,"price_multiplier":1.2},{"name":"Mocha","description":"Espresso with chocolate and steamed milk","id":3,"price_multiplier":1.3}] \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_1_request new file mode 100644 index 0000000..bfe9cc7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_1_request @@ -0,0 +1,13 @@ +GET /orders/1 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 17B2A940-71CE-5C40-EC35-5BD14B0E828D +X-Speakeasy-Test-Name: GetOrder-order1 + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_1_response new file mode 100644 index 0000000..2cbc27d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_1_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"id":5,"customer_name":"Eve","coffee_type":"Mocha","size":"Large","extras":["Whipped cream","Chocolate syrup"],"price":6} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_2_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_2_request new file mode 100644 index 0000000..a6cac33 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_2_request @@ -0,0 +1,13 @@ +GET /orders/2 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: B8F7994E-7018-C77B-3B24-C6A7A4736F36 +X-Speakeasy-Test-Name: GetOrder-order2 + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_2_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_2_response new file mode 100644 index 0000000..eccb3b1 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_2_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"id":6,"customer_name":"Grace","coffee_type":"Cold Brew","size":"Medium","extras":["Vanilla syrup"],"price":5.5} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_3_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_3_request new file mode 100644 index 0000000..4e647c7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_3_request @@ -0,0 +1,13 @@ +GET /orders/257133 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: CF644B78-D41C-BFC3-8185-CE2FAE93AA65 +X-Speakeasy-Test-Name: GetOrder-not_found + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_3_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_3_response new file mode 100644 index 0000000..2cbc27d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrder_3_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"id":5,"customer_name":"Eve","coffee_type":"Mocha","size":"Large","extras":["Whipped cream","Chocolate syrup"],"price":6} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_1_request new file mode 100644 index 0000000..309cc65 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_1_request @@ -0,0 +1,13 @@ +GET /orders HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: DCF346D2-4262-5FDF-23A4-C76EE8C3DC1F +X-Speakeasy-Test-Name: GetOrders-multiple_orders + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_1_response new file mode 100644 index 0000000..6f091ae --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_1_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +[{"id":1,"customer_name":"Alice","coffee_type":"Latte","size":"Medium","extras":["Extra shot","Soy milk"],"price":4.5},{"id":2,"customer_name":"Bob","coffee_type":"Espresso","size":"Small","extras":["Extra shot"],"price":3.5}] \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_2_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_2_request new file mode 100644 index 0000000..8d065bb --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_2_request @@ -0,0 +1,13 @@ +GET /orders?coffee_type=Latte HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 9CFB28F0-E3E7-9FCA-C481-0B1A0B093261 +X-Speakeasy-Test-Name: GetOrders-latte + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_2_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_2_response new file mode 100644 index 0000000..ed2821e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_2_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +[{"id":5,"customer_name":"Eve","coffee_type":"Mocha","size":"Large","extras":["Whipped cream","Chocolate syrup"],"price":6},{"id":6,"customer_name":"Grace","coffee_type":"Cold Brew","size":"Medium","extras":["Vanilla syrup"],"price":5.5}] \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_3_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_3_request new file mode 100644 index 0000000..e291076 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_3_request @@ -0,0 +1,13 @@ +GET /orders?coffee_type=Espresso HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 49A33E96-4472-C17E-66AA-074FE5B995A9 +X-Speakeasy-Test-Name: GetOrders-espresso + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_3_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_3_response new file mode 100644 index 0000000..ed2821e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/GetOrders_3_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +[{"id":5,"customer_name":"Eve","coffee_type":"Mocha","size":"Large","extras":["Whipped cream","Chocolate syrup"],"price":6},{"id":6,"customer_name":"Grace","coffee_type":"Cold Brew","size":"Medium","extras":["Vanilla syrup"],"price":5.5}] \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_1_request new file mode 100644 index 0000000..0447709 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_1_request @@ -0,0 +1,16 @@ +PUT /coffee-types/1 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Content-Length: 101 +Content-Type: application/json +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 6C248544-9C04-FE28-256E-B90218659AE4 +X-Speakeasy-Test-Name: UpdateCoffeeType-espresso + +{"name":"Flat White","description":"Espresso with steamed whole milk","id":5,"price_multiplier":1.25} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_1_response new file mode 100644 index 0000000..788788a --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_1_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"name":"Flat White","description":"Espresso with steamed whole milk","id":5,"price_multiplier":1.25} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_2_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_2_request new file mode 100644 index 0000000..bc3e5f5 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_2_request @@ -0,0 +1,16 @@ +PUT /coffee-types/2 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Content-Length: 94 +Content-Type: application/json +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 42511DD4-3A08-63B7-82CD-26C92E1FDF02 +X-Speakeasy-Test-Name: UpdateCoffeeType-latte + +{"name":"Cold Brew","description":"Smooth, cold-steeped coffee","id":4,"price_multiplier":1.4} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_2_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_2_response new file mode 100644 index 0000000..788788a --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_2_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"name":"Flat White","description":"Espresso with steamed whole milk","id":5,"price_multiplier":1.25} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_3_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_3_request new file mode 100644 index 0000000..4bab3ac --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_3_request @@ -0,0 +1,16 @@ +PUT /coffee-types/488852 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Content-Length: 101 +Content-Type: application/json +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 61428712-4D54-1D45-AB2D-FD3B831BDD3F +X-Speakeasy-Test-Name: UpdateCoffeeType-not_found + +{"name":"Flat White","description":"Espresso with steamed whole milk","id":5,"price_multiplier":1.25} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_3_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_3_response new file mode 100644 index 0000000..788788a --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateCoffeeType_3_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"name":"Flat White","description":"Espresso with steamed whole milk","id":5,"price_multiplier":1.25} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_1_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_1_request new file mode 100644 index 0000000..60f9828 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_1_request @@ -0,0 +1,16 @@ +PUT /orders/1 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Content-Length: 79 +Content-Type: application/json +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: FCB59FDF-2BB0-F09F-C6E9-BB3E51632F29 +X-Speakeasy-Test-Name: UpdateOrder-order1 + +{"coffee_type":"Cappuccino","extras":["Cinnamon","Whipped cream"],"price":5.75} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_1_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_1_response new file mode 100644 index 0000000..eccb3b1 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_1_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"id":6,"customer_name":"Grace","coffee_type":"Cold Brew","size":"Medium","extras":["Vanilla syrup"],"price":5.5} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_2_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_2_request new file mode 100644 index 0000000..6ba13c9 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_2_request @@ -0,0 +1,16 @@ +PUT /orders/2 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Content-Length: 70 +Content-Type: application/json +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: 0DB54397-2BDA-6E1F-E18D-792EE9367211 +X-Speakeasy-Test-Name: UpdateOrder-order2 + +{"customer_name":"Frank","size":"Small","extras":["Sugar-free syrup"]} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_2_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_2_response new file mode 100644 index 0000000..eccb3b1 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_2_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"id":6,"customer_name":"Grace","coffee_type":"Cold Brew","size":"Medium","extras":["Vanilla syrup"],"price":5.5} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_3_request b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_3_request new file mode 100644 index 0000000..da54e82 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_3_request @@ -0,0 +1,16 @@ +PUT /orders/488852 HTTP/1.1 +Host: localhost:18080 +Accept: application/json +Accept-Encoding: gzip, deflate +Accept-Language: * +Connection: keep-alive +Content-Length: 79 +Content-Type: application/json +Cookie: +Sec-Fetch-Mode: cors +User-Agent: speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client +X-Api-Key: your-api-key-here +X-Speakeasy-Test-Instance-Id: CA48093F-C379-48F1-7453-64A140440000 +X-Speakeasy-Test-Name: UpdateOrder-not_found + +{"coffee_type":"Cappuccino","extras":["Cinnamon","Whipped cream"],"price":5.75} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_3_response b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_3_response new file mode 100644 index 0000000..eccb3b1 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/_debug/UpdateOrder_3_response @@ -0,0 +1,5 @@ +HTTP/1.1 200 OK +Connection: close +Content-Type: application/json + +{"id":6,"customer_name":"Grace","coffee_type":"Cold Brew","size":"Medium","extras":["Vanilla syrup"],"price":5.5} \ No newline at end of file diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/go.mod b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/go.mod new file mode 100644 index 0000000..38b2d5e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/go.mod @@ -0,0 +1,15 @@ +module mockserver + +go 1.22 + +require ( + github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 + github.com/go-pkgz/expirable-cache/v3 v3.0.0 + github.com/gorilla/mux v1.8.1 +) + +require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/stretchr/testify v1.9.0 // indirect +) diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/go.sum b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/go.sum new file mode 100644 index 0000000..fa86a5f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/go.sum @@ -0,0 +1,16 @@ +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 h1:S92OBrGuLLZsyM5ybUzgc/mPjIYk2AZqufieooe98uw= +github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05/go.mod h1:M9R1FoZ3y//hwwnJtO51ypFGwm8ZfpxPT/ZLtO1mcgQ= +github.com/go-pkgz/expirable-cache/v3 v3.0.0 h1:u3/gcu3sabLYiTCevoRKv+WzjIn5oo7P8XtiXBeRDLw= +github.com/go-pkgz/expirable-cache/v3 v3.0.0/go.mod h1:2OQiDyEGQalYecLWmXprm3maPXeVb5/6/X7yRPYTzec= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/contenttype.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/contenttype.go new file mode 100644 index 0000000..42afbd0 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/contenttype.go @@ -0,0 +1,99 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package assert + +import ( + "fmt" + "mime" + "net/http" + "strings" +) + +func ContentType(req *http.Request, expected string, isRequired bool) error { + got := req.Header.Get("Content-Type") + + if got == "" { + if isRequired { + return fmt.Errorf("expected Content-Type to be set, got: %s", got) + } + return nil + } + + mimeType, _, err := mime.ParseMediaType(got) + if err != nil { + return fmt.Errorf("got Content-Type %s is invalid: %w", got, err) + } + + expectedMimeType, _, err := mime.ParseMediaType(expected) + if err != nil { + return fmt.Errorf("expected Content-Type %s is invalid: %w", expected, err) + } + + if mimeType != expectedMimeType { + return fmt.Errorf( + "expected Content-Type to be %s, got: %s", + expected, + got, + ) + } + + return nil +} + +func AcceptHeader(req *http.Request, expectedValues []string) error { + if len(expectedValues) == 0 { + return nil + } + + gotAccept := req.Header.Get("Accept") + + gotValues := strings.Split(gotAccept, ",") + + for i, gotValue := range gotValues { + mimeType := strings.Split(strings.TrimSpace(gotValue), ";")[0] + + gotMimeType, _, err := mime.ParseMediaType(mimeType) + if err != nil { + return fmt.Errorf("got Accept value %s is invalid: %w", gotValue, err) + } + + gotValues[i] = gotMimeType + } + + allFound := true + + parsedExpectedValues := make([]string, len(expectedValues)) + + for i, expected := range expectedValues { + mimeType := strings.Split(expected, ";")[0] + + expectedMimeType, _, err := mime.ParseMediaType(mimeType) + if err != nil { + return fmt.Errorf("expected Accept value %s is invalid: %w", expected, err) + } + + parsedExpectedValues[i] = expectedMimeType + } + + for _, gotValue := range gotValues { + found := false + + for _, expected := range parsedExpectedValues { + if expected == gotValue { + found = true + break + } + } + + if !found { + allFound = false + break + } + } + + if !allFound { + return fmt.Errorf("expected Accept value to be one of %s, got: %s", strings.Join(parsedExpectedValues, ", "), gotAccept) + } + + return nil +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/header.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/header.go new file mode 100644 index 0000000..50f910d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/header.go @@ -0,0 +1,70 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package assert + +import ( + "fmt" + "net/http" +) + +// HeaderExists generically verifies the given request header name exists with +// a single, non-empty value. If an unexpected value is found, it will return an +// error with a diagnostic text body and which should cause the handler to return +// immediately. +func HeaderExists(req *http.Request, name string) error { + values := req.Header.Values(name) + + if len(values) == 0 { + return fmt.Errorf("missing expected header %s", name) + } + + if len(values) > 1 { + return fmt.Errorf("expected single header for %s, got %d values", name, len(values)) + } + + got := values[0] + + if got == "" { + return fmt.Errorf("expected non-empty header %s", name) + } + + return nil +} + +// HeaderValues generically verifies the given request header name has the +// expected values. If an unexpected value is found, it will return an error +// with a diagnostic text body and which should cause the handler to return +// immediately. +func HeaderValues(req *http.Request, name string, expected []string) error { + got := req.Header.Values(name) + + if len(got) == 0 { + return fmt.Errorf( + "missing expected header %s which should be %v", + name, + expected, + ) + } + + if len(got) != len(expected) { + return fmt.Errorf( + "expected header %s to be %v, got: %v", + name, + expected, + got, + ) + } + + for index, expectedValue := range expected { + if got[index] != expectedValue { + return fmt.Errorf( + "expected header %s to be %v, got: %v", + name, + expected, + got, + ) + } + } + + return nil +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/parameter.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/parameter.go new file mode 100644 index 0000000..f8a5e45 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/parameter.go @@ -0,0 +1,110 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package assert + +import ( + "fmt" + "net/http" + "net/url" +) + +// ParameterHeaderValues verifies the request header parameter key has the +// expected multiple values. If an unexpected value is found, it will return an +// error with a diagnostic text body and which should cause the handler to +// return immediately. +func ParameterHeaderValues(req *http.Request, key string, expected []string) error { + got := req.Header.Values(key) + + if len(got) == 0 { + return fmt.Errorf( + "missing expected header parameter %s which should be %v", + key, + expected, + ) + } + + if len(got) != len(expected) { + return fmt.Errorf( + "expected header parameter %s to be %s, got: %v", + key, + expected, + got, + ) + } + + for index, expectedValue := range expected { + if got[index] != expectedValue { + return fmt.Errorf( + "expected header parameter %s to be %v, got: %v", + key, + expected, + got, + ) + } + } + + return nil +} + +// ParameterPathValue verifies the request path parameter key has the expected +// value. If an unexpected value is found, it will return an error with +// a diagnostic text body and which should cause the handler to +// return immediately. +func ParameterPathValue(req *http.Request, key string, expected string) error { + got := req.PathValue(key) + + if got != expected { + return fmt.Errorf( + "expected path parameter %s to be %s, got: %s", + key, + expected, + got, + ) + } + + return nil +} + +// ParameterQueryValues verifies the request query parameter key has the +// expected multiple values. If an unexpected value is found, it will return an +// error with a diagnostic text body and which should cause the handler to +// return immediately. +func ParameterQueryValues(req *http.Request, key string, expected []string) error { + queryValues, err := url.ParseQuery(req.URL.RawQuery) + + if err != nil { + return fmt.Errorf("error parsing query parameters: %w", err) + } + + got, ok := queryValues[key] + + if !ok || len(got) == 0 { + return fmt.Errorf( + "missing expected query parameter %s which should be %v", + key, + expected, + ) + } + + if len(got) != len(expected) { + return fmt.Errorf( + "expected query parameter %s to be %s, got: %v", + key, + expected, + got, + ) + } + + for index, expectedValue := range expected { + if got[index] != expectedValue { + return fmt.Errorf( + "expected query parameter %s to be %v, got: %v", + key, + expected, + got, + ) + } + } + + return nil +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/pointer.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/pointer.go new file mode 100644 index 0000000..fa03e4c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/pointer.go @@ -0,0 +1,12 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package assert + +// Pointer returns a pointer to the given value. +// +// This is intended to simplify inline builtin value expressions that are not +// implemented in the Go language specification, such as a hypothetical +// &"example". +func Pointer[T any](v T) *T { + return &v +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/security.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/security.go new file mode 100644 index 0000000..7d0a714 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/assert/security.go @@ -0,0 +1,75 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package assert + +import ( + "errors" + "fmt" + "net/http" + "strings" +) + +// SecurityAuthorizationHeader verifies the request security Authorization +// header is present and has the expected HTTP Authorization scheme with a value +// if required. If a missing value or multiple values are found, it will +// return an error with a diagnostic text body and which should cause the +// handler to return immediately. +func SecurityAuthorizationHeader(req *http.Request, optional bool, httpAuthorizationScheme string) error { + values := req.Header.Values("Authorization") + + if len(values) == 0 { + if optional { + return nil + } + + return errors.New("missing expected Authorization header") + } + + if len(values) > 1 { + return fmt.Errorf("expected single Authorization header, got %d values", len(values)) + } + + got := values[0] + + if got == "" { + // Should return error, even if optional, as that represents an errant + // client implementation. + return errors.New("expected non-empty Authorization header") + } + + if httpAuthorizationScheme != "" && !strings.HasPrefix(got, httpAuthorizationScheme+" ") { + return fmt.Errorf("expected HTTP Authorization scheme %s, got: %s", httpAuthorizationScheme, got) + } + + return nil +} + +// SecurityHeader verifies the request security header name is present and has +// a value if required. If a missing value or multiple values are found, it will +// return an error with a diagnostic text body and which should cause the +// handler to return immediately. +func SecurityHeader(req *http.Request, name string, optional bool) error { + values := req.Header.Values(name) + + if len(values) == 0 { + if optional { + return nil + } + + return fmt.Errorf("missing expected security header %s", name) + } + + if len(values) > 1 { + return fmt.Errorf("expected single security header for %s, got %d values", name, len(values)) + } + + got := values[0] + + if got == "" { + // Should return error, even if optional, as that represents an errant + // client implementation. + return fmt.Errorf("expected non-empty security header %s", name) + } + + return nil +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/doc.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/doc.go new file mode 100644 index 0000000..a4e60c8 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/doc.go @@ -0,0 +1,5 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +// Package handlers contains all generated HTTP handlers for the server. They +// are listed via the generated GeneratedHandlers() function. +package handler diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/generated_handler.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/generated_handler.go new file mode 100644 index 0000000..929558e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/generated_handler.go @@ -0,0 +1,35 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "context" + "net/http" +) + +// GeneratedHandler is the type that encapsulates a generated handler. +type GeneratedHandler struct { + // HTTP request handler function. + handlerFunc http.HandlerFunc + + // HTTP method, such as GET. + Method string + + // URL path, such as /path. + Path string +} + +// NewGeneratedHandler creates a generated handler via method, path, and handler +// function. +func NewGeneratedHandler(ctx context.Context, method string, path string, handlerFunc http.HandlerFunc) *GeneratedHandler { + return &GeneratedHandler{ + handlerFunc: handlerFunc, + Method: method, + Path: path, + } +} + +// HandlerFunc returns the underlying HTTP handler function. +func (h GeneratedHandler) HandlerFunc() http.HandlerFunc { + return h.handlerFunc +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/generated_handlers.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/generated_handlers.go new file mode 100644 index 0000000..d33bdb7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/generated_handlers.go @@ -0,0 +1,26 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "context" + "mockserver/internal/logging" + "mockserver/internal/tracking" + "net/http" +) + +// GeneratedHandlers returns all generated handlers. +func GeneratedHandlers(ctx context.Context, dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) []*GeneratedHandler { + return []*GeneratedHandler{ + NewGeneratedHandler(ctx, http.MethodDelete, "/coffee-types/{type_id}", pathDeleteCoffeeTypesTypeID(dir, rt)), + NewGeneratedHandler(ctx, http.MethodDelete, "/orders/{order_id}", pathDeleteOrdersOrderID(dir, rt)), + NewGeneratedHandler(ctx, http.MethodGet, "/coffee-types", pathGetCoffeeTypes(dir, rt)), + NewGeneratedHandler(ctx, http.MethodGet, "/coffee-types/{type_id}", pathGetCoffeeTypesTypeID(dir, rt)), + NewGeneratedHandler(ctx, http.MethodGet, "/orders", pathGetOrders(dir, rt)), + NewGeneratedHandler(ctx, http.MethodGet, "/orders/{order_id}", pathGetOrdersOrderID(dir, rt)), + NewGeneratedHandler(ctx, http.MethodPost, "/coffee-types", pathPostCoffeeTypes(dir, rt)), + NewGeneratedHandler(ctx, http.MethodPost, "/orders", pathPostOrders(dir, rt)), + NewGeneratedHandler(ctx, http.MethodPut, "/coffee-types/{type_id}", pathPutCoffeeTypesTypeID(dir, rt)), + NewGeneratedHandler(ctx, http.MethodPut, "/orders/{order_id}", pathPutOrdersOrderID(dir, rt)), + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathdeletecoffeetypestypeid.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathdeletecoffeetypestypeid.go new file mode 100644 index 0000000..5b2bc53 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathdeletecoffeetypestypeid.go @@ -0,0 +1,92 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/tracking" + "net/http" +) + +func pathDeleteCoffeeTypesTypeID(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "DeleteCoffeeType-espresso[0]": + dir.HandlerFunc("DeleteCoffeeType", testDeleteCoffeeTypeDeleteCoffeeTypeEspresso0)(w, req) + case "DeleteCoffeeType-latte[0]": + dir.HandlerFunc("DeleteCoffeeType", testDeleteCoffeeTypeDeleteCoffeeTypeLatte0)(w, req) + case "DeleteCoffeeType-not_found[0]": + dir.HandlerFunc("DeleteCoffeeType", testDeleteCoffeeTypeDeleteCoffeeTypeNotFound0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testDeleteCoffeeTypeDeleteCoffeeTypeEspresso0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + w.WriteHeader(http.StatusNoContent) +} + +func testDeleteCoffeeTypeDeleteCoffeeTypeLatte0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + w.WriteHeader(http.StatusNoContent) +} + +func testDeleteCoffeeTypeDeleteCoffeeTypeNotFound0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + w.WriteHeader(http.StatusNoContent) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathdeleteordersorderid.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathdeleteordersorderid.go new file mode 100644 index 0000000..7b42e50 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathdeleteordersorderid.go @@ -0,0 +1,92 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/tracking" + "net/http" +) + +func pathDeleteOrdersOrderID(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "DeleteOrder-order1[0]": + dir.HandlerFunc("DeleteOrder", testDeleteOrderDeleteOrderOrder10)(w, req) + case "DeleteOrder-order2[0]": + dir.HandlerFunc("DeleteOrder", testDeleteOrderDeleteOrderOrder20)(w, req) + case "DeleteOrder-not_found[0]": + dir.HandlerFunc("DeleteOrder", testDeleteOrderDeleteOrderNotFound0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testDeleteOrderDeleteOrderOrder10(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + w.WriteHeader(http.StatusNoContent) +} + +func testDeleteOrderDeleteOrderOrder20(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + w.WriteHeader(http.StatusNoContent) +} + +func testDeleteOrderDeleteOrderNotFound0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + w.WriteHeader(http.StatusNoContent) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetcoffeetypes.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetcoffeetypes.go new file mode 100644 index 0000000..3022a40 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetcoffeetypes.go @@ -0,0 +1,82 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/sdk/models/components" + "mockserver/internal/sdk/types" + "mockserver/internal/sdk/utils" + "mockserver/internal/tracking" + "net/http" +) + +func pathGetCoffeeTypes(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "GetCoffeeTypes-coffee_types[0]": + dir.HandlerFunc("GetCoffeeTypes", testGetCoffeeTypesGetCoffeeTypesCoffeeTypes0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testGetCoffeeTypesGetCoffeeTypesCoffeeTypes0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := []components.CoffeeType{ + components.CoffeeType{ + Name: "Espresso", + Description: types.String("Strong and bold coffee shot"), + ID: 1, + PriceMultiplier: types.Float64(1), + }, + components.CoffeeType{ + Name: "Latte", + Description: types.String("Espresso with steamed milk"), + ID: 2, + PriceMultiplier: types.Float64(1.2), + }, + components.CoffeeType{ + Name: "Mocha", + Description: types.String("Espresso with chocolate and steamed milk"), + ID: 3, + PriceMultiplier: types.Float64(1.3), + }, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetcoffeetypestypeid.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetcoffeetypestypeid.go new file mode 100644 index 0000000..36346bd --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetcoffeetypestypeid.go @@ -0,0 +1,146 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/sdk/models/components" + "mockserver/internal/sdk/types" + "mockserver/internal/sdk/utils" + "mockserver/internal/tracking" + "net/http" +) + +func pathGetCoffeeTypesTypeID(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "GetCoffeeType-espresso[0]": + dir.HandlerFunc("GetCoffeeType", testGetCoffeeTypeGetCoffeeTypeEspresso0)(w, req) + case "GetCoffeeType-latte[0]": + dir.HandlerFunc("GetCoffeeType", testGetCoffeeTypeGetCoffeeTypeLatte0)(w, req) + case "GetCoffeeType-not_found[0]": + dir.HandlerFunc("GetCoffeeType", testGetCoffeeTypeGetCoffeeTypeNotFound0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testGetCoffeeTypeGetCoffeeTypeEspresso0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeType{ + Name: "Cold Brew", + Description: types.String("Smooth, cold-steeped coffee"), + ID: 4, + PriceMultiplier: types.Float64(1.4), + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testGetCoffeeTypeGetCoffeeTypeLatte0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeType{ + Name: "Flat White", + Description: types.String("Espresso with steamed whole milk"), + ID: 5, + PriceMultiplier: types.Float64(1.25), + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testGetCoffeeTypeGetCoffeeTypeNotFound0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeType{ + Name: "Cold Brew", + Description: types.String("Smooth, cold-steeped coffee"), + ID: 4, + PriceMultiplier: types.Float64(1.4), + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetorders.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetorders.go new file mode 100644 index 0000000..afbd79e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetorders.go @@ -0,0 +1,196 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/sdk/models/components" + "mockserver/internal/sdk/utils" + "mockserver/internal/tracking" + "net/http" +) + +func pathGetOrders(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "GetOrders-multiple_orders[0]": + dir.HandlerFunc("GetOrders", testGetOrdersGetOrdersMultipleOrders0)(w, req) + case "GetOrders-latte[0]": + dir.HandlerFunc("GetOrders", testGetOrdersGetOrdersLatte0)(w, req) + case "GetOrders-espresso[0]": + dir.HandlerFunc("GetOrders", testGetOrdersGetOrdersEspresso0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testGetOrdersGetOrdersMultipleOrders0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := []components.CoffeeOrder{ + components.CoffeeOrder{ + ID: 1, + CustomerName: "Alice", + CoffeeType: "Latte", + Size: components.CoffeeOrderSizeMedium, + Extras: []string{ + "Extra shot", + "Soy milk", + }, + Price: 4.5, + }, + components.CoffeeOrder{ + ID: 2, + CustomerName: "Bob", + CoffeeType: "Espresso", + Size: components.CoffeeOrderSizeSmall, + Extras: []string{ + "Extra shot", + }, + Price: 3.5, + }, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testGetOrdersGetOrdersLatte0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := []components.CoffeeOrder{ + components.CoffeeOrder{ + ID: 5, + CustomerName: "Eve", + CoffeeType: "Mocha", + Size: components.CoffeeOrderSizeLarge, + Extras: []string{ + "Whipped cream", + "Chocolate syrup", + }, + Price: 6, + }, + components.CoffeeOrder{ + ID: 6, + CustomerName: "Grace", + CoffeeType: "Cold Brew", + Size: components.CoffeeOrderSizeMedium, + Extras: []string{ + "Vanilla syrup", + }, + Price: 5.5, + }, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testGetOrdersGetOrdersEspresso0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := []components.CoffeeOrder{ + components.CoffeeOrder{ + ID: 5, + CustomerName: "Eve", + CoffeeType: "Mocha", + Size: components.CoffeeOrderSizeLarge, + Extras: []string{ + "Whipped cream", + "Chocolate syrup", + }, + Price: 6, + }, + components.CoffeeOrder{ + ID: 6, + CustomerName: "Grace", + CoffeeType: "Cold Brew", + Size: components.CoffeeOrderSizeMedium, + Extras: []string{ + "Vanilla syrup", + }, + Price: 5.5, + }, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetordersorderid.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetordersorderid.go new file mode 100644 index 0000000..2d426de --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathgetordersorderid.go @@ -0,0 +1,159 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/sdk/models/components" + "mockserver/internal/sdk/utils" + "mockserver/internal/tracking" + "net/http" +) + +func pathGetOrdersOrderID(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "GetOrder-order1[0]": + dir.HandlerFunc("GetOrder", testGetOrderGetOrderOrder10)(w, req) + case "GetOrder-order2[0]": + dir.HandlerFunc("GetOrder", testGetOrderGetOrderOrder20)(w, req) + case "GetOrder-not_found[0]": + dir.HandlerFunc("GetOrder", testGetOrderGetOrderNotFound0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testGetOrderGetOrderOrder10(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeOrder{ + ID: 5, + CustomerName: "Eve", + CoffeeType: "Mocha", + Size: components.CoffeeOrderSizeLarge, + Extras: []string{ + "Whipped cream", + "Chocolate syrup", + }, + Price: 6, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testGetOrderGetOrderOrder20(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeOrder{ + ID: 6, + CustomerName: "Grace", + CoffeeType: "Cold Brew", + Size: components.CoffeeOrderSizeMedium, + Extras: []string{ + "Vanilla syrup", + }, + Price: 5.5, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testGetOrderGetOrderNotFound0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeOrder{ + ID: 5, + CustomerName: "Eve", + CoffeeType: "Mocha", + Size: components.CoffeeOrderSizeLarge, + Extras: []string{ + "Whipped cream", + "Chocolate syrup", + }, + Price: 6, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathpostcoffeetypes.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathpostcoffeetypes.go new file mode 100644 index 0000000..36553b7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathpostcoffeetypes.go @@ -0,0 +1,73 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/sdk/models/components" + "mockserver/internal/sdk/types" + "mockserver/internal/sdk/utils" + "mockserver/internal/tracking" + "net/http" +) + +func pathPostCoffeeTypes(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "CreateCoffeeType-duplicate_id[0]": + dir.HandlerFunc("CreateCoffeeType", testCreateCoffeeTypeCreateCoffeeTypeDuplicateId0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testCreateCoffeeTypeCreateCoffeeTypeDuplicateId0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.ContentType(req, "application/json", true); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeType{ + Name: "Flat White", + Description: types.String("Espresso with steamed whole milk"), + ID: 5, + PriceMultiplier: types.Float64(1.25), + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + _, _ = w.Write(respBodyBytes) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathpostorders.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathpostorders.go new file mode 100644 index 0000000..f1fbab8 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathpostorders.go @@ -0,0 +1,125 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/sdk/models/components" + "mockserver/internal/sdk/utils" + "mockserver/internal/tracking" + "net/http" +) + +func pathPostOrders(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "CreateOrder-simple_order[0]": + dir.HandlerFunc("CreateOrder", testCreateOrderCreateOrderSimpleOrder0)(w, req) + case "CreateOrder-complex_order[0]": + dir.HandlerFunc("CreateOrder", testCreateOrderCreateOrderComplexOrder0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testCreateOrderCreateOrderSimpleOrder0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.ContentType(req, "application/json", true); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeOrder{ + ID: 5, + CustomerName: "Eve", + CoffeeType: "Mocha", + Size: components.CoffeeOrderSizeLarge, + Extras: []string{ + "Whipped cream", + "Chocolate syrup", + }, + Price: 6, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + _, _ = w.Write(respBodyBytes) +} + +func testCreateOrderCreateOrderComplexOrder0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.ContentType(req, "application/json", true); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeOrder{ + ID: 6, + CustomerName: "Grace", + CoffeeType: "Cold Brew", + Size: components.CoffeeOrderSizeMedium, + Extras: []string{ + "Vanilla syrup", + }, + Price: 5.5, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + _, _ = w.Write(respBodyBytes) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathputcoffeetypestypeid.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathputcoffeetypestypeid.go new file mode 100644 index 0000000..1b41d0f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathputcoffeetypestypeid.go @@ -0,0 +1,161 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/sdk/models/components" + "mockserver/internal/sdk/types" + "mockserver/internal/sdk/utils" + "mockserver/internal/tracking" + "net/http" +) + +func pathPutCoffeeTypesTypeID(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "UpdateCoffeeType-espresso[0]": + dir.HandlerFunc("UpdateCoffeeType", testUpdateCoffeeTypeUpdateCoffeeTypeEspresso0)(w, req) + case "UpdateCoffeeType-latte[0]": + dir.HandlerFunc("UpdateCoffeeType", testUpdateCoffeeTypeUpdateCoffeeTypeLatte0)(w, req) + case "UpdateCoffeeType-not_found[0]": + dir.HandlerFunc("UpdateCoffeeType", testUpdateCoffeeTypeUpdateCoffeeTypeNotFound0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testUpdateCoffeeTypeUpdateCoffeeTypeEspresso0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.ContentType(req, "application/json", true); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeType{ + Name: "Flat White", + Description: types.String("Espresso with steamed whole milk"), + ID: 5, + PriceMultiplier: types.Float64(1.25), + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testUpdateCoffeeTypeUpdateCoffeeTypeLatte0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.ContentType(req, "application/json", true); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeType{ + Name: "Flat White", + Description: types.String("Espresso with steamed whole milk"), + ID: 5, + PriceMultiplier: types.Float64(1.25), + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testUpdateCoffeeTypeUpdateCoffeeTypeNotFound0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.ContentType(req, "application/json", true); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeType{ + Name: "Flat White", + Description: types.String("Espresso with steamed whole milk"), + ID: 5, + PriceMultiplier: types.Float64(1.25), + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathputordersorderid.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathputordersorderid.go new file mode 100644 index 0000000..d38a949 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/pathputordersorderid.go @@ -0,0 +1,172 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package handler + +import ( + "fmt" + "log" + "mockserver/internal/handler/assert" + "mockserver/internal/logging" + "mockserver/internal/sdk/models/components" + "mockserver/internal/sdk/utils" + "mockserver/internal/tracking" + "net/http" +) + +func pathPutOrdersOrderID(dir *logging.HTTPFileDirectory, rt *tracking.RequestTracker) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + test := req.Header.Get("x-speakeasy-test-name") + instanceID := req.Header.Get("x-speakeasy-test-instance-id") + + count := rt.GetRequestCount(test, instanceID) + + switch fmt.Sprintf("%s[%d]", test, count) { + case "UpdateOrder-order1[0]": + dir.HandlerFunc("UpdateOrder", testUpdateOrderUpdateOrderOrder10)(w, req) + case "UpdateOrder-order2[0]": + dir.HandlerFunc("UpdateOrder", testUpdateOrderUpdateOrderOrder20)(w, req) + case "UpdateOrder-not_found[0]": + dir.HandlerFunc("UpdateOrder", testUpdateOrderUpdateOrderNotFound0)(w, req) + default: + http.Error(w, fmt.Sprintf("Unknown test: %s[%d]", test, count), http.StatusBadRequest) + } + } +} + +func testUpdateOrderUpdateOrderOrder10(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.ContentType(req, "application/json", true); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeOrder{ + ID: 6, + CustomerName: "Grace", + CoffeeType: "Cold Brew", + Size: components.CoffeeOrderSizeMedium, + Extras: []string{ + "Vanilla syrup", + }, + Price: 5.5, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testUpdateOrderUpdateOrderOrder20(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.ContentType(req, "application/json", true); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeOrder{ + ID: 6, + CustomerName: "Grace", + CoffeeType: "Cold Brew", + Size: components.CoffeeOrderSizeMedium, + Extras: []string{ + "Vanilla syrup", + }, + Price: 5.5, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} + +func testUpdateOrderUpdateOrderNotFound0(w http.ResponseWriter, req *http.Request) { + if err := assert.SecurityHeader(req, "X-API-Key", false); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if err := assert.ContentType(req, "application/json", true); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.AcceptHeader(req, []string{"application/json"}); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + if err := assert.HeaderExists(req, "User-Agent"); err != nil { + log.Printf("assertion error: %s\n", err) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + respBody := &components.CoffeeOrder{ + ID: 6, + CustomerName: "Grace", + CoffeeType: "Cold Brew", + Size: components.CoffeeOrderSizeMedium, + Extras: []string{ + "Vanilla syrup", + }, + Price: 5.5, + } + respBodyBytes, err := utils.MarshalJSON(respBody, "", true) + + if err != nil { + http.Error( + w, + "Unable to encode response body as JSON: "+err.Error(), + http.StatusInternalServerError, + ) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, _ = w.Write(respBodyBytes) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/values/files.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/values/files.go new file mode 100644 index 0000000..6eca885 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/handler/values/files.go @@ -0,0 +1,40 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package values + +import ( + "io" + "os" +) + +func ReadFileToStream(fileName string) io.Reader { + s, err := os.Open(fileName) + if err != nil { + panic(err) + } + return s +} + +func ReadFileToBytes(fileName string) []byte { + data, err := os.ReadFile(fileName) + if err != nil { + panic(err) + } + return data +} + +func ReadFileToString(fileName string) string { + data, err := os.ReadFile(fileName) + if err != nil { + panic(err) + } + return string(data) +} + +func ReadBytes(r io.Reader) []byte { + data, err := io.ReadAll(r) + if err != nil { + panic(err) + } + return data +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/doc.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/doc.go new file mode 100644 index 0000000..8835f1c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/doc.go @@ -0,0 +1,4 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +// Package logging contains the implementation and helpers for logging. +package logging diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/formats.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/formats.go new file mode 100644 index 0000000..d6ab53c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/formats.go @@ -0,0 +1,38 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package logging + +import ( + "fmt" + "strings" +) + +const ( + // JSON log format. + FormatJSON = "JSON" + + // Plaintext log format. + FormatText = "text" + + // Default log format. + DefaultFormat = FormatText +) + +// Formats returns all supported formats. +func Formats() []string { + return []string{ + FormatJSON, + FormatText, + } +} + +func formatFromString(format string) (string, error) { + switch format { + case FormatJSON: + return format, nil + case FormatText: + return format, nil + default: + return "", fmt.Errorf("unsupported log format (%s), supported formats: %s", format, strings.Join(Formats(), ", ")) + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/http_file.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/http_file.go new file mode 100644 index 0000000..d690d91 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/http_file.go @@ -0,0 +1,310 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package logging + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io/fs" + "log" + "net/http" + "net/http/httptest" + "net/http/httputil" + "os" + "path/filepath" + "strconv" + "strings" + "sync" +) + +const ( + // DefaultHTTPFileDirectory is the default directory used for raw HTTP + // request and response files. + DefaultHTTPFileDirectory = "_debug" +) + +// HTTPFileDirectory is the directory where raw HTTP request and response files +// are written. +type HTTPFileDirectory struct { + // Filesystem at path. + filesystem fs.FS + + // Mapping of operations to call count. Used to sequentially increment file + // names and return current count. + operationCalls map[string]int64 + + // Mutex to protect operationCalls. + operationCallsMutex *sync.RWMutex + + // Absolute path to directory. + path string +} + +// NewHTTPFileDirectory will create a HTTPFileDirectory which exists and is a +// directory or will return an error. +func NewHTTPFileDirectory(explicitPath string) (*HTTPFileDirectory, error) { + path, err := filepath.Abs(DefaultHTTPFileDirectory) + if err != nil { + return nil, fmt.Errorf("error getting absolute path of HTTP file directory (%s): %w", DefaultHTTPFileDirectory, err) + } + + if explicitPath != "" { + absExplicitPath, err := filepath.Abs(explicitPath) + if err != nil { + return nil, fmt.Errorf("error getting absolute path of HTTP file directory (%s): %w", explicitPath, err) + } + + path = absExplicitPath + } + + result := &HTTPFileDirectory{ + filesystem: os.DirFS(path), + operationCalls: make(map[string]int64), + operationCallsMutex: new(sync.RWMutex), + path: path, + } + + fileInfo, err := os.Stat(path) + + if errors.Is(err, os.ErrNotExist) { + err := os.Mkdir(path, 0o2777) + if err != nil { + return nil, fmt.Errorf("error making HTTP file directory (%s): %w", path, err) + } + + return result, nil + } + + if err != nil { + return nil, fmt.Errorf("error reading HTTP file directory (%s): %w", path, err) + } + + if !fileInfo.IsDir() { + return nil, fmt.Errorf("error using HTTP file directory (%s): not a directory", path) + } + + return result, nil +} + +// Clean will remove all files from HTTPFileDirectory. +func (d *HTTPFileDirectory) Clean() error { + walkDirFunc := func(path string, entry fs.DirEntry, err error) error { + if err != nil { + return fmt.Errorf("error walking %s: %w", d.path, err) + } + + if path == "." { + return nil + } + + if entry.IsDir() { + return fs.SkipDir + } + + absPath := filepath.Join(d.path, path) + + err = os.Remove(absPath) + if err != nil { + return fmt.Errorf("error removing %s: %w", absPath, err) + } + + return nil + } + + return fs.WalkDir(d.filesystem, ".", walkDirFunc) +} + +// HandlerFunc is a HTTP handler that automatically writes the raw HTTP +// request and response to {path}/{operationId}_{call}_request and +// {path}/{operationId}_{call}_response files respectively. +func (d *HTTPFileDirectory) HandlerFunc(operationId string, next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + call := d.nextOperationCall(operationId) + + dump, err := httputil.DumpRequest(req, true) + if err != nil { + log.Printf("error dumping HTTP request: %s", err) + } + + if len(dump) > 0 { + requestPath := filepath.Join(d.path, d.operationCallRequestFilename(operationId, call)) + + err = os.WriteFile(requestPath, dump, 0o644) + if err != nil { + log.Printf("error writing HTTP request file (%s): %s", requestPath, err) + } + } + + recorder := httptest.NewRecorder() + + next(recorder, req) + + dump, err = httputil.DumpResponse(recorder.Result(), true) + if err != nil { + log.Printf("error dumping HTTP response: %s", err) + } + + if len(dump) > 0 { + responsePath := filepath.Join(d.path, d.operationCallResponseFilename(operationId, call)) + err = os.WriteFile(responsePath, dump, 0o644) + if err != nil { + log.Printf("error writing HTTP response file (%s): %s", responsePath, err) + } + } + + recorderToWriter(recorder, w) + } +} + +// Operation will return a new OASOperation from HTTPFileDirectory. +func (d *HTTPFileDirectory) Operation(operationId string) (*OASOperation, error) { + request, err := d.Request(operationId, 1) + if err != nil { + return nil, err + } + + result := NewOASOperation(d, operationId, request.Method, request.URL.Path) + + return result, nil +} + +// Operations will return all detected OASOperation from HTTPFileDirectory. +func (d *HTTPFileDirectory) Operations() ([]*OASOperation, error) { + var result []*OASOperation + + walkDirFunc := func(path string, entry fs.DirEntry, err error) error { + if err != nil { + return fmt.Errorf("error walking %s: %w", d.path, err) + } + + if !strings.HasSuffix(path, "_1_request") { + return nil + } + + operationId := strings.TrimSuffix(path, "_1_request") + operation, err := d.Operation(operationId) + if err != nil { + return err + } + + result = append(result, operation) + + return nil + } + + err := fs.WalkDir(d.filesystem, ".", walkDirFunc) + + return result, err +} + +// OperationCallCount will return the number of detected calls for an +// OASOperation. +func (d *HTTPFileDirectory) OperationCallCount(operationId string) int64 { + d.operationCallsMutex.RLock() + defer d.operationCallsMutex.RUnlock() + + result, ok := d.operationCalls[operationId] + + if ok { + return result + } + + return 0 +} + +// RawRequest returns the raw HTTP request contents as dumped by +// [httputil.DumpRequest]. +func (d *HTTPFileDirectory) RawRequest(operationId string, call int64) ([]byte, error) { + filename := d.operationCallRequestFilename(operationId, call) + file, err := fs.ReadFile(d.filesystem, filename) + if err != nil { + return nil, fmt.Errorf("error reading HTTP request file (%s): %w", filename, err) + } + + return file, nil +} + +// RawResponse returns the raw HTTP response contents as dumped by +// [httputil.DumpResponse]. +func (d *HTTPFileDirectory) RawResponse(operationId string, call int64) ([]byte, error) { + filename := d.operationCallResponseFilename(operationId, call) + file, err := fs.ReadFile(d.filesystem, d.operationCallResponseFilename(operationId, call)) + if err != nil { + return nil, fmt.Errorf("error reading HTTP response file (%s): %w", filename, err) + } + + return file, nil +} + +// Request returns the parsed HTTP request contents. +func (d *HTTPFileDirectory) Request(operationId string, call int64) (*http.Request, error) { + rawRequest, err := d.RawRequest(operationId, call) + if err != nil { + return nil, err + } + + result, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(rawRequest))) + if err != nil { + return nil, fmt.Errorf("error converting HTTP request for operation %s call %d: %w", operationId, call, err) + } + + return result, nil +} + +// Response returns the parsed HTTP response contents. +func (d *HTTPFileDirectory) Response(operationId string, call int64) (*http.Response, error) { + rawResponse, err := d.RawResponse(operationId, call) + if err != nil { + return nil, err + } + + result, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(rawResponse)), nil) + if err != nil { + return nil, fmt.Errorf("error converting HTTP response for operation %s call %d: %w", operationId, call, err) + } + + return result, nil +} + +// nextOperationCall returns the incremented call number for an operation. +func (d *HTTPFileDirectory) nextOperationCall(operationId string) int64 { + d.operationCallsMutex.Lock() + defer d.operationCallsMutex.Unlock() + + var result int64 + + priorCalls, ok := d.operationCalls[operationId] + + if ok { + result = priorCalls + 1 + } else { + // Start call counts at 1 for human consumption. + result = 1 + } + + d.operationCalls[operationId] = result + + return result +} + +// operationCallRequestFilename returns the raw HTTP request file name for the +// given operation and call. +func (d *HTTPFileDirectory) operationCallRequestFilename(operationId string, call int64) string { + return sanitizeOperationIdForFilename(operationId) + "_" + strconv.FormatInt(call, 10) + "_request" +} + +// operationCallResponseFilename returns the raw HTTP response file name for the +// given operation and call. +func (d *HTTPFileDirectory) operationCallResponseFilename(operationId string, call int64) string { + return sanitizeOperationIdForFilename(operationId) + "_" + strconv.FormatInt(call, 10) + "_response" +} + +func sanitizeOperationIdForFilename(operationId string) string { + operationId = strings.ReplaceAll(operationId, "{", "_") + operationId = strings.ReplaceAll(operationId, "}", "_") + operationId = strings.ReplaceAll(operationId, "/", "_") + operationId = strings.ReplaceAll(operationId, " ", "_") + return operationId +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/http_logger.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/http_logger.go new file mode 100644 index 0000000..fdd5d05 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/http_logger.go @@ -0,0 +1,90 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package logging + +import ( + "context" + "fmt" + "log/slog" + "net/http" + "net/http/httptest" + "net/http/httputil" +) + +// HTTPLoggerHandler wraps another [http.Handler] with logging output using the +// provided logger. +func HTTPLoggerHandler(logger *slog.Logger, next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + httpLogger := logger.WithGroup("http") + recorder := httptest.NewRecorder() + reqAttr := slog.Group( + "request", + slog.String("method", req.Method), + slog.String("url", req.URL.RequestURI()), + ) + + if !logger.Enabled(context.Background(), slog.LevelDebug) { + httpLogger.With(reqAttr).Info("received request") + next.ServeHTTP(recorder, req) + + resp := recorder.Result() + respAttr := slog.Group( + "response", + slog.String("status", resp.Status), + ) + + httpLogger.With(reqAttr).With(respAttr).Info("serving response") + + recorderToWriter(recorder, w) + + return + } + + dump, err := httputil.DumpRequest(req, true) + + if err != nil { + http.Error(w, fmt.Sprint(err), http.StatusInternalServerError) + + return + } + + rawReqAttr := slog.Group( + "request", + slog.String("method", req.Method), + slog.String("url", req.URL.RequestURI()), + slog.String("raw", string(dump)), + ) + + httpLogger.With(rawReqAttr).Debug("received request") + + next.ServeHTTP(recorder, req) + + dump, err = httputil.DumpResponse(recorder.Result(), true) + + if err != nil { + http.Error(w, fmt.Sprint(err), http.StatusInternalServerError) + + return + } + + rawRespAttr := slog.Group( + "response", + slog.String("raw", string(dump)), + ) + + // Intentionally use simpler request log attributes + httpLogger.With(reqAttr).With(rawRespAttr).Debug("serving response") + + recorderToWriter(recorder, w) + }) +} + +// recorderToWriter copies the recorded response back to the writer. +func recorderToWriter(recorder *httptest.ResponseRecorder, w http.ResponseWriter) { + for k, v := range recorder.Result().Header { + w.Header()[k] = v + } + + w.WriteHeader(recorder.Code) + _, _ = recorder.Body.WriteTo(w) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/levels.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/levels.go new file mode 100644 index 0000000..d2a8e93 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/levels.go @@ -0,0 +1,55 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package logging + +import ( + "fmt" + "log/slog" + "strings" +) + +const ( + // Debug log level. + LevelDebug = "DEBUG" + + // Info log level. + LevelInfo = "INFO" + + // Warning log level. + LevelWarn = "WARN" + + // Error log level. + LevelError = "ERROR" + + // Default log level. + DefaultLevel = LevelInfo +) + +// Levels returns all supported levels. +func Levels() []string { + return []string{ + LevelDebug, + LevelInfo, + LevelWarn, + LevelError, + } +} + +func levelFromString(level string) (*slog.LevelVar, error) { + result := new(slog.LevelVar) + + switch strings.ToUpper(level) { + case "DEBUG": + result.Set(slog.LevelDebug) + case "INFO": + result.Set(slog.LevelInfo) + case "WARN": + result.Set(slog.LevelWarn) + case "ERROR": + result.Set(slog.LevelError) + default: + return nil, fmt.Errorf("unsupported log level (%s), supported levels: %s", level, strings.Join(Levels(), ", ")) + } + + return result, nil +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/logger.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/logger.go new file mode 100644 index 0000000..bfd6dc7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/logger.go @@ -0,0 +1,40 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package logging + +import ( + "fmt" + "io" + "log/slog" +) + +func NewLogger(w io.Writer, formatStr string, levelStr string) (*slog.Logger, error) { + level, err := levelFromString(levelStr) + + if err != nil { + return nil, err + } + + format, err := formatFromString(formatStr) + + if err != nil { + return nil, err + } + + handlerOpts := &slog.HandlerOptions{ + Level: level, + } + + var handler slog.Handler + + switch format { + case FormatJSON: + handler = slog.NewJSONHandler(w, handlerOpts) + case FormatText: + handler = slog.NewTextHandler(w, handlerOpts) + default: + return nil, fmt.Errorf("unimplemented format: %s", format) + } + + return slog.New(handler), nil +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/oas_operation.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/oas_operation.go new file mode 100644 index 0000000..d4f2af7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/oas_operation.go @@ -0,0 +1,87 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package logging + +import "net/http" + +// OASOperation contains a singular OAS operation. An operation can have one or +// more calls. +type OASOperation struct { + // Underlying HTTP calls for the operation. + calls []*OASOperationCall + + // Directory that contains HTTP request and response logs. + dir *HTTPFileDirectory + + // Operation identifier as defined in OAS. + id string + + // HTTP method for the operation, such as GET. + method string + + // URL path for the operation, such as /path. + path string + + // TODO: Add group +} + +// NewOASOperation creates a new OASOperation. +func NewOASOperation(dir *HTTPFileDirectory, operationId string, method string, path string) *OASOperation { + operationCalls := dir.OperationCallCount(operationId) + result := &OASOperation{ + calls: make([]*OASOperationCall, 0, operationCalls), + dir: dir, + id: operationId, + method: method, + path: path, + } + + for i := range operationCalls { + // Start at 1 for human consumption. + result.calls = append(result.calls, NewOASOperationCall(result, i+1)) + } + + return result +} + +// CallCount returns the number of calls to an operation. +func (o *OASOperation) CallCount() int64 { + return int64(len(o.calls)) +} + +// Id returns the operation identifier as defined in OAS. +func (o *OASOperation) Id() string { + return o.id +} + +// Method returns the HTTP method for the operation, such as GET. +func (o *OASOperation) Method() string { + return o.method +} + +// Path returns the URL path for the operation, such as /path. +func (o *OASOperation) Path() string { + return o.path +} + +// RawRequest returns the raw HTTP request contents as dumped by +// [httputil.DumpRequest]. +func (o *OASOperation) RawRequest(call int64) ([]byte, error) { + return o.dir.RawRequest(o.id, call) +} + +// RawResponse returns the raw HTTP response contents as dumped by +// [httputil.DumpResponse]. +func (o *OASOperation) RawResponse(call int64) ([]byte, error) { + return o.dir.RawResponse(o.id, call) +} + +// Request returns the parsed HTTP request contents. +func (o *OASOperation) Request(call int64) (*http.Request, error) { + return o.dir.Request(o.id, call) +} + +// Response returns the parsed HTTP response contents. +func (o *OASOperation) Response(call int64) (*http.Response, error) { + return o.dir.Response(o.id, call) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/oas_operation_call.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/oas_operation_call.go new file mode 100644 index 0000000..beb0590 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/logging/oas_operation_call.go @@ -0,0 +1,123 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package logging + +import ( + "bufio" + "bytes" + "net/http" +) + +// OASOperationCall contains a singular OAS operation HTTP call. +type OASOperationCall struct { + // The HTTP call number, as determined by the HTTP server. Starts at 1 and + // incremented. + call int64 + + // The associated OAS operation to this call. + operation *OASOperation + + // Parsed HTTP request contents. Cached on first use. + request *http.Request + + // Raw HTTP request contents. Cached on first use. + requestRaw []byte + + // Parsed HTTP response contents. Cached on first use. + response *http.Response + + // Raw HTTP response contents. Cached on first use. + responseRaw []byte + + // TODO: Add test identifier +} + +// NewOASOperationCall creates a new OASOperationCall. +func NewOASOperationCall(operation *OASOperation, call int64) *OASOperationCall { + return &OASOperationCall{ + call: call, + operation: operation, + } +} + +// RawRequest returns the raw HTTP request contents as dumped by +// [httputil.DumpRequest]. +func (c *OASOperationCall) RawRequest() ([]byte, error) { + if c.requestRaw != nil { + return c.requestRaw, nil + } + + requestRaw, err := c.operation.RawRequest(c.call) + + if err != nil { + return nil, err + } + + c.requestRaw = requestRaw + + return c.requestRaw, nil +} + +// RawResponse returns the raw HTTP response contents as dumped by +// [httputil.DumpResponse]. +func (c *OASOperationCall) RawResponse() ([]byte, error) { + if c.responseRaw != nil { + return c.responseRaw, nil + } + + responseRaw, err := c.operation.RawResponse(c.call) + + if err != nil { + return nil, err + } + + c.responseRaw = responseRaw + + return c.responseRaw, nil +} + +// Request returns the parsed HTTP request contents. +func (c *OASOperationCall) Request() (*http.Request, error) { + if c.request != nil { + return c.request, nil + } + + requestRaw, err := c.RawRequest() + + if err != nil { + return nil, err + } + + request, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(requestRaw))) + + if err != nil { + return nil, err + } + + c.request = request + + return c.request, nil +} + +// Response returns the parsed HTTP response contents. +func (c *OASOperationCall) Response() (*http.Response, error) { + if c.response != nil { + return c.response, nil + } + + responseRaw, err := c.RawResponse() + + if err != nil { + return nil, err + } + + response, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(responseRaw)), nil) + + if err != nil { + return nil, err + } + + c.response = response + + return c.response, nil +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/coffeeorder.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/coffeeorder.go new file mode 100644 index 0000000..d1fdcd9 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/coffeeorder.go @@ -0,0 +1,96 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +import ( + "encoding/json" + "fmt" +) + +// CoffeeOrderSize - Size of the coffee order +type CoffeeOrderSize string + +const ( + CoffeeOrderSizeSmall CoffeeOrderSize = "Small" + CoffeeOrderSizeMedium CoffeeOrderSize = "Medium" + CoffeeOrderSizeLarge CoffeeOrderSize = "Large" +) + +func (e CoffeeOrderSize) ToPointer() *CoffeeOrderSize { + return &e +} +func (e *CoffeeOrderSize) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "Small": + fallthrough + case "Medium": + fallthrough + case "Large": + *e = CoffeeOrderSize(v) + return nil + default: + return fmt.Errorf("invalid value for CoffeeOrderSize: %v", v) + } +} + +// CoffeeOrder - Represents a coffee order in the system +type CoffeeOrder struct { + // Unique identifier for the order + ID int64 `json:"id"` + // Name of the customer placing the order + CustomerName string `json:"customer_name"` + // Type of coffee ordered (must match an existing coffee type) + CoffeeType string `json:"coffee_type"` + // Size of the coffee order + Size CoffeeOrderSize `json:"size"` + // Optional additions to the coffee order + Extras []string `json:"extras,omitempty"` + // Total price of the order + Price float64 `json:"price"` +} + +func (o *CoffeeOrder) GetID() int64 { + if o == nil { + return 0 + } + return o.ID +} + +func (o *CoffeeOrder) GetCustomerName() string { + if o == nil { + return "" + } + return o.CustomerName +} + +func (o *CoffeeOrder) GetCoffeeType() string { + if o == nil { + return "" + } + return o.CoffeeType +} + +func (o *CoffeeOrder) GetSize() CoffeeOrderSize { + if o == nil { + return CoffeeOrderSize("") + } + return o.Size +} + +func (o *CoffeeOrder) GetExtras() []string { + if o == nil { + return nil + } + return o.Extras +} + +func (o *CoffeeOrder) GetPrice() float64 { + if o == nil { + return 0.0 + } + return o.Price +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/coffeeorderupdate.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/coffeeorderupdate.go new file mode 100644 index 0000000..982c496 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/coffeeorderupdate.go @@ -0,0 +1,86 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +import ( + "encoding/json" + "fmt" +) + +type CoffeeOrderUpdateSize string + +const ( + CoffeeOrderUpdateSizeSmall CoffeeOrderUpdateSize = "Small" + CoffeeOrderUpdateSizeMedium CoffeeOrderUpdateSize = "Medium" + CoffeeOrderUpdateSizeLarge CoffeeOrderUpdateSize = "Large" +) + +func (e CoffeeOrderUpdateSize) ToPointer() *CoffeeOrderUpdateSize { + return &e +} +func (e *CoffeeOrderUpdateSize) UnmarshalJSON(data []byte) error { + var v string + if err := json.Unmarshal(data, &v); err != nil { + return err + } + switch v { + case "Small": + fallthrough + case "Medium": + fallthrough + case "Large": + *e = CoffeeOrderUpdateSize(v) + return nil + default: + return fmt.Errorf("invalid value for CoffeeOrderUpdateSize: %v", v) + } +} + +// CoffeeOrderUpdate - Model for updating an existing coffee order (all fields optional) +type CoffeeOrderUpdate struct { + // Updated customer name + CustomerName *string `json:"customer_name,omitempty"` + // Updated coffee type (must match an existing coffee type) + CoffeeType *string `json:"coffee_type,omitempty"` + // Updated size of the coffee order + Size *CoffeeOrderUpdateSize `json:"size,omitempty"` + // Updated optional additions to the coffee order + Extras []string `json:"extras,omitempty"` + // Updated total price of the order + Price *float64 `json:"price,omitempty"` +} + +func (o *CoffeeOrderUpdate) GetCustomerName() *string { + if o == nil { + return nil + } + return o.CustomerName +} + +func (o *CoffeeOrderUpdate) GetCoffeeType() *string { + if o == nil { + return nil + } + return o.CoffeeType +} + +func (o *CoffeeOrderUpdate) GetSize() *CoffeeOrderUpdateSize { + if o == nil { + return nil + } + return o.Size +} + +func (o *CoffeeOrderUpdate) GetExtras() []string { + if o == nil { + return nil + } + return o.Extras +} + +func (o *CoffeeOrderUpdate) GetPrice() *float64 { + if o == nil { + return nil + } + return o.Price +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/coffeetype.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/coffeetype.go new file mode 100644 index 0000000..fe3894c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/coffeetype.go @@ -0,0 +1,43 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +// CoffeeType - Represents a type of coffee available in the system +type CoffeeType struct { + // Name of the coffee type + Name string `json:"name"` + // Detailed description of the coffee type + Description *string `json:"description,omitempty"` + // Unique identifier for the coffee type + ID int64 `json:"id"` + // Price multiplier for this coffee type + PriceMultiplier *float64 `json:"price_multiplier,omitempty"` +} + +func (o *CoffeeType) GetName() string { + if o == nil { + return "" + } + return o.Name +} + +func (o *CoffeeType) GetDescription() *string { + if o == nil { + return nil + } + return o.Description +} + +func (o *CoffeeType) GetID() int64 { + if o == nil { + return 0 + } + return o.ID +} + +func (o *CoffeeType) GetPriceMultiplier() *float64 { + if o == nil { + return nil + } + return o.PriceMultiplier +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/httpmetadata.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/httpmetadata.go new file mode 100644 index 0000000..e18bdc0 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/httpmetadata.go @@ -0,0 +1,28 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +import ( + "net/http" +) + +type HTTPMetadata struct { + // Raw HTTP response; suitable for custom response parsing + Response *http.Response `json:"-"` + // Raw HTTP request; suitable for debugging + Request *http.Request `json:"-"` +} + +func (o *HTTPMetadata) GetResponse() *http.Response { + if o == nil { + return nil + } + return o.Response +} + +func (o *HTTPMetadata) GetRequest() *http.Request { + if o == nil { + return nil + } + return o.Request +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/security.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/security.go new file mode 100644 index 0000000..78967c1 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/security.go @@ -0,0 +1,14 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +type Security struct { + APIKeyAuth string `security:"scheme,type=apiKey,subtype=header,name=X-API-Key"` +} + +func (o *Security) GetAPIKeyAuth() string { + if o == nil { + return "" + } + return o.APIKeyAuth +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/validationerror.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/validationerror.go new file mode 100644 index 0000000..86234f3 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/components/validationerror.go @@ -0,0 +1,103 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +import ( + "errors" + "fmt" + "mockserver/internal/sdk/utils" +) + +type LocType string + +const ( + LocTypeStr LocType = "str" + LocTypeInteger LocType = "integer" +) + +type Loc struct { + Str *string + Integer *int64 + + Type LocType +} + +func CreateLocStr(str string) Loc { + typ := LocTypeStr + + return Loc{ + Str: &str, + Type: typ, + } +} + +func CreateLocInteger(integer int64) Loc { + typ := LocTypeInteger + + return Loc{ + Integer: &integer, + Type: typ, + } +} + +func (u *Loc) UnmarshalJSON(data []byte) error { + + var str string = "" + if err := utils.UnmarshalJSON(data, &str, "", true, true); err == nil { + u.Str = &str + u.Type = LocTypeStr + return nil + } + + var integer int64 = int64(0) + if err := utils.UnmarshalJSON(data, &integer, "", true, true); err == nil { + u.Integer = &integer + u.Type = LocTypeInteger + return nil + } + + return fmt.Errorf("could not unmarshal `%s` into any supported union types for Loc", string(data)) +} + +func (u Loc) MarshalJSON() ([]byte, error) { + if u.Str != nil { + return utils.MarshalJSON(u.Str, "", true) + } + + if u.Integer != nil { + return utils.MarshalJSON(u.Integer, "", true) + } + + return nil, errors.New("could not marshal union type Loc: all fields are null") +} + +// ValidationError - Detailed information about a validation error +type ValidationError struct { + // Type of error + Type string `json:"type"` + // Location of the error in the request + Loc []Loc `json:"loc"` + // Error message + Msg string `json:"msg"` +} + +func (o *ValidationError) GetType() string { + if o == nil { + return "" + } + return o.Type +} + +func (o *ValidationError) GetLoc() []Loc { + if o == nil { + return []Loc{} + } + return o.Loc +} + +func (o *ValidationError) GetMsg() string { + if o == nil { + return "" + } + return o.Msg +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/createcoffeetype.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/createcoffeetype.go new file mode 100644 index 0000000..93fefd5 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/createcoffeetype.go @@ -0,0 +1,27 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type CreateCoffeeTypeResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` + // Successful Response + CoffeeType *components.CoffeeType +} + +func (o *CreateCoffeeTypeResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} + +func (o *CreateCoffeeTypeResponse) GetCoffeeType() *components.CoffeeType { + if o == nil { + return nil + } + return o.CoffeeType +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/createorder.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/createorder.go new file mode 100644 index 0000000..7c0e278 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/createorder.go @@ -0,0 +1,27 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type CreateOrderResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` + // Successful Response + CoffeeOrder *components.CoffeeOrder +} + +func (o *CreateOrderResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} + +func (o *CreateOrderResponse) GetCoffeeOrder() *components.CoffeeOrder { + if o == nil { + return nil + } + return o.CoffeeOrder +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/deletecoffeetype.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/deletecoffeetype.go new file mode 100644 index 0000000..0286ede --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/deletecoffeetype.go @@ -0,0 +1,30 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type DeleteCoffeeTypeRequest struct { + // The ID of the coffee type to operate on + TypeID int64 `pathParam:"style=simple,explode=false,name=type_id"` +} + +func (o *DeleteCoffeeTypeRequest) GetTypeID() int64 { + if o == nil { + return 0 + } + return o.TypeID +} + +type DeleteCoffeeTypeResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` +} + +func (o *DeleteCoffeeTypeResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/deleteorder.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/deleteorder.go new file mode 100644 index 0000000..b879a8c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/deleteorder.go @@ -0,0 +1,30 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type DeleteOrderRequest struct { + // The ID of the order to operate on + OrderID int64 `pathParam:"style=simple,explode=false,name=order_id"` +} + +func (o *DeleteOrderRequest) GetOrderID() int64 { + if o == nil { + return 0 + } + return o.OrderID +} + +type DeleteOrderResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` +} + +func (o *DeleteOrderResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getcoffeetype.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getcoffeetype.go new file mode 100644 index 0000000..6355501 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getcoffeetype.go @@ -0,0 +1,39 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type GetCoffeeTypeRequest struct { + // The ID of the coffee type to operate on + TypeID int64 `pathParam:"style=simple,explode=false,name=type_id"` +} + +func (o *GetCoffeeTypeRequest) GetTypeID() int64 { + if o == nil { + return 0 + } + return o.TypeID +} + +type GetCoffeeTypeResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` + // Successful Response + CoffeeType *components.CoffeeType +} + +func (o *GetCoffeeTypeResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} + +func (o *GetCoffeeTypeResponse) GetCoffeeType() *components.CoffeeType { + if o == nil { + return nil + } + return o.CoffeeType +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getcoffeetypes.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getcoffeetypes.go new file mode 100644 index 0000000..cae4d5d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getcoffeetypes.go @@ -0,0 +1,27 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type GetCoffeeTypesResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` + // Successful Response + ResponseGetCoffeeTypesCoffeeTypesGet []components.CoffeeType +} + +func (o *GetCoffeeTypesResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} + +func (o *GetCoffeeTypesResponse) GetResponseGetCoffeeTypesCoffeeTypesGet() []components.CoffeeType { + if o == nil { + return nil + } + return o.ResponseGetCoffeeTypesCoffeeTypesGet +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getorder.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getorder.go new file mode 100644 index 0000000..dbca2ad --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getorder.go @@ -0,0 +1,39 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type GetOrderRequest struct { + // The ID of the order to operate on + OrderID int64 `pathParam:"style=simple,explode=false,name=order_id"` +} + +func (o *GetOrderRequest) GetOrderID() int64 { + if o == nil { + return 0 + } + return o.OrderID +} + +type GetOrderResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` + // Successful Response + CoffeeOrder *components.CoffeeOrder +} + +func (o *GetOrderResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} + +func (o *GetOrderResponse) GetCoffeeOrder() *components.CoffeeOrder { + if o == nil { + return nil + } + return o.CoffeeOrder +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getorders.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getorders.go new file mode 100644 index 0000000..6abe3d6 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/getorders.go @@ -0,0 +1,39 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type GetOrdersRequest struct { + // Optional filter by coffee type (case-insensitive) + CoffeeType *string `queryParam:"style=form,explode=true,name=coffee_type"` +} + +func (o *GetOrdersRequest) GetCoffeeType() *string { + if o == nil { + return nil + } + return o.CoffeeType +} + +type GetOrdersResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` + // Successful Response + ResponseGetOrdersOrdersGet []components.CoffeeOrder +} + +func (o *GetOrdersResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} + +func (o *GetOrdersResponse) GetResponseGetOrdersOrdersGet() []components.CoffeeOrder { + if o == nil { + return nil + } + return o.ResponseGetOrdersOrdersGet +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/updatecoffeetype.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/updatecoffeetype.go new file mode 100644 index 0000000..2ec1418 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/updatecoffeetype.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type UpdateCoffeeTypeRequest struct { + // The ID of the coffee type to operate on + TypeID int64 `pathParam:"style=simple,explode=false,name=type_id"` + CoffeeType components.CoffeeType `request:"mediaType=application/json"` +} + +func (o *UpdateCoffeeTypeRequest) GetTypeID() int64 { + if o == nil { + return 0 + } + return o.TypeID +} + +func (o *UpdateCoffeeTypeRequest) GetCoffeeType() components.CoffeeType { + if o == nil { + return components.CoffeeType{} + } + return o.CoffeeType +} + +type UpdateCoffeeTypeResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` + // Successful Response + CoffeeType *components.CoffeeType +} + +func (o *UpdateCoffeeTypeResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} + +func (o *UpdateCoffeeTypeResponse) GetCoffeeType() *components.CoffeeType { + if o == nil { + return nil + } + return o.CoffeeType +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/updateorder.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/updateorder.go new file mode 100644 index 0000000..ca5931f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/operations/updateorder.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "mockserver/internal/sdk/models/components" +) + +type UpdateOrderRequest struct { + // The ID of the order to operate on + OrderID int64 `pathParam:"style=simple,explode=false,name=order_id"` + CoffeeOrderUpdate components.CoffeeOrderUpdate `request:"mediaType=application/json"` +} + +func (o *UpdateOrderRequest) GetOrderID() int64 { + if o == nil { + return 0 + } + return o.OrderID +} + +func (o *UpdateOrderRequest) GetCoffeeOrderUpdate() components.CoffeeOrderUpdate { + if o == nil { + return components.CoffeeOrderUpdate{} + } + return o.CoffeeOrderUpdate +} + +type UpdateOrderResponse struct { + HTTPMeta components.HTTPMetadata `json:"-"` + // Successful Response + CoffeeOrder *components.CoffeeOrder +} + +func (o *UpdateOrderResponse) GetHTTPMeta() components.HTTPMetadata { + if o == nil { + return components.HTTPMetadata{} + } + return o.HTTPMeta +} + +func (o *UpdateOrderResponse) GetCoffeeOrder() *components.CoffeeOrder { + if o == nil { + return nil + } + return o.CoffeeOrder +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/sdkerrors/errorresponse.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/sdkerrors/errorresponse.go new file mode 100644 index 0000000..9116f6f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/sdkerrors/errorresponse.go @@ -0,0 +1,20 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" +) + +// ErrorResponse - Standard error response format +type ErrorResponse struct { + // Error detail message + Detail string `json:"detail"` +} + +var _ error = &ErrorResponse{} + +func (e *ErrorResponse) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/sdkerrors/httpvalidationerror.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/sdkerrors/httpvalidationerror.go new file mode 100644 index 0000000..065ca86 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/models/sdkerrors/httpvalidationerror.go @@ -0,0 +1,21 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package sdkerrors + +import ( + "encoding/json" + "mockserver/internal/sdk/models/components" +) + +// HTTPValidationError - Error thrown when request validation fails +type HTTPValidationError struct { + // List of validation errors + Detail []components.ValidationError `json:"detail,omitempty"` +} + +var _ error = &HTTPValidationError{} + +func (e *HTTPValidationError) Error() string { + data, _ := json.Marshal(e) + return string(data) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/bigint.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/bigint.go new file mode 100644 index 0000000..9c6a086 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/bigint.go @@ -0,0 +1,21 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package types + +import ( + "fmt" + "math/big" +) + +// MustNewBigIntFromString returns an instance of big.Int from a string +// The string is assumed to be base 10 and if it is not a valid big.Int +// then the function panics. +// Avoid using this function in production code. +func MustNewBigIntFromString(s string) *big.Int { + i, ok := new(big.Int).SetString(s, 10) + if !ok { + panic(fmt.Errorf("failed to parse string as big.Int")) + } + + return i +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/date.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/date.go new file mode 100644 index 0000000..5b2782f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/date.go @@ -0,0 +1,90 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package types + +import ( + "encoding/json" + "fmt" + "strings" + "time" +) + +// Date is a wrapper around time.Time that allows for JSON marshaling a date string formatted as "2006-01-02". +type Date struct { + time.Time +} + +var ( + _ json.Marshaler = &Date{} + _ json.Unmarshaler = &Date{} + _ fmt.Stringer = &Date{} +) + +// NewDate returns an instance of Date from a time.Time. +func NewDate(t time.Time) *Date { + d := DateFromTime(t) + return &d +} + +// DateFromTime returns a Date from a time.Time. +func DateFromTime(t time.Time) Date { + return Date{t} +} + +// NewDateFromString returns an instance of Date from a string formatted as "2006-01-02". +func NewDateFromString(str string) (*Date, error) { + d, err := DateFromString(str) + if err != nil { + return nil, err + } + + return &d, nil +} + +// DateFromString returns a Date from a string formatted as "2006-01-02". +func DateFromString(str string) (Date, error) { + var d Date + var err error + + d.Time, err = time.Parse("2006-01-02", str) + return d, err +} + +// MustNewDateFromString returns an instance of Date from a string formatted as "2006-01-02" or panics. +// Avoid using this function in production code. +func MustNewDateFromString(str string) *Date { + d := MustDateFromString(str) + return &d +} + +// MustDateFromString returns a Date from a string formatted as "2006-01-02" or panics. +// Avoid using this function in production code. +func MustDateFromString(str string) Date { + d, err := DateFromString(str) + if err != nil { + panic(err) + } + return d +} + +func (d Date) GetTime() time.Time { + return d.Time +} + +func (d Date) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf(`"%s"`, d.Time.Format("2006-01-02"))), nil +} + +func (d *Date) UnmarshalJSON(data []byte) error { + var err error + + str := string(data) + str = strings.Trim(str, `"`) + + d.Time, err = time.Parse("2006-01-02", str) + return err +} + +func (d Date) String() string { + return d.Time.Format("2006-01-02") +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/datetime.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/datetime.go new file mode 100644 index 0000000..3eff332 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/datetime.go @@ -0,0 +1,23 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package types + +import "time" + +// MustTimeFromString returns a time.Time from a string formatted as "2006-01-02T15:04:05Z07:00" or panics. +// Avoid using this function in production code. +func MustTimeFromString(str string) time.Time { + t, err := time.Parse(time.RFC3339, str) + if err != nil { + panic(err) + } + + return t +} + +// MustNewTimeFromString returns an instance of time.Time from a string formatted as "2006-01-02T15:04:05Z07:00" or panics. +// Avoid using this function in production code. +func MustNewTimeFromString(str string) *time.Time { + t := MustTimeFromString(str) + return &t +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/decimal.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/decimal.go new file mode 100644 index 0000000..d8429bc --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/decimal.go @@ -0,0 +1,20 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package types + +import ( + "fmt" + + "github.com/ericlagergren/decimal" +) + +// MustNewDecimalFromString returns an instance of Decimal from a string +// Avoid using this function in production code. +func MustNewDecimalFromString(s string) *decimal.Big { + d, ok := new(decimal.Big).SetString(s) + if !ok { + panic(fmt.Errorf("failed to parse string as decimal.Big")) + } + + return d +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/pointers.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/pointers.go new file mode 100644 index 0000000..35c439d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/types/pointers.go @@ -0,0 +1,11 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package types + +func String(s string) *string { return &s } +func Bool(b bool) *bool { return &b } +func Int(i int) *int { return &i } +func Int64(i int64) *int64 { return &i } +func Float32(f float32) *float32 { return &f } +func Float64(f float64) *float64 { return &f } +func Pointer[T any](v T) *T { return &v } diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/utils/json.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/utils/json.go new file mode 100644 index 0000000..f264f1a --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/utils/json.go @@ -0,0 +1,675 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package utils + +import ( + "bytes" + "encoding/json" + "fmt" + "math/big" + "reflect" + "strconv" + "strings" + "time" + "unsafe" + + "mockserver/internal/sdk/types" + + "github.com/ericlagergren/decimal" +) + +func MarshalJSON(v interface{}, tag reflect.StructTag, topLevel bool) ([]byte, error) { + typ, val := dereferencePointers(reflect.TypeOf(v), reflect.ValueOf(v)) + + switch { + case isModelType(typ): + if topLevel { + return json.Marshal(v) + } + + if isNil(typ, val) { + return []byte("null"), nil + } + + out := map[string]json.RawMessage{} + + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + fieldVal := val.Field(i) + + fieldName := field.Name + + omitEmpty := false + jsonTag := field.Tag.Get("json") + if jsonTag != "" { + for _, tag := range strings.Split(jsonTag, ",") { + if tag == "omitempty" { + omitEmpty = true + } else { + fieldName = tag + } + } + } + + if isNil(field.Type, fieldVal) && field.Tag.Get("const") == "" { + if omitEmpty { + continue + } + } + + if !field.IsExported() && field.Tag.Get("const") == "" { + continue + } + + additionalProperties := field.Tag.Get("additionalProperties") + if fieldName == "-" && additionalProperties == "" { + continue + } + + if additionalProperties == "true" { + if isNil(field.Type, fieldVal) { + continue + } + fieldVal := trueReflectValue(fieldVal) + if fieldVal.Type().Kind() != reflect.Map { + return nil, fmt.Errorf("additionalProperties must be a map") + } + + for _, key := range fieldVal.MapKeys() { + r, err := marshalValue(fieldVal.MapIndex(key).Interface(), field.Tag) + if err != nil { + return nil, err + } + + out[key.String()] = r + } + + continue + } + + var fv interface{} + + if field.IsExported() { + fv = fieldVal.Interface() + } else { + pt := reflect.New(typ).Elem() + pt.Set(val) + + pf := pt.Field(i) + + fv = reflect.NewAt(pf.Type(), unsafe.Pointer(pf.UnsafeAddr())).Elem().Interface() + } + + r, err := marshalValue(fv, field.Tag) + if err != nil { + return nil, err + } + + out[fieldName] = r + } + + return json.Marshal(out) + default: + return marshalValue(v, tag) + } +} + +func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool, disallowUnknownFields bool) error { + if reflect.TypeOf(v).Kind() != reflect.Ptr { + return fmt.Errorf("v must be a pointer") + } + + typ, val := dereferencePointers(reflect.TypeOf(v), reflect.ValueOf(v)) + + switch { + case isModelType(typ): + if topLevel || bytes.Equal(b, []byte("null")) { + d := json.NewDecoder(bytes.NewReader(b)) + if disallowUnknownFields { + d.DisallowUnknownFields() + } + return d.Decode(v) + } + + var unmarhsaled map[string]json.RawMessage + + if err := json.Unmarshal(b, &unmarhsaled); err != nil { + return err + } + + var additionalPropertiesField *reflect.StructField + var additionalPropertiesValue *reflect.Value + + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + fieldVal := val.Field(i) + + fieldName := field.Name + + jsonTag := field.Tag.Get("json") + if jsonTag != "" { + for _, tag := range strings.Split(jsonTag, ",") { + if tag != "omitempty" { + fieldName = tag + } + } + } + + if field.Tag.Get("additionalProperties") == "true" { + additionalPropertiesField = &field + additionalPropertiesValue = &fieldVal + continue + } + + // If we receive a value for a const field ignore it but mark it as unmarshaled + if field.Tag.Get("const") != "" { + if r, ok := unmarhsaled[fieldName]; ok { + val := string(r) + + if strings.HasPrefix(val, `"`) && strings.HasSuffix(val, `"`) { + var err error + val, err = strconv.Unquote(val) + if err != nil { + return fmt.Errorf("failed to unquote const field `%s` value `%s`: %w", fieldName, val, err) + } + } + constValue := field.Tag.Get("const") + if val != constValue { + return fmt.Errorf("const field `%s` does not match expected value `%s` got `%s`", fieldName, constValue, val) + } + + delete(unmarhsaled, fieldName) + } + } else if !field.IsExported() { + continue + } + + value, ok := unmarhsaled[fieldName] + if !ok { + defaultTag := field.Tag.Get("default") + if defaultTag != "" { + value = handleDefaultConstValue(defaultTag, fieldVal.Interface(), field.Tag) + ok = true + } + } else { + delete(unmarhsaled, fieldName) + } + + if ok { + if err := unmarshalValue(value, fieldVal, field.Tag, disallowUnknownFields); err != nil { + return err + } + } + } + + keys := make([]string, 0, len(unmarhsaled)) + for k := range unmarhsaled { + keys = append(keys, k) + } + + if len(keys) > 0 { + if disallowUnknownFields && (additionalPropertiesField == nil || additionalPropertiesValue == nil) { + return fmt.Errorf("unknown fields: %v", keys) + } + + if additionalPropertiesField != nil && additionalPropertiesValue != nil { + typeOfMap := additionalPropertiesField.Type + if additionalPropertiesValue.Type().Kind() == reflect.Interface { + typeOfMap = reflect.TypeOf(map[string]interface{}{}) + } else if additionalPropertiesValue.Type().Kind() != reflect.Map { + return fmt.Errorf("additionalProperties must be a map") + } + + mapValue := reflect.MakeMap(typeOfMap) + + for key, value := range unmarhsaled { + val := reflect.New(typeOfMap.Elem()) + + if err := unmarshalValue(value, val, additionalPropertiesField.Tag, disallowUnknownFields); err != nil { + return err + } + + if val.Elem().Type().String() == typeOfMap.Elem().String() { + mapValue.SetMapIndex(reflect.ValueOf(key), val.Elem()) + } else { + mapValue.SetMapIndex(reflect.ValueOf(key), trueReflectValue(val)) + } + + } + if additionalPropertiesValue.Type().Kind() == reflect.Interface { + additionalPropertiesValue.Set(mapValue) + } else { + additionalPropertiesValue.Set(mapValue) + } + } + } + default: + return unmarshalValue(b, reflect.ValueOf(v), tag, disallowUnknownFields) + } + + return nil +} + +func marshalValue(v interface{}, tag reflect.StructTag) (json.RawMessage, error) { + constTag := tag.Get("const") + if constTag != "" { + return handleDefaultConstValue(constTag, v, tag), nil + } + + if isNil(reflect.TypeOf(v), reflect.ValueOf(v)) { + defaultTag := tag.Get("default") + if defaultTag != "" { + return handleDefaultConstValue(defaultTag, v, tag), nil + } + + return []byte("null"), nil + } + + typ, val := dereferencePointers(reflect.TypeOf(v), reflect.ValueOf(v)) + switch typ.Kind() { + case reflect.Int64: + format := tag.Get("integer") + if format == "string" { + b := val.Interface().(int64) + return []byte(fmt.Sprintf(`"%d"`, b)), nil + } + case reflect.Float64: + format := tag.Get("number") + if format == "string" { + b := val.Interface().(float64) + return []byte(fmt.Sprintf(`"%g"`, b)), nil + } + case reflect.Map: + if isNil(typ, val) { + return []byte("null"), nil + } + + out := map[string]json.RawMessage{} + + for _, key := range val.MapKeys() { + itemVal := val.MapIndex(key) + + if isNil(itemVal.Type(), itemVal) { + out[key.String()] = []byte("null") + continue + } + + r, err := marshalValue(itemVal.Interface(), tag) + if err != nil { + return nil, err + } + + out[key.String()] = r + } + + return json.Marshal(out) + case reflect.Slice, reflect.Array: + if isNil(typ, val) { + return []byte("null"), nil + } + + out := []json.RawMessage{} + + for i := 0; i < val.Len(); i++ { + itemVal := val.Index(i) + + if isNil(itemVal.Type(), itemVal) { + out = append(out, []byte("null")) + continue + } + + r, err := marshalValue(itemVal.Interface(), tag) + if err != nil { + return nil, err + } + + out = append(out, r) + } + + return json.Marshal(out) + case reflect.Struct: + switch typ { + case reflect.TypeOf(time.Time{}): + return []byte(fmt.Sprintf(`"%s"`, val.Interface().(time.Time).Format(time.RFC3339Nano))), nil + case reflect.TypeOf(big.Int{}): + format := tag.Get("bigint") + if format == "string" { + b := val.Interface().(big.Int) + return []byte(fmt.Sprintf(`"%s"`, (&b).String())), nil + } + case reflect.TypeOf(decimal.Big{}): + format := tag.Get("decimal") + if format == "number" { + b := val.Interface().(decimal.Big) + f, ok := (&b).Float64() + if ok { + return []byte(b.String()), nil + } + + return []byte(fmt.Sprintf(`%f`, f)), nil + } + } + } + + return json.Marshal(v) +} + +func handleDefaultConstValue(tagValue string, val interface{}, tag reflect.StructTag) json.RawMessage { + if tagValue == "null" { + return []byte("null") + } + + typ := dereferenceTypePointer(reflect.TypeOf(val)) + switch typ { + case reflect.TypeOf(time.Time{}): + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + case reflect.TypeOf(big.Int{}): + bigIntTag := tag.Get("bigint") + if bigIntTag == "string" { + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + } + case reflect.TypeOf(int64(0)): + format := tag.Get("integer") + if format == "string" { + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + } + case reflect.TypeOf(float64(0)): + format := tag.Get("number") + if format == "string" { + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + } + case reflect.TypeOf(decimal.Big{}): + decimalTag := tag.Get("decimal") + if decimalTag != "number" { + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + } + case reflect.TypeOf(types.Date{}): + return []byte(fmt.Sprintf(`"%s"`, tagValue)) + default: + if typ.Kind() == reflect.String { + return []byte(fmt.Sprintf("%q", tagValue)) + } + } + + return []byte(tagValue) +} + +func unmarshalValue(value json.RawMessage, v reflect.Value, tag reflect.StructTag, disallowUnknownFields bool) error { + if bytes.Equal(value, []byte("null")) { + if v.CanAddr() { + return json.Unmarshal(value, v.Addr().Interface()) + } else { + return json.Unmarshal(value, v.Interface()) + } + } + + typ := dereferenceTypePointer(v.Type()) + + switch typ.Kind() { + case reflect.Int64: + var b int64 + + format := tag.Get("integer") + if format == "string" { + var s string + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + var err error + b, err = strconv.ParseInt(s, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse string as int64: %w", err) + } + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(typ)) + } + v = v.Elem() + } + + v.Set(reflect.ValueOf(b)) + return nil + } + case reflect.Float64: + var b float64 + + format := tag.Get("number") + if format == "string" { + var s string + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + var err error + b, err = strconv.ParseFloat(s, 64) + if err != nil { + return fmt.Errorf("failed to parse string as float64: %w", err) + } + + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(typ)) + } + v = v.Elem() + } + + v.Set(reflect.ValueOf(b)) + return nil + } + case reflect.Map: + if bytes.Equal(value, []byte("null")) || !isComplexValueType(dereferenceTypePointer(typ.Elem())) { + if v.CanAddr() { + return json.Unmarshal(value, v.Addr().Interface()) + } else { + return json.Unmarshal(value, v.Interface()) + } + } + + var unmarhsaled map[string]json.RawMessage + + if err := json.Unmarshal(value, &unmarhsaled); err != nil { + return err + } + + m := reflect.MakeMap(typ) + + for k, value := range unmarhsaled { + itemVal := reflect.New(typ.Elem()) + + if err := unmarshalValue(value, itemVal, tag, disallowUnknownFields); err != nil { + return err + } + + m.SetMapIndex(reflect.ValueOf(k), itemVal.Elem()) + } + + v.Set(m) + return nil + case reflect.Slice, reflect.Array: + var unmarshaled []json.RawMessage + + if err := json.Unmarshal(value, &unmarshaled); err != nil { + return err + } + + arrVal := reflect.MakeSlice(typ, len(unmarshaled), len(unmarshaled)) + + for index, value := range unmarshaled { + itemVal := reflect.New(typ.Elem()) + + if err := unmarshalValue(value, itemVal, tag, disallowUnknownFields); err != nil { + return err + } + + arrVal.Index(index).Set(itemVal.Elem()) + } + + if v.Kind() == reflect.Pointer { + if v.IsNil() { + v.Set(reflect.New(typ)) + } + v = v.Elem() + } + + v.Set(arrVal) + return nil + case reflect.Struct: + switch typ { + case reflect.TypeOf(time.Time{}): + var s string + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + t, err := time.Parse(time.RFC3339Nano, s) + if err != nil { + return fmt.Errorf("failed to parse string as time.Time: %w", err) + } + + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(typ)) + } + v = v.Elem() + } + + v.Set(reflect.ValueOf(t)) + return nil + case reflect.TypeOf(big.Int{}): + var b *big.Int + + format := tag.Get("bigint") + if format == "string" { + var s string + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + var ok bool + b, ok = new(big.Int).SetString(s, 10) + if !ok { + return fmt.Errorf("failed to parse string as big.Int") + } + } else { + if err := json.Unmarshal(value, &b); err != nil { + return err + } + } + + if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Ptr { + v = v.Elem() + } + + v.Set(reflect.ValueOf(b)) + return nil + case reflect.TypeOf(decimal.Big{}): + var d *decimal.Big + format := tag.Get("decimal") + if format == "number" { + var ok bool + d, ok = new(decimal.Big).SetString(string(value)) + if !ok { + return fmt.Errorf("failed to parse number as decimal.Big") + } + } else { + if err := json.Unmarshal(value, &d); err != nil { + return err + } + } + + if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Ptr { + v = v.Elem() + } + + v.Set(reflect.ValueOf(d)) + return nil + case reflect.TypeOf(types.Date{}): + var s string + + if err := json.Unmarshal(value, &s); err != nil { + return err + } + + d, err := types.DateFromString(s) + if err != nil { + return fmt.Errorf("failed to parse string as types.Date: %w", err) + } + + if v.Kind() == reflect.Ptr { + if v.IsNil() { + v.Set(reflect.New(typ)) + } + v = v.Elem() + } + + v.Set(reflect.ValueOf(d)) + return nil + } + } + + var val interface{} + + if v.CanAddr() { + val = v.Addr().Interface() + } else { + val = v.Interface() + } + + d := json.NewDecoder(bytes.NewReader(value)) + if disallowUnknownFields { + d.DisallowUnknownFields() + } + return d.Decode(val) +} + +func dereferencePointers(typ reflect.Type, val reflect.Value) (reflect.Type, reflect.Value) { + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } else { + return typ, val + } + + return dereferencePointers(typ, val) +} + +func dereferenceTypePointer(typ reflect.Type) reflect.Type { + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } else { + return typ + } + + return dereferenceTypePointer(typ) +} + +func isComplexValueType(typ reflect.Type) bool { + switch typ.Kind() { + case reflect.Struct: + switch typ { + case reflect.TypeOf(time.Time{}): + fallthrough + case reflect.TypeOf(big.Int{}): + fallthrough + case reflect.TypeOf(decimal.Big{}): + fallthrough + case reflect.TypeOf(types.Date{}): + return true + } + } + + return false +} + +func isModelType(typ reflect.Type) bool { + if isComplexValueType(typ) { + return false + } + + if typ.Kind() == reflect.Struct { + return true + } + + return false +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/utils/reflect.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/utils/reflect.go new file mode 100644 index 0000000..cde47c8 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/utils/reflect.go @@ -0,0 +1,36 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package utils + +import ( + "reflect" +) + +func isNil(typ reflect.Type, val reflect.Value) bool { + // `reflect.TypeOf(nil) == nil` so calling typ.Kind() will cause a nil pointer + // dereference panic. Catch it and return early. + // https://github.com/golang/go/issues/51649 + // https://github.com/golang/go/issues/54208 + if typ == nil { + return true + } + + if typ.Kind() == reflect.Ptr || typ.Kind() == reflect.Map || typ.Kind() == reflect.Slice || typ.Kind() == reflect.Interface { + return val.IsNil() + } + + return false +} + +func trueReflectValue(val reflect.Value) reflect.Value { + kind := val.Type().Kind() + for kind == reflect.Interface || kind == reflect.Ptr { + innerVal := val.Elem() + if !innerVal.IsValid() { + break + } + val = innerVal + kind = val.Type().Kind() + } + return val +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/utils/sort.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/utils/sort.go new file mode 100644 index 0000000..6b265be --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/sdk/utils/sort.go @@ -0,0 +1,94 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package utils + +import ( + "regexp" + "sort" + "strings" +) + +// SortSerializedMaps will sort a given string, []string, or map[string]string +// such that all keys are ordered. This should only be used to simplify testing +// logic. +func SortSerializedMaps(input interface{}, regex string, delim string) interface{} { + sortString := func(input string) string { + r := regexp.MustCompile(regex) + + return replaceAllStringSubmatchFunc(r, input, func(matches []string) string { + result := matches[0] + + for i := 1; i < len(matches); i++ { + match := matches[i] + + pairs := []string{} + if strings.Contains(match, "=") { + pairs = strings.Split(match, delim) + + sort.SliceStable(pairs, func(i, j int) bool { + return strings.Split(pairs[i], "=")[0] < strings.Split(pairs[j], "=")[0] + }) + } else { + values := strings.Split(match, delim) + + if len(values) == 1 { + pairs = values + } else { + pairs = make([]string, len(values)/2) + for i := 0; i < len(values); i += 2 { + pairs[i/2] = values[i] + delim + values[i+1] + } + } + + sort.SliceStable(pairs, func(i, j int) bool { + return strings.Split(pairs[i], delim)[0] < strings.Split(pairs[j], delim)[0] + }) + } + + match = strings.Join(pairs, delim) + + result = strings.Replace(result, matches[i], match, 1) + } + + return result + }) + } + + switch input := input.(type) { + case string: + return sortString(input) + case []string: + for i, v := range input { + input[i] = sortString(v) + } + return input + case map[string]string: + for k, v := range input { + input[k] = sortString(v) + } + return input + default: + panic("unsupported type") + } +} + +func replaceAllStringSubmatchFunc(re *regexp.Regexp, str string, repl func([]string) string) string { + result := "" + lastIndex := 0 + + for _, v := range re.FindAllSubmatchIndex([]byte(str), -1) { + groups := []string{} + for i := 0; i < len(v); i += 2 { + if v[i] == -1 || v[i+1] == -1 { + groups = append(groups, "") + } else { + groups = append(groups, str[v[i]:v[i+1]]) + } + } + + result += str[lastIndex:v[0]] + repl(groups) + lastIndex = v[1] + } + + return result + str[lastIndex:] +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/doc.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/doc.go new file mode 100644 index 0000000..666dc10 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/doc.go @@ -0,0 +1,4 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +// Package server implements the HTTP server. +package server diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/generated_handlers.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/generated_handlers.go new file mode 100644 index 0000000..1ea1635 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/generated_handlers.go @@ -0,0 +1,17 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package server + +import ( + "context" + + "mockserver/internal/handler" +) + +func (s *Server) registerGeneratedHandlers(ctx context.Context) { + s.logger.Debug("registering generated handlers") + + for _, h := range handler.GeneratedHandlers(ctx, s.httpFileDir, s.requestTracker) { + s.RegisterHandlerFunc(ctx, []string{h.Method}, h.Path, h.HandlerFunc()) + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/internal_handlers.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/internal_handlers.go new file mode 100644 index 0000000..1c24861 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/internal_handlers.go @@ -0,0 +1,343 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package server + +import ( + "bytes" + "context" + "fmt" + "html/template" + "io" + "net/http" + "path/filepath" + "strings" +) + +const ( + // Mock server internal route prefix to prevent naming collisions. + internalPathPrefix = "/_mockserver" +) + +// registerInternalHandlers adds any internal handlers, such as healthcheck +// endpoints and fallback handling. +func (s *Server) registerInternalHandlers(ctx context.Context) { + s.logger.Debug("registering internal handlers") + + // Healthcheck endpoint + s.RegisterHandlerFunc(ctx, []string{http.MethodGet}, internalPathPrefix+"/health", healthcheckHandler) + + // HTTP log index endpoint + s.RegisterHandlerFunc(ctx, []string{http.MethodGet}, internalPathPrefix+"/log", s.httpFileIndexHandler) + + // HTTP log operation endpoint + s.RegisterHandlerFunc(ctx, []string{http.MethodGet}, internalPathPrefix+"/log/{operationId}", s.httpOperationHandler) + + // Default all other requests to 404 Not Found + s.RegisterHandlerFunc(ctx, []string{}, "/", rootHandler) +} + +// healthcheckHandler returns a simple OK response. +func healthcheckHandler(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "text/plain; charset=utf-8") + w.WriteHeader(http.StatusOK) + fmt.Fprintln(w, "OK") +} + +// httpFileIndexHandler returns a HTML index page for all logged HTTP operations +// written to the HTTP file directory. +func (s *Server) httpFileIndexHandler(w http.ResponseWriter, _ *http.Request) { + operations, err := s.httpFileDir.Operations() + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation log error: %s", err), + http.StatusInternalServerError, + ) + + return + } + + type operationModel struct { + CallCount int64 + ID string + LogURL string + Method string + Path string + } + + type indexModel struct { + Operations []operationModel + } + + var index indexModel + + for _, operation := range operations { + index.Operations = append(index.Operations, operationModel{ + CallCount: operation.CallCount(), + ID: operation.Id(), + LogURL: internalPathPrefix + "/log/" + operation.Id(), + Method: operation.Method(), + Path: operation.Path(), + }) + } + + tmpl := template.New("index.html.tmpl") + tmpl.Funcs(template.FuncMap{ + "mod": func(i, j int) bool { return i%j == 0 }, + }) + _, err = tmpl.ParseFiles( + filepath.Join("internal", "server", "templates", "log", "style.css.tmpl"), + filepath.Join("internal", "server", "templates", "log", "index.html.tmpl"), + ) + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation log template error: %s", err), + http.StatusInternalServerError, + ) + + return + } + + var wBuf bytes.Buffer + + err = tmpl.Execute(&wBuf, index) + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation log template execution error: %s", err), + http.StatusInternalServerError, + ) + + return + } + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusOK) + _, _ = wBuf.WriteTo(w) +} + +// httpOperationHandler returns a HTML page for HTTP request and response log files +// written to _debug. +func (s *Server) httpOperationHandler(w http.ResponseWriter, req *http.Request) { + operationId := req.PathValue("operationId") + + if operationId == "" { + http.Error(w, "operation logs not found", http.StatusNotFound) + + return + } + + operation, err := s.httpFileDir.Operation(operationId) + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation %s log error: %s", operationId, err), + http.StatusInternalServerError, + ) + + return + } + + type headerModel struct { + Key string + Values template.HTML + } + + type queryParameterModel struct { + Key string + Values template.HTML + } + + type operationCallModel struct { + Call int64 + ID string + LogOperationURL string + + RawRequest template.HTML + RawResponse template.HTML + + RequestBody string + RequestHeaders []headerModel + RequestQueryParameters []queryParameterModel + + ResponseBody string + ResponseHeaders []headerModel + ResponseStatus string + } + + type operationDataModel struct { + Calls []operationCallModel + ID string + LogIndexURL string + RequestMethod string + RequestPath string + } + + operationData := operationDataModel{ + ID: operationId, + LogIndexURL: internalPathPrefix + "/log", + RequestMethod: operation.Method(), + RequestPath: operation.Path(), + } + + for i := range operation.CallCount() { + call := i + 1 + + callReqRaw, err := operation.RawRequest(call) + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation %s call %d log raw request error: %s", operationId, call, err), + http.StatusInternalServerError, + ) + + return + } + + callReq, err := operation.Request(call) + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation %s call %d log request error: %s", operationId, call, err), + http.StatusInternalServerError, + ) + + return + } + + callReqBody, err := io.ReadAll(callReq.Body) + defer callReq.Body.Close() + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation %s call %d log request body error: %s", operationId, call, err), + http.StatusInternalServerError, + ) + + return + } + + callRespRaw, err := operation.RawResponse(call) + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation %s call %d log response error: %s", operationId, call, err), + http.StatusInternalServerError, + ) + + return + } + + callResp, err := operation.Response(call) + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation %s call %d log response error: %s", operationId, call, err), + http.StatusInternalServerError, + ) + + return + } + + callRespBody, err := io.ReadAll(callResp.Body) + defer callReq.Body.Close() + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation %s call %d log response body error: %s", operationId, call, err), + http.StatusInternalServerError, + ) + + return + } + + operationCall := operationCallModel{ + Call: call, + LogOperationURL: internalPathPrefix + "/log/" + operationId, + + RawRequest: template.HTML(strings.ReplaceAll(string(callReqRaw), "\r\n", "
")), + RawResponse: template.HTML(strings.ReplaceAll(string(callRespRaw), "\r\n", "
")), + + RequestBody: string(callReqBody), + ResponseBody: string(callRespBody), + ResponseStatus: callResp.Status, + } + + for key, values := range callReq.URL.Query() { + operationCall.RequestQueryParameters = append(operationCall.RequestQueryParameters, queryParameterModel{ + Key: key, + Values: template.HTML(strings.Join(values, "
")), + }) + } + + for key, values := range callReq.Header { + operationCall.RequestHeaders = append(operationCall.RequestHeaders, headerModel{ + Key: key, + Values: template.HTML(strings.Join(values, "
")), + }) + } + + for key, values := range callResp.Header { + operationCall.ResponseHeaders = append(operationCall.ResponseHeaders, headerModel{ + Key: key, + Values: template.HTML(strings.Join(values, "
")), + }) + } + + operationData.Calls = append(operationData.Calls, operationCall) + } + + tmpl := template.New("operation.html.tmpl") + tmpl.Funcs(template.FuncMap{ + "mod": func(i, j int) bool { return i%j == 0 }, + }) + _, err = tmpl.ParseFiles( + filepath.Join("internal", "server", "templates", "log", "style.css.tmpl"), + filepath.Join("internal", "server", "templates", "log", "operation.html.tmpl"), + ) + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation log template error: %s", err), + http.StatusInternalServerError, + ) + + return + } + + var wBuf bytes.Buffer + + err = tmpl.Execute(&wBuf, operationData) + + if err != nil { + http.Error( + w, + fmt.Sprintf("operation log template execution error: %s", err), + http.StatusInternalServerError, + ) + + return + } + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusOK) + _, _ = wBuf.WriteTo(w) +} + +// rootHandler returns a slightly customized [http.NotFoundHandler], saying +// "path" instead of "page". +func rootHandler(w http.ResponseWriter, _ *http.Request) { + http.Error(w, "path not found", http.StatusNotFound) +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/server.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/server.go new file mode 100644 index 0000000..1223961 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/server.go @@ -0,0 +1,134 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package server + +import ( + "context" + "errors" + "fmt" + "log/slog" + "mockserver/internal/logging" + "mockserver/internal/tracking" + "net/http" + "strings" + "time" + + "github.com/gorilla/mux" +) + +const ( + // Default address for server listening. + DefaultAddress = ":18080" +) + +// Server implements the HTTP server. +type Server struct { + // Address for server listening. + address string + + // Directory for raw HTTP request and response files. + httpFileDir *logging.HTTPFileDirectory + + // Logger implementation. + logger *slog.Logger + + // Underlying mux implementation. + // Based on gorilla mux as the native mux suffered from issues with ambiguous paths and different http methods + // eg - panic: pattern "HEAD /v8/artifacts/{hash}" (registered at /usr/src/app/internal/server/server.go:104) conflicts with pattern "GET /v8/artifacts/status" (registered at /usr/src/app/internal/server/server.go:104): HEAD /v8/artifacts/{hash} matches fewer methods than GET /v8/artifacts/status, but has a more general path pattern + mux *mux.Router + + // Underlying server implementation. + server *http.Server + + requestTracker *tracking.RequestTracker +} + +// NewServer creates a new Server instance. +func NewServer(ctx context.Context, opts ...ServerOption) (*Server, error) { + // Initialize with defaults. + result := &Server{ + address: DefaultAddress, + logger: slog.Default(), + mux: mux.NewRouter(), + requestTracker: tracking.New(), + } + + // Customize based on ServerOption. + for _, opt := range opts { + err := opt(result) + + if err != nil { + return result, err + } + } + + result.server = &http.Server{ + Addr: result.address, + Handler: logging.HTTPLoggerHandler(result.logger, result.mux), + ErrorLog: slog.NewLogLogger(result.logger.Handler(), slog.LevelError), + } + + httpFileDir, err := logging.NewHTTPFileDirectory("") + + if err != nil { + return result, err + } + + err = httpFileDir.Clean() + + if err != nil { + return result, err + } + + result.httpFileDir = httpFileDir + + result.registerGeneratedHandlers(ctx) + result.registerInternalHandlers(ctx) + + return result, err +} + +// Address returns the server address including protocol, hostname, and port. +func (s *Server) Address() string { + return "http://localhost" + s.address +} + +// RegisterHandlerFunc adds a new HTTP handler function for the given methods and path. +func (s *Server) RegisterHandlerFunc(ctx context.Context, methods []string, path string, handlerFunc http.HandlerFunc) { + s.logger.DebugContext(ctx, fmt.Sprintf("registering handler for %s %s", strings.Join(methods, ", "), path)) + + r := s.mux.HandleFunc(path, handlerFunc) + if len(methods) > 0 { + r.Methods(methods...) + } +} + +// Serve starts the server. +func (s *Server) Serve(ctx context.Context) error { + s.logger.InfoContext(ctx, "starting server with address "+s.server.Addr) + + err := s.server.ListenAndServe() + + if errors.Is(err, http.ErrServerClosed) { + return nil + } + + return fmt.Errorf("error running server: %w", err) +} + +// Shutdown gracefully stops the server. +func (s *Server) Shutdown(ctx context.Context) error { + s.logger.WarnContext(ctx, "shutting down server") + s.server.SetKeepAlivesEnabled(false) + + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + err := s.server.Shutdown(ctx) + + if err != nil { + return fmt.Errorf("error shutting down server: %w", err) + } + + return nil +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/server_option.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/server_option.go new file mode 100644 index 0000000..ff85a67 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/server_option.go @@ -0,0 +1,30 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package server + +import ( + "log/slog" +) + +// ServerOption is a function which modifies the Server. +type ServerOption func(*Server) error + +// WithAddress sets the listening address for a Server. By default, the server +// address is :18080. +func WithAddress(address string) ServerOption { + return func(s *Server) error { + s.address = address + + return nil + } +} + +// WithLogger sets the logger implementation for a Server. By default, the +// server logger is [slog.Default]. +func WithLogger(logger *slog.Logger) ServerOption { + return func(s *Server) error { + s.logger = logger + + return nil + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/templates/log/index.html.tmpl b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/templates/log/index.html.tmpl new file mode 100644 index 0000000..8b1124e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/templates/log/index.html.tmpl @@ -0,0 +1,22 @@ + + + Operation Logs + + + +

// Speakeasy

+

Operation Logs

+ + + {{ range $idx, $o := .Operations }} + + + + + + {{ end }} +
OperationRequestCalls
{{ .ID }}{{ .Method }} {{ .Path }}{{ .CallCount }}
+ + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/templates/log/operation.html.tmpl b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/templates/log/operation.html.tmpl new file mode 100644 index 0000000..a54a2ad --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/templates/log/operation.html.tmpl @@ -0,0 +1,93 @@ + + + Operation Logs: {{ .ID }} + + + +

// Speakeasy

+

Operation Logs: {{ .ID }}

+

{{ .RequestMethod }} {{ .RequestPath }}

+

Back to All Operation Logs

+
+ {{ range $idx, $c := .Calls }} +
+ {{ if (ne (len $.Calls) 1) }} +

Call {{ .Call }}

+ {{ end }} +
+

Request

+ + {{ if (gt (len .RequestQueryParameters) 0) }} +
+

Query Parameters

+ + + {{ range $idx, $p := .RequestQueryParameters }} + + + + + {{ end }} +
KeyValue
{{ .Key }}{{ .Values }}
+
+ {{ end }} +
+

Headers

+ + + {{ range $idx, $h := .RequestHeaders }} + + + + + {{ end }} +
KeyValue(s)
{{ .Key }}{{ .Values }}
+
+ {{ if (gt (len .RequestBody) 0) }} +
+

Body

+

{{ .RequestBody }}

+
+ {{ end }} +

+

+ Raw Request +
{{ .RawRequest }}
+
+

+
+
+

Response

+

{{ .ResponseStatus }}

+
+

Headers

+ + + {{ range $idx, $h := .ResponseHeaders }} + + + + + {{ end }} +
KeyValue(s)
{{ .Key }}{{ .Values }}
+
+ {{ if (gt (len .ResponseBody) 0) }} +
+

Body

+

{{ .ResponseBody }}

+
+ {{ end }} +

+

+ Raw Response +
{{ .RawResponse }}
+
+

+
+
+ {{ end }} +
+ + diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/templates/log/style.css.tmpl b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/templates/log/style.css.tmpl new file mode 100644 index 0000000..5490930 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/server/templates/log/style.css.tmpl @@ -0,0 +1,64 @@ +{{ define "style" }} +a { + color: rgba(251, 227, 50, 1.0); +} +body { + background: black; + font-family: Arial, Helvetica, sans-serif; +} +code { + color: white; +} +details > div { + border-left: 1px solid gray; + margin-left: 10px; + padding: 10px; +} +div { + width: fit-content; +} +div.operation-call.odd { + background-color: rgba(251, 227, 50, 0.1); +} +h1 { + color: hsl(53, 96%, 59%); +} +h2 { + color: rgba(255, 255, 255, 1.0); +} +h3 { + color: rgba(255, 255, 255, 0.75); +} +h4 { + color: rgba(255, 255, 255, 0.50); +} +p { + color: white; + padding-left: 10px; +} +summary { + color: gray; + font-weight: bold; + margin-bottom: 5px; +} +table { + border-collapse: collapse; + margin: 5px; +} +th { + border-bottom: 1px solid gray; + color: white; + padding: 10px; + text-align: left; +} +td { + color: white; + padding: 10px; +} +tr.even { + background-color: rgba(255, 255, 255, 0.0); +} +tr.odd { + background-color: rgba(255, 255, 255, 0.1); +} +{{ end }} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/tracking/requesttracker.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/tracking/requesttracker.go new file mode 100644 index 0000000..1d9131d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/internal/tracking/requesttracker.go @@ -0,0 +1,47 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package tracking + +import ( + "fmt" + "time" + + cache "github.com/go-pkgz/expirable-cache/v3" +) + +type RequestTracker struct { + cache cache.Cache[string, *testEntry] +} + +type testEntry struct { + name string + id string + count int + created time.Time +} + +func New() *RequestTracker { + return &RequestTracker{ + cache: cache.NewCache[string, *testEntry]().WithTTL(5 * time.Minute), + } +} + +func (t *RequestTracker) GetRequestCount(testName, instanceID string) int { + key := fmt.Sprintf("%s-%s", testName, instanceID) + + entry, ok := t.cache.Get(key) + if !ok { + entry = &testEntry{ + name: testName, + id: instanceID, + count: 0, + created: time.Now(), + } + } + + count := entry.count + entry.count++ + t.cache.Set(key, entry, 0) + + return count +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/main.go b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/main.go new file mode 100644 index 0000000..2270443 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/main.go @@ -0,0 +1,74 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package main + +import ( + "context" + "flag" + "fmt" + "os" + "os/signal" + "strings" + + "mockserver/internal/logging" + "mockserver/internal/server" +) + +func main() { + ctx := context.Background() + + address := flag.String("address", server.DefaultAddress, fmt.Sprintf("server listen address (default: %s)", server.DefaultAddress)) + logFormat := flag.String("log-format", logging.DefaultFormat, fmt.Sprintf("logging format (default: %s, supported: %s)", logging.DefaultFormat, strings.Join(logging.Formats(), ", "))) + logLevel := flag.String("log-level", logging.DefaultLevel, fmt.Sprintf("logging level (default: %s, supported: %s)", logging.DefaultLevel, strings.Join(logging.Levels(), ", "))) + + flag.Parse() + + logger, err := logging.NewLogger(os.Stdout, *logFormat, *logLevel) + + if err != nil { + fmt.Fprintf(os.Stderr, "error setting up logging: %s", err) + os.Exit(1) + } + + serverOpts := []server.ServerOption{ + server.WithAddress(*address), + server.WithLogger(logger), + } + + s, err := server.NewServer(ctx, serverOpts...) + + if err != nil { + logger.ErrorContext(ctx, err.Error()) + os.Exit(1) + } + + finishedShutdown := make(chan struct{}) + startShutdown := make(chan os.Signal, 1) + signal.Notify(startShutdown, os.Interrupt) + + go func() { + <-startShutdown + + logger.WarnContext(ctx, "server received interrupt") + + err := s.Shutdown(ctx) + + if err != nil { + logger.Error(err.Error()) + os.Exit(1) + } + + close(finishedShutdown) + }() + + err = s.Serve(ctx) + + if err != nil { + logger.ErrorContext(ctx, err.Error()) + os.Exit(1) + } + + <-finishedShutdown + + logger.InfoContext(ctx, "server stopped") +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/testdata/example.file b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/testdata/example.file new file mode 100644 index 0000000..3b18e51 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/mockserver/testdata/example.file @@ -0,0 +1 @@ +hello world diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/orders.test.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/orders.test.ts new file mode 100644 index 0000000..6370484 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/orders.test.ts @@ -0,0 +1,378 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { SpeakeasyCoffeeClient } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Orders Get Orders Multiple Orders", async () => { + const testHttpClient = createTestHTTPClient("GetOrders-multiple_orders"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.list({}); + expect(result).toBeDefined(); + expect(result).toEqual([ + { + id: 1, + customerName: "Alice", + coffeeType: "Latte", + size: "Medium", + extras: [ + "Extra shot", + "Soy milk", + ], + price: 4.5, + }, + { + id: 2, + customerName: "Bob", + coffeeType: "Espresso", + size: "Small", + extras: [ + "Extra shot", + ], + price: 3.5, + }, + ]); +}); + +test("Orders Get Orders Latte", async () => { + const testHttpClient = createTestHTTPClient("GetOrders-latte"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Latte", + }); + expect(result).toBeDefined(); + expect(result).toEqual([ + { + id: 5, + customerName: "Eve", + coffeeType: "Mocha", + size: "Large", + extras: [ + "Whipped cream", + "Chocolate syrup", + ], + price: 6, + }, + { + id: 6, + customerName: "Grace", + coffeeType: "Cold Brew", + size: "Medium", + extras: [ + "Vanilla syrup", + ], + price: 5.5, + }, + ]); +}); + +test("Orders Get Orders Espresso", async () => { + const testHttpClient = createTestHTTPClient("GetOrders-espresso"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.list({ + coffeeType: "Espresso", + }); + expect(result).toBeDefined(); + expect(result).toEqual([ + { + id: 5, + customerName: "Eve", + coffeeType: "Mocha", + size: "Large", + extras: [ + "Whipped cream", + "Chocolate syrup", + ], + price: 6, + }, + { + id: 6, + customerName: "Grace", + coffeeType: "Cold Brew", + size: "Medium", + extras: [ + "Vanilla syrup", + ], + price: 5.5, + }, + ]); +}); + +test("Orders Create Order Simple Order", async () => { + const testHttpClient = createTestHTTPClient("CreateOrder-simple_order"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.create({ + id: 3, + customerName: "Charlie", + coffeeType: "Americano", + size: "Large", + price: 3.75, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + id: 5, + customerName: "Eve", + coffeeType: "Mocha", + size: "Large", + extras: [ + "Whipped cream", + "Chocolate syrup", + ], + price: 6, + }); +}); + +test("Orders Create Order Complex Order", async () => { + const testHttpClient = createTestHTTPClient("CreateOrder-complex_order"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.create({ + id: 4, + customerName: "Diana", + coffeeType: "Cappuccino", + size: "Medium", + extras: [ + "Whipped cream", + "Caramel syrup", + ], + price: 5.25, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + id: 6, + customerName: "Grace", + coffeeType: "Cold Brew", + size: "Medium", + extras: [ + "Vanilla syrup", + ], + price: 5.5, + }); +}); + +test("Orders Get Order Order1", async () => { + const testHttpClient = createTestHTTPClient("GetOrder-order1"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.getById({ + orderId: 1, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + id: 5, + customerName: "Eve", + coffeeType: "Mocha", + size: "Large", + extras: [ + "Whipped cream", + "Chocolate syrup", + ], + price: 6, + }); +}); + +test("Orders Get Order Order2", async () => { + const testHttpClient = createTestHTTPClient("GetOrder-order2"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.getById({ + orderId: 2, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + id: 6, + customerName: "Grace", + coffeeType: "Cold Brew", + size: "Medium", + extras: [ + "Vanilla syrup", + ], + price: 5.5, + }); +}); + +test("Orders Get Order Not Found", async () => { + const testHttpClient = createTestHTTPClient("GetOrder-not_found"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.getById({ + orderId: 257133, + }); + expect(result).toBeDefined(); +}); + +test("Orders Update Order Order1", async () => { + const testHttpClient = createTestHTTPClient("UpdateOrder-order1"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.update({ + orderId: 1, + coffeeOrderUpdate: { + coffeeType: "Cappuccino", + extras: [ + "Cinnamon", + "Whipped cream", + ], + price: 5.75, + }, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + id: 6, + customerName: "Grace", + coffeeType: "Cold Brew", + size: "Medium", + extras: [ + "Vanilla syrup", + ], + price: 5.5, + }); +}); + +test("Orders Update Order Order2", async () => { + const testHttpClient = createTestHTTPClient("UpdateOrder-order2"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.update({ + orderId: 2, + coffeeOrderUpdate: { + customerName: "Frank", + size: "Small", + extras: [ + "Sugar-free syrup", + ], + }, + }); + expect(result).toBeDefined(); + expect(result).toEqual({ + id: 6, + customerName: "Grace", + coffeeType: "Cold Brew", + size: "Medium", + extras: [ + "Vanilla syrup", + ], + price: 5.5, + }); +}); + +test("Orders Update Order Not Found", async () => { + const testHttpClient = createTestHTTPClient("UpdateOrder-not_found"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + const result = await speakeasyCoffeeClient.orders.update({ + orderId: 488852, + coffeeOrderUpdate: { + coffeeType: "Cappuccino", + extras: [ + "Cinnamon", + "Whipped cream", + ], + price: 5.75, + }, + }); + expect(result).toBeDefined(); +}); + +test("Orders Delete Order Order1", async () => { + const testHttpClient = createTestHTTPClient("DeleteOrder-order1"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + await speakeasyCoffeeClient.orders.delete({ + orderId: 1, + }); +}); + +test("Orders Delete Order Order2", async () => { + const testHttpClient = createTestHTTPClient("DeleteOrder-order2"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + await speakeasyCoffeeClient.orders.delete({ + orderId: 2, + }); +}); + +test("Orders Delete Order Not Found", async () => { + const testHttpClient = createTestHTTPClient("DeleteOrder-not_found"); + + const speakeasyCoffeeClient = new SpeakeasyCoffeeClient({ + serverURL: process.env["TEST_SERVER_URL"] ?? "http://localhost:18080", + httpClient: testHttpClient, + apiKeyAuth: "your-api-key-here", + }); + + await speakeasyCoffeeClient.orders.delete({ + orderId: 545907, + }); +}); diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/testclient.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/testclient.ts new file mode 100644 index 0000000..0dd5b59 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/__tests__/testclient.ts @@ -0,0 +1,48 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { getRandomValues } from "crypto"; +import { HTTPClient } from "../lib/http.js"; + +export function createTestHTTPClient(testName: string): HTTPClient { + const httpClient = new HTTPClient({ + fetcher: (request: URL | RequestInfo) => { + return fetch(request); + }, + }); + + const testInstanceId = genTestId(); + + httpClient.addHook("beforeRequest", (request: Request) => { + const nextRequest = new Request(request, { + signal: request.signal || AbortSignal.timeout(5000), + }); + + nextRequest.headers.set("x-speakeasy-test-name", testName); + nextRequest.headers.set("x-speakeasy-test-instance-id", testInstanceId); + + return nextRequest; + }); + + return httpClient; +} + +function genTestId(): string { + const b = new Uint8Array(16); + getRandomValues(b); + + return `${buf2hex(b.slice(0, 4))}-${buf2hex(b.slice(4, 6))}-${ + buf2hex( + b.slice(6, 8), + ) + }-${buf2hex(b.slice(8, 10))}-${buf2hex(b.slice(10))}`; +} + +// Helper function to convert buffer to hex string +function buf2hex(buffer: Uint8Array): string { + return [...buffer] + .map((x) => x.toString(16).padStart(2, "0")) + .join("") + .toUpperCase(); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/core.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/core.ts new file mode 100644 index 0000000..e6090c7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/core.ts @@ -0,0 +1,13 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ClientSDK } from "./lib/sdks.js"; + +/** + * A minimal client to use when calling standalone SDK functions. Typically, an + * instance of this class would be instantiated once at the start of an + * application and passed around through some dependency injection mechanism to + * parts of an application that need to make SDK calls. + */ +export class SpeakeasyCoffeeClientCore extends ClientSDK {} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesCreate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesCreate.ts new file mode 100644 index 0000000..41b7bdf --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesCreate.ts @@ -0,0 +1,167 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import * as components from "../models/components/index.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import * as errors from "../models/errors/index.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Create Coffee Type + * + * @remarks + * Create a new coffee type. + */ +export function coffeeTypesCreate( + client: SpeakeasyCoffeeClientCore, + request: components.CoffeeType, + options?: RequestOptions, +): APIPromise< + Result< + components.CoffeeType, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + request: components.CoffeeType, + options?: RequestOptions, +): Promise< + [ + Result< + components.CoffeeType, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => components.CoffeeType$outboundSchema.parse(value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/coffee-types")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "CreateCoffeeType", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["400", "422", "4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + components.CoffeeType, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.json(201, components.CoffeeType$inboundSchema), + M.jsonErr(400, errors.ErrorResponse$inboundSchema), + M.jsonErr(422, errors.HTTPValidationError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesDelete.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesDelete.ts new file mode 100644 index 0000000..b2b89e6 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesDelete.ts @@ -0,0 +1,174 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { encodeSimple } from "../lib/encodings.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import * as errors from "../models/errors/index.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import * as operations from "../models/operations/index.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Delete Coffee Type + * + * @remarks + * Delete a coffee type. + */ +export function coffeeTypesDelete( + client: SpeakeasyCoffeeClientCore, + request: operations.DeleteCoffeeTypeRequest, + options?: RequestOptions, +): APIPromise< + Result< + void, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + request: operations.DeleteCoffeeTypeRequest, + options?: RequestOptions, +): Promise< + [ + Result< + void, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => operations.DeleteCoffeeTypeRequest$outboundSchema.parse(value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const pathParams = { + type_id: encodeSimple("type_id", payload.type_id, { + explode: false, + charEncoding: "percent", + }), + }; + + const path = pathToFunc("/coffee-types/{type_id}")(pathParams); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "DeleteCoffeeType", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "DELETE", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["404", "422", "4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + void, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.nil(204, z.void()), + M.jsonErr(404, errors.ErrorResponse$inboundSchema), + M.jsonErr(422, errors.HTTPValidationError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesGetById.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesGetById.ts new file mode 100644 index 0000000..5e50a50 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesGetById.ts @@ -0,0 +1,174 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { encodeSimple } from "../lib/encodings.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import * as components from "../models/components/index.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import * as errors from "../models/errors/index.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import * as operations from "../models/operations/index.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Get Coffee Type + * + * @remarks + * Retrieve a specific coffee type by its ID. + */ +export function coffeeTypesGetById( + client: SpeakeasyCoffeeClientCore, + request: operations.GetCoffeeTypeRequest, + options?: RequestOptions, +): APIPromise< + Result< + components.CoffeeType, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + request: operations.GetCoffeeTypeRequest, + options?: RequestOptions, +): Promise< + [ + Result< + components.CoffeeType, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => operations.GetCoffeeTypeRequest$outboundSchema.parse(value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const pathParams = { + type_id: encodeSimple("type_id", payload.type_id, { + explode: false, + charEncoding: "percent", + }), + }; + + const path = pathToFunc("/coffee-types/{type_id}")(pathParams); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "GetCoffeeType", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["404", "422", "4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + components.CoffeeType, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.json(200, components.CoffeeType$inboundSchema), + M.jsonErr(404, errors.ErrorResponse$inboundSchema), + M.jsonErr(422, errors.HTTPValidationError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesList.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesList.ts new file mode 100644 index 0000000..17faefa --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesList.ts @@ -0,0 +1,137 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import * as components from "../models/components/index.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Get Coffee Types + * + * @remarks + * Retrieve all available coffee types. + */ +export function coffeeTypesList( + client: SpeakeasyCoffeeClientCore, + options?: RequestOptions, +): APIPromise< + Result< + Array, + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + options?: RequestOptions, +): Promise< + [ + Result< + Array, + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const path = pathToFunc("/coffee-types")(); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "GetCoffeeTypes", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const [result] = await M.match< + Array, + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.json(200, z.array(components.CoffeeType$inboundSchema)), + M.fail("4XX"), + M.fail("5XX"), + )(response); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesUpdate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesUpdate.ts new file mode 100644 index 0000000..5b084c9 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/coffeeTypesUpdate.ts @@ -0,0 +1,175 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { encodeJSON, encodeSimple } from "../lib/encodings.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import * as components from "../models/components/index.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import * as errors from "../models/errors/index.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import * as operations from "../models/operations/index.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Update Coffee Type + * + * @remarks + * Update an existing coffee type. + */ +export function coffeeTypesUpdate( + client: SpeakeasyCoffeeClientCore, + request: operations.UpdateCoffeeTypeRequest, + options?: RequestOptions, +): APIPromise< + Result< + components.CoffeeType, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + request: operations.UpdateCoffeeTypeRequest, + options?: RequestOptions, +): Promise< + [ + Result< + components.CoffeeType, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => operations.UpdateCoffeeTypeRequest$outboundSchema.parse(value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload.CoffeeType, { explode: true }); + + const pathParams = { + type_id: encodeSimple("type_id", payload.type_id, { + explode: false, + charEncoding: "percent", + }), + }; + + const path = pathToFunc("/coffee-types/{type_id}")(pathParams); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "UpdateCoffeeType", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "PUT", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["404", "422", "4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + components.CoffeeType, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.json(200, components.CoffeeType$inboundSchema), + M.jsonErr(404, errors.ErrorResponse$inboundSchema), + M.jsonErr(422, errors.HTTPValidationError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersCreate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersCreate.ts new file mode 100644 index 0000000..0f8610f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersCreate.ts @@ -0,0 +1,164 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { encodeJSON } from "../lib/encodings.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import * as components from "../models/components/index.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import * as errors from "../models/errors/index.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Create Order + * + * @remarks + * Create a new coffee order. + * Validates that the coffee type exists. + */ +export function ordersCreate( + client: SpeakeasyCoffeeClientCore, + request: components.CoffeeOrder, + options?: RequestOptions, +): APIPromise< + Result< + components.CoffeeOrder, + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + request: components.CoffeeOrder, + options?: RequestOptions, +): Promise< + [ + Result< + components.CoffeeOrder, + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => components.CoffeeOrder$outboundSchema.parse(value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload, { explode: true }); + + const path = pathToFunc("/orders")(); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "CreateOrder", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "POST", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["400", "422", "4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + components.CoffeeOrder, + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.json(201, components.CoffeeOrder$inboundSchema), + M.jsonErr([400, 422], errors.HTTPValidationError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersDelete.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersDelete.ts new file mode 100644 index 0000000..11c237b --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersDelete.ts @@ -0,0 +1,174 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { encodeSimple } from "../lib/encodings.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import * as errors from "../models/errors/index.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import * as operations from "../models/operations/index.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Delete Order + * + * @remarks + * Delete a coffee order. + */ +export function ordersDelete( + client: SpeakeasyCoffeeClientCore, + request: operations.DeleteOrderRequest, + options?: RequestOptions, +): APIPromise< + Result< + void, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + request: operations.DeleteOrderRequest, + options?: RequestOptions, +): Promise< + [ + Result< + void, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => operations.DeleteOrderRequest$outboundSchema.parse(value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const pathParams = { + order_id: encodeSimple("order_id", payload.order_id, { + explode: false, + charEncoding: "percent", + }), + }; + + const path = pathToFunc("/orders/{order_id}")(pathParams); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "DeleteOrder", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "DELETE", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["404", "422", "4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + void, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.nil(204, z.void()), + M.jsonErr(404, errors.ErrorResponse$inboundSchema), + M.jsonErr(422, errors.HTTPValidationError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersGetById.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersGetById.ts new file mode 100644 index 0000000..ea1e6a5 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersGetById.ts @@ -0,0 +1,174 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { encodeSimple } from "../lib/encodings.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import * as components from "../models/components/index.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import * as errors from "../models/errors/index.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import * as operations from "../models/operations/index.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Get Order + * + * @remarks + * Retrieve a specific coffee order by its ID. + */ +export function ordersGetById( + client: SpeakeasyCoffeeClientCore, + request: operations.GetOrderRequest, + options?: RequestOptions, +): APIPromise< + Result< + components.CoffeeOrder, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + request: operations.GetOrderRequest, + options?: RequestOptions, +): Promise< + [ + Result< + components.CoffeeOrder, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => operations.GetOrderRequest$outboundSchema.parse(value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const pathParams = { + order_id: encodeSimple("order_id", payload.order_id, { + explode: false, + charEncoding: "percent", + }), + }; + + const path = pathToFunc("/orders/{order_id}")(pathParams); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "GetOrder", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["404", "422", "4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + components.CoffeeOrder, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.json(200, components.CoffeeOrder$inboundSchema), + M.jsonErr(404, errors.ErrorResponse$inboundSchema), + M.jsonErr(422, errors.HTTPValidationError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersList.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersList.ts new file mode 100644 index 0000000..085d43c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersList.ts @@ -0,0 +1,170 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { encodeFormQuery } from "../lib/encodings.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import * as components from "../models/components/index.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import * as errors from "../models/errors/index.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import * as operations from "../models/operations/index.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Get Orders + * + * @remarks + * Retrieve all coffee orders. + * If 'coffee_type' is provided, returns orders matching that coffee type. + */ +export function ordersList( + client: SpeakeasyCoffeeClientCore, + request: operations.GetOrdersRequest, + options?: RequestOptions, +): APIPromise< + Result< + Array, + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + request: operations.GetOrdersRequest, + options?: RequestOptions, +): Promise< + [ + Result< + Array, + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => operations.GetOrdersRequest$outboundSchema.parse(value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = null; + + const path = pathToFunc("/orders")(); + + const query = encodeFormQuery({ + "coffee_type": payload.coffee_type, + }); + + const headers = new Headers(compactMap({ + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "GetOrders", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "GET", + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["422", "4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + Array, + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.json(200, z.array(components.CoffeeOrder$inboundSchema)), + M.jsonErr(422, errors.HTTPValidationError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersUpdate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersUpdate.ts new file mode 100644 index 0000000..24b2a28 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/funcs/ordersUpdate.ts @@ -0,0 +1,175 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { encodeJSON, encodeSimple } from "../lib/encodings.js"; +import * as M from "../lib/matchers.js"; +import { compactMap } from "../lib/primitives.js"; +import { safeParse } from "../lib/schemas.js"; +import { RequestOptions } from "../lib/sdks.js"; +import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { pathToFunc } from "../lib/url.js"; +import * as components from "../models/components/index.js"; +import { APIError } from "../models/errors/apierror.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import * as errors from "../models/errors/index.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import * as operations from "../models/operations/index.js"; +import { APICall, APIPromise } from "../types/async.js"; +import { Result } from "../types/fp.js"; + +/** + * Update Order + * + * @remarks + * Update an existing coffee order. + */ +export function ordersUpdate( + client: SpeakeasyCoffeeClientCore, + request: operations.UpdateOrderRequest, + options?: RequestOptions, +): APIPromise< + Result< + components.CoffeeOrder, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + > +> { + return new APIPromise($do( + client, + request, + options, + )); +} + +async function $do( + client: SpeakeasyCoffeeClientCore, + request: operations.UpdateOrderRequest, + options?: RequestOptions, +): Promise< + [ + Result< + components.CoffeeOrder, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >, + APICall, + ] +> { + const parsed = safeParse( + request, + (value) => operations.UpdateOrderRequest$outboundSchema.parse(value), + "Input validation failed", + ); + if (!parsed.ok) { + return [parsed, { status: "invalid" }]; + } + const payload = parsed.value; + const body = encodeJSON("body", payload.CoffeeOrderUpdate, { explode: true }); + + const pathParams = { + order_id: encodeSimple("order_id", payload.order_id, { + explode: false, + charEncoding: "percent", + }), + }; + + const path = pathToFunc("/orders/{order_id}")(pathParams); + + const headers = new Headers(compactMap({ + "Content-Type": "application/json", + Accept: "application/json", + })); + + const secConfig = await extractSecurity(client._options.apiKeyAuth); + const securityInput = secConfig == null ? {} : { apiKeyAuth: secConfig }; + const requestSecurity = resolveGlobalSecurity(securityInput); + + const context = { + baseURL: options?.serverURL ?? client._baseURL ?? "", + operationID: "UpdateOrder", + oAuth2Scopes: [], + + resolvedSecurity: requestSecurity, + + securitySource: client._options.apiKeyAuth, + retryConfig: options?.retries + || client._options.retryConfig + || { strategy: "none" }, + retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"], + }; + + const requestRes = client._createRequest(context, { + security: requestSecurity, + method: "PUT", + baseURL: options?.serverURL, + path: path, + headers: headers, + body: body, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, options); + if (!requestRes.ok) { + return [requestRes, { status: "invalid" }]; + } + const req = requestRes.value; + + const doResult = await client._do(req, { + context, + errorCodes: ["404", "422", "4XX", "5XX"], + retryConfig: context.retryConfig, + retryCodes: context.retryCodes, + }); + if (!doResult.ok) { + return [doResult, { status: "request-error", request: req }]; + } + const response = doResult.value; + + const responseFields = { + HttpMeta: { Response: response, Request: req }, + }; + + const [result] = await M.match< + components.CoffeeOrder, + | errors.ErrorResponse + | errors.HTTPValidationError + | APIError + | SDKValidationError + | UnexpectedClientError + | InvalidRequestError + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + >( + M.json(200, components.CoffeeOrder$inboundSchema), + M.jsonErr(404, errors.ErrorResponse$inboundSchema), + M.jsonErr(422, errors.HTTPValidationError$inboundSchema), + M.fail("4XX"), + M.fail("5XX"), + )(response, { extraFields: responseFields }); + if (!result.ok) { + return [result, { status: "complete", request: req, response }]; + } + + return [result, { status: "complete", request: req, response }]; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/hooks.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/hooks.ts new file mode 100644 index 0000000..d34c884 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/hooks.ts @@ -0,0 +1,132 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { RequestInput } from "../lib/http.js"; +import { + AfterErrorContext, + AfterErrorHook, + AfterSuccessContext, + AfterSuccessHook, + BeforeCreateRequestContext, + BeforeCreateRequestHook, + BeforeRequestContext, + BeforeRequestHook, + Hook, + Hooks, + SDKInitHook, + SDKInitOptions, +} from "./types.js"; + +import { initHooks } from "./registration.js"; + +export class SDKHooks implements Hooks { + sdkInitHooks: SDKInitHook[] = []; + beforeCreateRequestHooks: BeforeCreateRequestHook[] = []; + beforeRequestHooks: BeforeRequestHook[] = []; + afterSuccessHooks: AfterSuccessHook[] = []; + afterErrorHooks: AfterErrorHook[] = []; + + constructor() { + const presetHooks: Array = []; + + for (const hook of presetHooks) { + if ("sdkInit" in hook) { + this.registerSDKInitHook(hook); + } + if ("beforeCreateRequest" in hook) { + this.registerBeforeCreateRequestHook(hook); + } + if ("beforeRequest" in hook) { + this.registerBeforeRequestHook(hook); + } + if ("afterSuccess" in hook) { + this.registerAfterSuccessHook(hook); + } + if ("afterError" in hook) { + this.registerAfterErrorHook(hook); + } + } + initHooks(this); + } + + registerSDKInitHook(hook: SDKInitHook) { + this.sdkInitHooks.push(hook); + } + + registerBeforeCreateRequestHook(hook: BeforeCreateRequestHook) { + this.beforeCreateRequestHooks.push(hook); + } + + registerBeforeRequestHook(hook: BeforeRequestHook) { + this.beforeRequestHooks.push(hook); + } + + registerAfterSuccessHook(hook: AfterSuccessHook) { + this.afterSuccessHooks.push(hook); + } + + registerAfterErrorHook(hook: AfterErrorHook) { + this.afterErrorHooks.push(hook); + } + + sdkInit(opts: SDKInitOptions): SDKInitOptions { + return this.sdkInitHooks.reduce((opts, hook) => hook.sdkInit(opts), opts); + } + + beforeCreateRequest( + hookCtx: BeforeCreateRequestContext, + input: RequestInput, + ): RequestInput { + let inp = input; + + for (const hook of this.beforeCreateRequestHooks) { + inp = hook.beforeCreateRequest(hookCtx, inp); + } + + return inp; + } + + async beforeRequest( + hookCtx: BeforeRequestContext, + request: Request, + ): Promise { + let req = request; + + for (const hook of this.beforeRequestHooks) { + req = await hook.beforeRequest(hookCtx, req); + } + + return req; + } + + async afterSuccess( + hookCtx: AfterSuccessContext, + response: Response, + ): Promise { + let res = response; + + for (const hook of this.afterSuccessHooks) { + res = await hook.afterSuccess(hookCtx, res); + } + + return res; + } + + async afterError( + hookCtx: AfterErrorContext, + response: Response | null, + error: unknown, + ): Promise<{ response: Response | null; error: unknown }> { + let res = response; + let err = error; + + for (const hook of this.afterErrorHooks) { + const result = await hook.afterError(hookCtx, res, err); + res = result.response; + err = result.error; + } + + return { response: res, error: err }; + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/index.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/index.ts new file mode 100644 index 0000000..f60ec7a --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/index.ts @@ -0,0 +1,6 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export * from "./hooks.js"; +export * from "./types.js"; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/registration.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/registration.ts new file mode 100644 index 0000000..7064973 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/registration.ts @@ -0,0 +1,14 @@ +import { Hooks } from "./types.js"; + +/* + * This file is only ever generated once on the first generation and then is free to be modified. + * Any hooks you wish to add should be registered in the initHooks function. Feel free to define them + * in this file or in separate files in the hooks folder. + */ + +// @ts-expect-error remove this line when you add your first hook and hooks is used +export function initHooks(hooks: Hooks) { + // Add hooks by calling hooks.register{ClientInit/BeforeCreateRequest/BeforeRequest/AfterSuccess/AfterError}Hook + // with an instance of a hook that implements that specific Hook interface + // Hooks are registered per SDK instance, and are valid for the lifetime of the SDK instance +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/types.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/types.ts new file mode 100644 index 0000000..f34898c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/hooks/types.ts @@ -0,0 +1,110 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { HTTPClient, RequestInput } from "../lib/http.js"; +import { RetryConfig } from "../lib/retries.js"; +import { SecurityState } from "../lib/security.js"; + +export type HookContext = { + baseURL: string | URL; + operationID: string; + oAuth2Scopes?: string[]; + securitySource?: any | (() => Promise); + retryConfig: RetryConfig; + resolvedSecurity: SecurityState | null; +}; + +export type Awaitable = T | Promise; + +export type SDKInitOptions = { + baseURL: URL | null; + client: HTTPClient; +}; + +export type BeforeCreateRequestContext = HookContext & {}; +export type BeforeRequestContext = HookContext & {}; +export type AfterSuccessContext = HookContext & {}; +export type AfterErrorContext = HookContext & {}; + +/** + * SDKInitHook is called when the SDK is initializing. The + * hook can return a new baseURL and HTTP client to be used by the SDK. + */ +export interface SDKInitHook { + sdkInit: (opts: SDKInitOptions) => SDKInitOptions; +} + +export interface BeforeCreateRequestHook { + /** + * A hook that is called before the SDK creates a `Request` object. The hook + * can modify how a request is constructed since certain modifications, like + * changing the request URL, cannot be done on a request object directly. + */ + beforeCreateRequest: ( + hookCtx: BeforeCreateRequestContext, + input: RequestInput, + ) => RequestInput; +} + +export interface BeforeRequestHook { + /** + * A hook that is called before the SDK sends a request. The hook can + * introduce instrumentation code such as logging, tracing and metrics or + * replace the request before it is sent or throw an error to stop the + * request from being sent. + */ + beforeRequest: ( + hookCtx: BeforeRequestContext, + request: Request, + ) => Awaitable; +} + +export interface AfterSuccessHook { + /** + * A hook that is called after the SDK receives a response. The hook can + * introduce instrumentation code such as logging, tracing and metrics or + * modify the response before it is handled or throw an error to stop the + * response from being handled. + */ + afterSuccess: ( + hookCtx: AfterSuccessContext, + response: Response, + ) => Awaitable; +} + +export interface AfterErrorHook { + /** + * A hook that is called after the SDK encounters an error, or a + * non-successful response. The hook can introduce instrumentation code such + * as logging, tracing and metrics or modify the response or error values. + */ + afterError: ( + hookCtx: AfterErrorContext, + response: Response | null, + error: unknown, + ) => Awaitable<{ + response: Response | null; + error: unknown; + }>; +} + +export interface Hooks { + /** Registers a hook to be used by the SDK for initialization event. */ + registerSDKInitHook(hook: SDKInitHook): void; + /** Registers a hook to be used by the SDK for to modify `Request` construction. */ + registerBeforeCreateRequestHook(hook: BeforeCreateRequestHook): void; + /** Registers a hook to be used by the SDK for the before request event. */ + registerBeforeRequestHook(hook: BeforeRequestHook): void; + /** Registers a hook to be used by the SDK for the after success event. */ + registerAfterSuccessHook(hook: AfterSuccessHook): void; + /** Registers a hook to be used by the SDK for the after error event. */ + registerAfterErrorHook(hook: AfterErrorHook): void; +} + +export type Hook = + | SDKInitHook + | BeforeCreateRequestHook + | BeforeRequestHook + | AfterSuccessHook + | AfterErrorHook; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/index.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/index.ts new file mode 100644 index 0000000..5ddc765 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/index.ts @@ -0,0 +1,7 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export * from "./lib/config.js"; +export * as files from "./lib/files.js"; +export * from "./sdk/sdk.js"; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/base64.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/base64.ts new file mode 100644 index 0000000..c2d5b38 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/base64.ts @@ -0,0 +1,37 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; + +export function bytesToBase64(u8arr: Uint8Array): string { + return btoa(String.fromCodePoint(...u8arr)); +} + +export function bytesFromBase64(encoded: string): Uint8Array { + return Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0)); +} + +export function stringToBytes(str: string): Uint8Array { + return new TextEncoder().encode(str); +} + +export function stringFromBytes(u8arr: Uint8Array): string { + return new TextDecoder().decode(u8arr); +} + +export function stringToBase64(str: string): string { + return bytesToBase64(stringToBytes(str)); +} + +export function stringFromBase64(b64str: string): string { + return stringFromBytes(bytesFromBase64(b64str)); +} + +export const zodOutbound = z + .instanceof(Uint8Array) + .or(z.string().transform(stringToBytes)); + +export const zodInbound = z + .instanceof(Uint8Array) + .or(z.string().transform(bytesFromBase64)); diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/config.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/config.ts new file mode 100644 index 0000000..039ad75 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/config.ts @@ -0,0 +1,64 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { HTTPClient } from "./http.js"; +import { Logger } from "./logger.js"; +import { RetryConfig } from "./retries.js"; +import { Params, pathToFunc } from "./url.js"; + +/** + * Contains the list of servers available to the SDK + */ +export const ServerList = [ + /** + * Development server + */ + "http://localhost:8000", +] as const; + +export type SDKOptions = { + apiKeyAuth?: string | (() => Promise) | undefined; + + httpClient?: HTTPClient; + /** + * Allows overriding the default server used by the SDK + */ + serverIdx?: number | undefined; + /** + * Allows overriding the default server URL used by the SDK + */ + serverURL?: string | undefined; + /** + * Allows overriding the default retry config used by the SDK + */ + retryConfig?: RetryConfig; + timeoutMs?: number; + debugLogger?: Logger; +}; + +export function serverURLFromOptions(options: SDKOptions): URL | null { + let serverURL = options.serverURL; + + const params: Params = {}; + + if (!serverURL) { + const serverIdx = options.serverIdx ?? 0; + if (serverIdx < 0 || serverIdx >= ServerList.length) { + throw new Error(`Invalid server index ${serverIdx}`); + } + serverURL = ServerList[serverIdx] || ""; + } + + const u = pathToFunc(serverURL)(params); + return new URL(u); +} + +export const SDK_METADATA = { + language: "typescript", + openapiDocVersion: "1.0.0", + sdkVersion: "0.1.0", + genVersion: "2.539.1", + userAgent: + "speakeasy-sdk/typescript 0.1.0 2.539.1 1.0.0 speakeasy-coffee-client", +} as const; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/dlv.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/dlv.ts new file mode 100644 index 0000000..e81091f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/dlv.ts @@ -0,0 +1,53 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +/* +MIT License + +Copyright (c) 2024 Jason Miller (http://jasonformat.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/** + * @param obj The object to walk + * @param key The key path to walk the object with + * @param def A default value to return if the result is undefined + * + * @example + * dlv(obj, "a.b.c.d") + * @example + * dlv(object, ["a", "b", "c", "d"]) + * @example + * dlv(object, "foo.bar.baz", "Hello, default value!") + */ +export function dlv( + obj: any, + key: string | string[], + def?: T, + p?: number, + undef?: never, +): T | undefined { + key = Array.isArray(key) ? key : key.split("."); + for (p = 0; p < key.length; p++) { + const k = key[p]; + obj = k != null && obj ? obj[k] : undef; + } + return obj === undef ? def : obj; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/encodings.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/encodings.ts new file mode 100644 index 0000000..25c9dcb --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/encodings.ts @@ -0,0 +1,483 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { bytesToBase64 } from "./base64.js"; +import { isPlainObject } from "./is-plain-object.js"; + +export class EncodingError extends Error { + constructor(message: string) { + super(message); + this.name = "EncodingError"; + } +} + +export function encodeMatrix( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: "percent" | "none" }, +): string | undefined { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + if (pairs.every(([_, v]) => v == null)) { + return; + } + + const encodeString = (v: string) => { + return options?.charEncoding === "percent" ? encodeURIComponent(v) : v; + }; + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + pairs.forEach(([pk, pv]) => { + let tmp = ""; + let encValue: string | null | undefined = null; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + encValue = mapDefined(pv, (v) => `${encodeValue(v)}`)?.join(","); + } else if (isPlainObject(pv)) { + const mapped = mapDefinedEntries(Object.entries(pv), ([k, v]) => { + return `,${encodeString(k)},${encodeValue(v)}`; + }); + encValue = mapped?.join("").slice(1); + } else { + encValue = `${encodeValue(pv)}`; + } + + if (encValue == null) { + return; + } + + const keyPrefix = encodeString(pk); + tmp = `${keyPrefix}=${encValue}`; + // trim trailing '=' if value was empty + if (tmp === `${keyPrefix}=`) { + tmp = tmp.slice(0, -1); + } + + // If we end up with the nothing then skip forward + if (!tmp) { + return; + } + + out += `;${tmp}`; + }); + + return out; +} + +export function encodeLabel( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: "percent" | "none" }, +): string | undefined { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + if (pairs.every(([_, v]) => v == null)) { + return; + } + + const encodeString = (v: string) => { + return options?.charEncoding === "percent" ? encodeURIComponent(v) : v; + }; + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + pairs.forEach(([pk, pv]) => { + let encValue: string | null | undefined = ""; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + encValue = mapDefined(pv, (v) => `${encodeValue(v)}`)?.join("."); + } else if (isPlainObject(pv)) { + const mapped = mapDefinedEntries(Object.entries(pv), ([k, v]) => { + return `.${encodeString(k)}.${encodeValue(v)}`; + }); + encValue = mapped?.join("").slice(1); + } else { + const k = + options?.explode && isPlainObject(value) ? `${encodeString(pk)}=` : ""; + encValue = `${k}${encodeValue(pv)}`; + } + + out += encValue == null ? "" : `.${encValue}`; + }); + + return out; +} + +type FormEncoder = ( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: "percent" | "none" }, +) => string | undefined; + +function formEncoder(sep: string): FormEncoder { + return ( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: "percent" | "none" }, + ) => { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + if (pairs.every(([_, v]) => v == null)) { + return; + } + + const encodeString = (v: string) => { + return options?.charEncoding === "percent" ? encodeURIComponent(v) : v; + }; + + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + const encodedSep = encodeString(sep); + + pairs.forEach(([pk, pv]) => { + let tmp = ""; + let encValue: string | null | undefined = null; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + encValue = mapDefined(pv, (v) => `${encodeValue(v)}`)?.join(encodedSep); + } else if (isPlainObject(pv)) { + encValue = mapDefinedEntries(Object.entries(pv), ([k, v]) => { + return `${encodeString(k)}${encodedSep}${encodeValue(v)}`; + })?.join(encodedSep); + } else { + encValue = `${encodeValue(pv)}`; + } + + if (encValue == null) { + return; + } + + tmp = `${encodeString(pk)}=${encValue}`; + + // If we end up with the nothing then skip forward + if (!tmp || tmp === "=") { + return; + } + + out += `&${tmp}`; + }); + + return out.slice(1); + }; +} + +export const encodeForm = formEncoder(","); +export const encodeSpaceDelimited = formEncoder(" "); +export const encodePipeDelimited = formEncoder("|"); + +export function encodeBodyForm( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: "percent" | "none" }, +): string { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + const encodeString = (v: string) => { + return options?.charEncoding === "percent" ? encodeURIComponent(v) : v; + }; + + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + pairs.forEach(([pk, pv]) => { + let tmp = ""; + let encValue = ""; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + encValue = JSON.stringify(pv, jsonReplacer); + } else if (isPlainObject(pv)) { + encValue = JSON.stringify(pv, jsonReplacer); + } else { + encValue = `${encodeValue(pv)}`; + } + + tmp = `${encodeString(pk)}=${encValue}`; + + // If we end up with the nothing then skip forward + if (!tmp || tmp === "=") { + return; + } + + out += `&${tmp}`; + }); + + return out.slice(1); +} + +export function encodeDeepObject( + key: string, + value: unknown, + options?: { charEncoding?: "percent" | "none" }, +): string | undefined { + if (value == null) { + return; + } + + if (!isPlainObject(value)) { + throw new EncodingError( + `Value of parameter '${key}' which uses deepObject encoding must be an object or null`, + ); + } + + return encodeDeepObjectObject(key, value, options); +} + +export function encodeDeepObjectObject( + key: string, + value: unknown, + options?: { charEncoding?: "percent" | "none" }, +): string | undefined { + if (value == null) { + return; + } + + let out = ""; + + const encodeString = (v: string) => { + return options?.charEncoding === "percent" ? encodeURIComponent(v) : v; + }; + + if (!isPlainObject(value)) { + throw new EncodingError(`Expected parameter '${key}' to be an object.`); + } + + Object.entries(value).forEach(([ck, cv]) => { + if (cv == null) { + return; + } + + const pk = `${key}[${ck}]`; + + if (isPlainObject(cv)) { + const objOut = encodeDeepObjectObject(pk, cv, options); + + out += objOut == null ? "" : `&${objOut}`; + + return; + } + + const pairs: unknown[] = Array.isArray(cv) ? cv : [cv]; + const encoded = mapDefined(pairs, (v) => { + return `${encodeString(pk)}=${encodeString(serializeValue(v))}`; + })?.join("&"); + + out += encoded == null ? "" : `&${encoded}`; + }); + + return out.slice(1); +} + +export function encodeJSON( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: "percent" | "none" }, +): string | undefined { + if (typeof value === "undefined") { + return; + } + + const encodeString = (v: string) => { + return options?.charEncoding === "percent" ? encodeURIComponent(v) : v; + }; + + const encVal = encodeString(JSON.stringify(value, jsonReplacer)); + + return options?.explode ? encVal : `${encodeString(key)}=${encVal}`; +} + +export const encodeSimple = ( + key: string, + value: unknown, + options?: { explode?: boolean; charEncoding?: "percent" | "none" }, +): string | undefined => { + let out = ""; + const pairs: [string, unknown][] = options?.explode + ? explode(key, value) + : [[key, value]]; + + if (pairs.every(([_, v]) => v == null)) { + return; + } + + const encodeString = (v: string) => { + return options?.charEncoding === "percent" ? encodeURIComponent(v) : v; + }; + const encodeValue = (v: unknown) => encodeString(serializeValue(v)); + + pairs.forEach(([pk, pv]) => { + let tmp: string | null | undefined = ""; + + if (pv == null) { + return; + } else if (Array.isArray(pv)) { + tmp = mapDefined(pv, (v) => `${encodeValue(v)}`)?.join(","); + } else if (isPlainObject(pv)) { + const mapped = mapDefinedEntries(Object.entries(pv), ([k, v]) => { + return `,${encodeString(k)},${encodeValue(v)}`; + }); + tmp = mapped?.join("").slice(1); + } else { + const k = options?.explode && isPlainObject(value) ? `${pk}=` : ""; + tmp = `${k}${encodeValue(pv)}`; + } + + out += tmp ? `,${tmp}` : ""; + }); + + return out.slice(1); +}; + +function explode(key: string, value: unknown): [string, unknown][] { + if (Array.isArray(value)) { + return value.map((v) => [key, v]); + } else if (isPlainObject(value)) { + const o = value ?? {}; + return Object.entries(o).map(([k, v]) => [k, v]); + } else { + return [[key, value]]; + } +} + +function serializeValue(value: unknown): string { + if (value == null) { + return ""; + } else if (value instanceof Date) { + return value.toISOString(); + } else if (value instanceof Uint8Array) { + return bytesToBase64(value); + } else if (typeof value === "object") { + return JSON.stringify(value, jsonReplacer); + } + + return `${value}`; +} + +function jsonReplacer(_: string, value: unknown): unknown { + if (value instanceof Uint8Array) { + return bytesToBase64(value); + } else { + return value; + } +} + +function mapDefined(inp: T[], mapper: (v: T) => R): R[] | null { + const res = inp.reduce((acc, v) => { + if (v == null) { + return acc; + } + + const m = mapper(v); + if (m == null) { + return acc; + } + + acc.push(m); + + return acc; + }, []); + + return res.length ? res : null; +} + +function mapDefinedEntries( + inp: Iterable<[K, V]>, + mapper: (v: [K, V]) => R, +): R[] | null { + const acc: R[] = []; + for (const [k, v] of inp) { + if (v == null) { + continue; + } + + const m = mapper([k, v]); + if (m == null) { + continue; + } + + acc.push(m); + } + + return acc.length ? acc : null; +} + +export function queryJoin(...args: (string | undefined)[]): string { + return args.filter(Boolean).join("&"); +} + +type QueryEncoderOptions = { + explode?: boolean; + charEncoding?: "percent" | "none"; +}; + +type QueryEncoder = ( + key: string, + value: unknown, + options?: QueryEncoderOptions, +) => string | undefined; + +type BulkQueryEncoder = ( + values: Record, + options?: QueryEncoderOptions, +) => string; + +export function queryEncoder(f: QueryEncoder): BulkQueryEncoder { + const bulkEncode = function ( + values: Record, + options?: QueryEncoderOptions, + ): string { + const opts: QueryEncoderOptions = { + ...options, + explode: options?.explode ?? true, + charEncoding: options?.charEncoding ?? "percent", + }; + + const encoded = Object.entries(values).map(([key, value]) => { + return f(key, value, opts); + }); + return queryJoin(...encoded); + }; + + return bulkEncode; +} + +export const encodeJSONQuery = queryEncoder(encodeJSON); +export const encodeFormQuery = queryEncoder(encodeForm); +export const encodeSpaceDelimitedQuery = queryEncoder(encodeSpaceDelimited); +export const encodePipeDelimitedQuery = queryEncoder(encodePipeDelimited); +export const encodeDeepObjectQuery = queryEncoder(encodeDeepObject); + +export function appendForm( + fd: FormData, + key: string, + value: unknown, + fileName?: string, +): void { + if (value == null) { + return; + } else if (value instanceof Blob && fileName) { + fd.append(key, value, fileName); + } else if (value instanceof Blob) { + fd.append(key, value); + } else { + fd.append(key, String(value)); + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/env.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/env.ts new file mode 100644 index 0000000..b62cd8e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/env.ts @@ -0,0 +1,41 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { dlv } from "./dlv.js"; + +import * as z from "zod"; + +export interface Env { + SPEAKEASYCOFFEECLIENT_API_KEY_AUTH?: string | undefined; + + SPEAKEASYCOFFEECLIENT_DEBUG?: boolean | undefined; +} + +export const envSchema: z.ZodType = z.object({ + SPEAKEASYCOFFEECLIENT_API_KEY_AUTH: z.string().optional(), + + SPEAKEASYCOFFEECLIENT_DEBUG: z.coerce.boolean().optional(), +}); + +let envMemo: Env | undefined = undefined; +/** + * Reads and validates environment variables. + */ +export function env(): Env { + if (envMemo) { + return envMemo; + } + + envMemo = envSchema.parse( + dlv(globalThis, "process.env") ?? dlv(globalThis, "Deno.env") ?? {}, + ); + return envMemo; +} + +/** + * Clears the cached env object. Useful for testing with a fresh environment. + */ +export function resetEnv() { + envMemo = undefined; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/files.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/files.ts new file mode 100644 index 0000000..59d15f0 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/files.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +/** + * Consumes a stream and returns a concatenated array buffer. Useful in + * situations where we need to read the whole file because it forms part of a + * larger payload containing other fields, and we can't modify the underlying + * request structure. + */ +export async function readableStreamToArrayBuffer( + readable: ReadableStream, +): Promise { + const reader = readable.getReader(); + const chunks: Uint8Array[] = []; + + let totalLength = 0; + let done = false; + + while (!done) { + const { value, done: doneReading } = await reader.read(); + + if (doneReading) { + done = true; + } else { + chunks.push(value); + totalLength += value.length; + } + } + + const concatenatedChunks = new Uint8Array(totalLength); + let offset = 0; + + for (const chunk of chunks) { + concatenatedChunks.set(chunk, offset); + offset += chunk.length; + } + + return concatenatedChunks.buffer as ArrayBuffer; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/http.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/http.ts new file mode 100644 index 0000000..13cf1fd --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/http.ts @@ -0,0 +1,323 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export type Fetcher = ( + input: RequestInfo | URL, + init?: RequestInit, +) => Promise; + +export type Awaitable = T | Promise; + +const DEFAULT_FETCHER: Fetcher = (input, init) => { + // If input is a Request and init is undefined, Bun will discard the method, + // headers, body and other options that were set on the request object. + // Node.js and browers would ignore an undefined init value. This check is + // therefore needed for interop with Bun. + if (init == null) { + return fetch(input); + } else { + return fetch(input, init); + } +}; + +export type RequestInput = { + /** + * The URL the request will use. + */ + url: URL; + /** + * Options used to create a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request). + */ + options?: RequestInit | undefined; +}; + +export interface HTTPClientOptions { + fetcher?: Fetcher; +} + +export type BeforeRequestHook = (req: Request) => Awaitable; +export type RequestErrorHook = (err: unknown, req: Request) => Awaitable; +export type ResponseHook = (res: Response, req: Request) => Awaitable; + +export class HTTPClient { + private fetcher: Fetcher; + private requestHooks: BeforeRequestHook[] = []; + private requestErrorHooks: RequestErrorHook[] = []; + private responseHooks: ResponseHook[] = []; + + constructor(private options: HTTPClientOptions = {}) { + this.fetcher = options.fetcher || DEFAULT_FETCHER; + } + + async request(request: Request): Promise { + let req = request; + for (const hook of this.requestHooks) { + const nextRequest = await hook(req); + if (nextRequest) { + req = nextRequest; + } + } + + try { + const res = await this.fetcher(req); + + for (const hook of this.responseHooks) { + await hook(res, req); + } + + return res; + } catch (err) { + for (const hook of this.requestErrorHooks) { + await hook(err, req); + } + + throw err; + } + } + + /** + * Registers a hook that is called before a request is made. The hook function + * can mutate the request or return a new request. This may be useful to add + * additional information to request such as request IDs and tracing headers. + */ + addHook(hook: "beforeRequest", fn: BeforeRequestHook): this; + /** + * Registers a hook that is called when a request cannot be made due to a + * network error. + */ + addHook(hook: "requestError", fn: RequestErrorHook): this; + /** + * Registers a hook that is called when a response has been received from the + * server. + */ + addHook(hook: "response", fn: ResponseHook): this; + addHook( + ...args: + | [hook: "beforeRequest", fn: BeforeRequestHook] + | [hook: "requestError", fn: RequestErrorHook] + | [hook: "response", fn: ResponseHook] + ) { + if (args[0] === "beforeRequest") { + this.requestHooks.push(args[1]); + } else if (args[0] === "requestError") { + this.requestErrorHooks.push(args[1]); + } else if (args[0] === "response") { + this.responseHooks.push(args[1]); + } else { + throw new Error(`Invalid hook type: ${args[0]}`); + } + return this; + } + + /** Removes a hook that was previously registered with `addHook`. */ + removeHook(hook: "beforeRequest", fn: BeforeRequestHook): this; + /** Removes a hook that was previously registered with `addHook`. */ + removeHook(hook: "requestError", fn: RequestErrorHook): this; + /** Removes a hook that was previously registered with `addHook`. */ + removeHook(hook: "response", fn: ResponseHook): this; + removeHook( + ...args: + | [hook: "beforeRequest", fn: BeforeRequestHook] + | [hook: "requestError", fn: RequestErrorHook] + | [hook: "response", fn: ResponseHook] + ): this { + let target: unknown[]; + if (args[0] === "beforeRequest") { + target = this.requestHooks; + } else if (args[0] === "requestError") { + target = this.requestErrorHooks; + } else if (args[0] === "response") { + target = this.responseHooks; + } else { + throw new Error(`Invalid hook type: ${args[0]}`); + } + + const index = target.findIndex((v) => v === args[1]); + if (index >= 0) { + target.splice(index, 1); + } + + return this; + } + + clone(): HTTPClient { + const child = new HTTPClient(this.options); + child.requestHooks = this.requestHooks.slice(); + child.requestErrorHooks = this.requestErrorHooks.slice(); + child.responseHooks = this.responseHooks.slice(); + + return child; + } +} + +export type StatusCodePredicate = number | string | (number | string)[]; + +// A semicolon surrounded by optional whitespace characters is used to separate +// segments in a media type string. +const mediaParamSeparator = /\s*;\s*/g; + +export function matchContentType(response: Response, pattern: string): boolean { + // `*` is a special case which means anything is acceptable. + if (pattern === "*") { + return true; + } + + let contentType = + response.headers.get("content-type")?.trim() || "application/octet-stream"; + contentType = contentType.toLowerCase(); + + const wantParts = pattern.toLowerCase().trim().split(mediaParamSeparator); + const [wantType = "", ...wantParams] = wantParts; + + if (wantType.split("/").length !== 2) { + return false; + } + + const gotParts = contentType.split(mediaParamSeparator); + const [gotType = "", ...gotParams] = gotParts; + + const [type = "", subtype = ""] = gotType.split("/"); + if (!type || !subtype) { + return false; + } + + if ( + wantType !== "*/*" && + gotType !== wantType && + `${type}/*` !== wantType && + `*/${subtype}` !== wantType + ) { + return false; + } + + if (gotParams.length < wantParams.length) { + return false; + } + + const params = new Set(gotParams); + for (const wantParam of wantParams) { + if (!params.has(wantParam)) { + return false; + } + } + + return true; +} + +const codeRangeRE = new RegExp("^[0-9]xx$", "i"); + +export function matchStatusCode( + response: Response, + codes: StatusCodePredicate, +): boolean { + const actual = `${response.status}`; + const expectedCodes = Array.isArray(codes) ? codes : [codes]; + if (!expectedCodes.length) { + return false; + } + + return expectedCodes.some((ec) => { + const code = `${ec}`; + + if (code === "default") { + return true; + } + + if (!codeRangeRE.test(`${code}`)) { + return code === actual; + } + + const expectFamily = code.charAt(0); + if (!expectFamily) { + throw new Error("Invalid status code range"); + } + + const actualFamily = actual.charAt(0); + if (!actualFamily) { + throw new Error(`Invalid response status code: ${actual}`); + } + + return actualFamily === expectFamily; + }); +} + +export function matchResponse( + response: Response, + code: StatusCodePredicate, + contentTypePattern: string, +): boolean { + return ( + matchStatusCode(response, code) && + matchContentType(response, contentTypePattern) + ); +} + +/** + * Uses various heurisitics to determine if an error is a connection error. + */ +export function isConnectionError(err: unknown): boolean { + if (typeof err !== "object" || err == null) { + return false; + } + + // Covers fetch in Deno as well + const isBrowserErr = + err instanceof TypeError && + err.message.toLowerCase().startsWith("failed to fetch"); + + const isNodeErr = + err instanceof TypeError && + err.message.toLowerCase().startsWith("fetch failed"); + + const isBunErr = "name" in err && err.name === "ConnectionError"; + + const isGenericErr = + "code" in err && + typeof err.code === "string" && + err.code.toLowerCase() === "econnreset"; + + return isBrowserErr || isNodeErr || isGenericErr || isBunErr; +} + +/** + * Uses various heurisitics to determine if an error is a timeout error. + */ +export function isTimeoutError(err: unknown): boolean { + if (typeof err !== "object" || err == null) { + return false; + } + + // Fetch in browser, Node.js, Bun, Deno + const isNative = "name" in err && err.name === "TimeoutError"; + const isLegacyNative = "code" in err && err.code === 23; + + // Node.js HTTP client and Axios + const isGenericErr = + "code" in err && + typeof err.code === "string" && + err.code.toLowerCase() === "econnaborted"; + + return isNative || isLegacyNative || isGenericErr; +} + +/** + * Uses various heurisitics to determine if an error is a abort error. + */ +export function isAbortError(err: unknown): boolean { + if (typeof err !== "object" || err == null) { + return false; + } + + // Fetch in browser, Node.js, Bun, Deno + const isNative = "name" in err && err.name === "AbortError"; + const isLegacyNative = "code" in err && err.code === 20; + + // Node.js HTTP client and Axios + const isGenericErr = + "code" in err && + typeof err.code === "string" && + err.code.toLowerCase() === "econnaborted"; + + return isNative || isLegacyNative || isGenericErr; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/is-plain-object.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/is-plain-object.ts new file mode 100644 index 0000000..61070d3 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/is-plain-object.ts @@ -0,0 +1,43 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +/* +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// Taken from https://github.com/sindresorhus/is-plain-obj/blob/97f38e8836f86a642cce98fc6ab3058bc36df181/index.js + +export function isPlainObject(value: unknown): value is object { + if (typeof value !== "object" || value === null) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return ( + (prototype === null || + prototype === Object.prototype || + Object.getPrototypeOf(prototype) === null) && + !(Symbol.toStringTag in value) && + !(Symbol.iterator in value) + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/logger.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/logger.ts new file mode 100644 index 0000000..d181f29 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/logger.ts @@ -0,0 +1,9 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export interface Logger { + group(label?: string): void; + groupEnd(): void; + log(message: any, ...args: any[]): void; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/matchers.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/matchers.ts new file mode 100644 index 0000000..65858ac --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/matchers.ts @@ -0,0 +1,322 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { APIError } from "../models/errors/apierror.js"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { Result } from "../types/fp.js"; +import { matchResponse, matchStatusCode, StatusCodePredicate } from "./http.js"; +import { isPlainObject } from "./is-plain-object.js"; +import { safeParse } from "./schemas.js"; + +export type Encoding = + | "json" + | "text" + | "bytes" + | "stream" + | "sse" + | "nil" + | "fail"; + +const DEFAULT_CONTENT_TYPES: Record = { + json: "application/json", + text: "text/plain", + bytes: "application/octet-stream", + stream: "application/octet-stream", + sse: "text/event-stream", + nil: "*", + fail: "*", +}; + +type Schema = { parse(raw: unknown): T }; + +type MatchOptions = { + ctype?: string; + hdrs?: boolean; + key?: string; + sseSentinel?: string; +}; + +export type ValueMatcher = MatchOptions & { + enc: Encoding; + codes: StatusCodePredicate; + schema: Schema; +}; + +export type ErrorMatcher = MatchOptions & { + enc: Encoding; + codes: StatusCodePredicate; + schema: Schema; + err: true; +}; + +export type FailMatcher = { + enc: "fail"; + codes: StatusCodePredicate; +}; + +export type Matcher = ValueMatcher | ErrorMatcher | FailMatcher; + +export function jsonErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "json", codes, schema }; +} +export function json( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "json", codes, schema }; +} + +export function textErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "text", codes, schema }; +} +export function text( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "text", codes, schema }; +} + +export function bytesErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "bytes", codes, schema }; +} +export function bytes( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "bytes", codes, schema }; +} + +export function streamErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "stream", codes, schema }; +} +export function stream( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "stream", codes, schema }; +} + +export function sseErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "sse", codes, schema }; +} +export function sse( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "sse", codes, schema }; +} + +export function nilErr( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ErrorMatcher { + return { ...options, err: true, enc: "nil", codes, schema }; +} +export function nil( + codes: StatusCodePredicate, + schema: Schema, + options?: MatchOptions, +): ValueMatcher { + return { ...options, enc: "nil", codes, schema }; +} + +export function fail(codes: StatusCodePredicate): FailMatcher { + return { enc: "fail", codes }; +} + +export type MatchedValue = Matchers extends Matcher[] + ? T + : never; +export type MatchedError = Matchers extends Matcher[] + ? E + : never; +export type MatchFunc = ( + response: Response, + options?: { resultKey?: string; extraFields?: Record }, +) => Promise<[result: Result, raw: unknown]>; + +export function match( + ...matchers: Array> +): MatchFunc { + return async function matchFunc( + response: Response, + options?: { resultKey?: string; extraFields?: Record }, + ): Promise< + [result: Result, raw: unknown] + > { + let raw: unknown; + let matcher: Matcher | undefined; + for (const match of matchers) { + const { codes } = match; + const ctpattern = "ctype" in match + ? match.ctype + : DEFAULT_CONTENT_TYPES[match.enc]; + if (ctpattern && matchResponse(response, codes, ctpattern)) { + matcher = match; + break; + } else if (!ctpattern && matchStatusCode(response, codes)) { + matcher = match; + break; + } + } + + if (!matcher) { + const responseBody = await response.text(); + return [{ + ok: false, + error: new APIError( + "Unexpected API response status or content-type", + response, + responseBody, + ), + }, responseBody]; + } + + const encoding = matcher.enc; + switch (encoding) { + case "json": + raw = await response.json(); + break; + case "bytes": + raw = new Uint8Array(await response.arrayBuffer()); + break; + case "stream": + raw = response.body; + break; + case "text": + raw = await response.text(); + break; + case "sse": + raw = response.body; + break; + case "nil": + raw = await discardResponseBody(response); + break; + case "fail": + raw = await response.text(); + break; + default: + encoding satisfies never; + throw new Error(`Unsupported response type: ${encoding}`); + } + + if (matcher.enc === "fail") { + return [{ + ok: false, + error: new APIError( + "API error occurred", + response, + typeof raw === "string" ? raw : "", + ), + }, raw]; + } + + const resultKey = matcher.key || options?.resultKey; + let data: unknown; + + if ("err" in matcher) { + data = { + ...options?.extraFields, + ...(matcher.hdrs ? { Headers: unpackHeaders(response.headers) } : null), + ...(isPlainObject(raw) ? raw : null), + }; + } else if (resultKey) { + data = { + ...options?.extraFields, + ...(matcher.hdrs ? { Headers: unpackHeaders(response.headers) } : null), + [resultKey]: raw, + }; + } else if (matcher.hdrs) { + data = { + ...options?.extraFields, + ...(matcher.hdrs ? { Headers: unpackHeaders(response.headers) } : null), + ...(isPlainObject(raw) ? raw : null), + }; + } else { + data = raw; + } + + if ("err" in matcher) { + const result = safeParse( + data, + (v: unknown) => matcher.schema.parse(v), + "Response validation failed", + ); + return [result.ok ? { ok: false, error: result.value } : result, raw]; + } else { + return [ + safeParse( + data, + (v: unknown) => matcher.schema.parse(v), + "Response validation failed", + ), + raw, + ]; + } + }; +} + +const headerValRE = /, */; +/** + * Iterates over a Headers object and returns an object with all the header + * entries. Values are represented as an array to account for repeated headers. + */ +export function unpackHeaders(headers: Headers): Record { + const out: Record = {}; + + for (const [k, v] of headers.entries()) { + out[k] = v.split(headerValRE); + } + + return out; +} + +/** + * Discards the response body to free up resources. + * + * To learn why this is need, see the undici docs: + * https://undici.nodejs.org/#/?id=garbage-collection + */ +export async function discardResponseBody(res: Response) { + const reader = res.body?.getReader(); + if (reader == null) { + return; + } + + try { + let done = false; + while (!done) { + const res = await reader.read(); + done = res.done; + } + } finally { + reader.releaseLock(); + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/primitives.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/primitives.ts new file mode 100644 index 0000000..d21f1dc --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/primitives.ts @@ -0,0 +1,150 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +class InvariantError extends Error { + constructor(message: string) { + super(message); + this.name = "InvariantError"; + } +} + +export function invariant( + condition: unknown, + message: string, +): asserts condition { + if (!condition) { + throw new InvariantError(message); + } +} + +export type ExactPartial = { + [P in keyof T]?: T[P] | undefined; +}; + +export type Remap = { + [k in keyof Inp as Mapping[k] extends string /* if we have a string mapping for this key then use it */ + ? Mapping[k] + : Mapping[k] extends null /* if the mapping is to `null` then drop the key */ + ? never + : k /* otherwise keep the key as-is */]: Inp[k]; +}; + +/** + * Converts or omits an object's keys according to a mapping. + * + * @param inp An object whose keys will be remapped + * @param mappings A mapping of original keys to new keys. If a key is not present in the mapping, it will be left as is. If a key is mapped to `null`, it will be removed in the resulting object. + * @returns A new object with keys remapped or omitted according to the mappings + */ +export function remap< + Inp extends Record, + const Mapping extends { [k in keyof Inp]?: string | null }, +>(inp: Inp, mappings: Mapping): Remap { + let out: any = {}; + + if (!Object.keys(mappings).length) { + out = inp; + return out; + } + + for (const [k, v] of Object.entries(inp)) { + const j = mappings[k]; + if (j === null) { + continue; + } + out[j ?? k] = v; + } + + return out; +} + +export function combineSignals( + ...signals: Array +): AbortSignal | null { + const filtered: AbortSignal[] = []; + for (const signal of signals) { + if (signal) { + filtered.push(signal); + } + } + + switch (filtered.length) { + case 0: + case 1: + return filtered[0] || null; + default: + if ("any" in AbortSignal && typeof AbortSignal.any === "function") { + return AbortSignal.any(filtered); + } + return abortSignalAny(filtered); + } +} + +export function abortSignalAny(signals: AbortSignal[]): AbortSignal { + const controller = new AbortController(); + const result = controller.signal; + if (!signals.length) { + return controller.signal; + } + + if (signals.length === 1) { + return signals[0] || controller.signal; + } + + for (const signal of signals) { + if (signal.aborted) { + return signal; + } + } + + function abort(this: AbortSignal) { + controller.abort(this.reason); + clean(); + } + + const signalRefs: WeakRef[] = []; + function clean() { + for (const signalRef of signalRefs) { + const signal = signalRef.deref(); + if (signal) { + signal.removeEventListener("abort", abort); + } + } + } + + for (const signal of signals) { + signalRefs.push(new WeakRef(signal)); + signal.addEventListener("abort", abort); + } + + return result; +} + +export function compactMap( + values: Record, +): Record { + const out: Record = {}; + + for (const [k, v] of Object.entries(values)) { + if (typeof v !== "undefined") { + out[k] = v; + } + } + + return out; +} + +export function allRequired>( + v: V, +): + | { + [K in keyof V]: NonNullable; + } + | undefined { + if (Object.values(v).every((x) => x == null)) { + return void 0; + } + + return v as ReturnType>; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/retries.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/retries.ts new file mode 100644 index 0000000..e3ce9ab --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/retries.ts @@ -0,0 +1,218 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { isConnectionError, isTimeoutError } from "./http.js"; + +export type BackoffStrategy = { + initialInterval: number; + maxInterval: number; + exponent: number; + maxElapsedTime: number; +}; + +const defaultBackoff: BackoffStrategy = { + initialInterval: 500, + maxInterval: 60000, + exponent: 1.5, + maxElapsedTime: 3600000, +}; + +export type RetryConfig = + | { strategy: "none" } + | { + strategy: "backoff"; + backoff?: BackoffStrategy; + retryConnectionErrors?: boolean; + }; + +/** + * PermanentError is an error that is not recoverable. Throwing this error will + * cause a retry loop to terminate. + */ +export class PermanentError extends Error { + /** The underlying cause of the error. */ + override readonly cause: unknown; + + constructor(message: string, options?: { cause?: unknown }) { + let msg = message; + if (options?.cause) { + msg += `: ${options.cause}`; + } + + super(msg, options); + this.name = "PermanentError"; + // In older runtimes, the cause field would not have been assigned through + // the super() call. + if (typeof this.cause === "undefined") { + this.cause = options?.cause; + } + + Object.setPrototypeOf(this, PermanentError.prototype); + } +} + +/** + * TemporaryError is an error is used to signal that an HTTP request can be + * retried as part of a retry loop. If retry attempts are exhausted and this + * error is thrown, the response will be returned to the caller. + */ +export class TemporaryError extends Error { + response: Response; + + constructor(message: string, response: Response) { + super(message); + this.response = response; + this.name = "TemporaryError"; + + Object.setPrototypeOf(this, TemporaryError.prototype); + } +} + +export async function retry( + fetchFn: () => Promise, + options: { + config: RetryConfig; + statusCodes: string[]; + }, +): Promise { + switch (options.config.strategy) { + case "backoff": + return retryBackoff( + wrapFetcher(fetchFn, { + statusCodes: options.statusCodes, + retryConnectionErrors: !!options.config.retryConnectionErrors, + }), + options.config.backoff ?? defaultBackoff, + ); + default: + return await fetchFn(); + } +} + +function wrapFetcher( + fn: () => Promise, + options: { + statusCodes: string[]; + retryConnectionErrors: boolean; + }, +): () => Promise { + return async () => { + try { + const res = await fn(); + if (isRetryableResponse(res, options.statusCodes)) { + throw new TemporaryError( + "Response failed with retryable status code", + res, + ); + } + + return res; + } catch (err: unknown) { + if (err instanceof TemporaryError) { + throw err; + } + + if ( + options.retryConnectionErrors && + (isTimeoutError(err) || isConnectionError(err)) + ) { + throw err; + } + + throw new PermanentError("Permanent error", { cause: err }); + } + }; +} + +const codeRangeRE = new RegExp("^[0-9]xx$", "i"); + +function isRetryableResponse(res: Response, statusCodes: string[]): boolean { + const actual = `${res.status}`; + + return statusCodes.some((code) => { + if (!codeRangeRE.test(code)) { + return code === actual; + } + + const expectFamily = code.charAt(0); + if (!expectFamily) { + throw new Error("Invalid status code range"); + } + + const actualFamily = actual.charAt(0); + if (!actualFamily) { + throw new Error(`Invalid response status code: ${actual}`); + } + + return actualFamily === expectFamily; + }); +} + +async function retryBackoff( + fn: () => Promise, + strategy: BackoffStrategy, +): Promise { + const { maxElapsedTime, initialInterval, exponent, maxInterval } = strategy; + + const start = Date.now(); + let x = 0; + + while (true) { + try { + const res = await fn(); + return res; + } catch (err: unknown) { + if (err instanceof PermanentError) { + throw err.cause; + } + const elapsed = Date.now() - start; + if (elapsed > maxElapsedTime) { + if (err instanceof TemporaryError) { + return err.response; + } + + throw err; + } + + let retryInterval = 0; + if (err instanceof TemporaryError) { + retryInterval = retryIntervalFromResponse(err.response); + } + + if (retryInterval <= 0) { + retryInterval = + initialInterval * Math.pow(x, exponent) + Math.random() * 1000; + } + + const d = Math.min(retryInterval, maxInterval); + + await delay(d); + x++; + } + } +} + +function retryIntervalFromResponse(res: Response): number { + const retryVal = res.headers.get("retry-after") || ""; + if (!retryVal) { + return 0; + } + + const parsedNumber = Number(retryVal); + if (Number.isInteger(parsedNumber)) { + return parsedNumber * 1000; + } + + const parsedDate = Date.parse(retryVal); + if (Number.isInteger(parsedDate)) { + const deltaMS = parsedDate - Date.now(); + return deltaMS > 0 ? Math.ceil(deltaMS) : 0; + } + + return 0; +} + +async function delay(delay: number): Promise { + return new Promise((resolve) => setTimeout(resolve, delay)); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/schemas.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/schemas.ts new file mode 100644 index 0000000..0e340b7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/schemas.ts @@ -0,0 +1,91 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { + output, + ZodEffects, + ZodError, + ZodObject, + ZodRawShape, + ZodTypeAny, +} from "zod"; +import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; +import { ERR, OK, Result } from "../types/fp.js"; + +/** + * Utility function that executes some code which may throw a ZodError. It + * intercepts this error and converts it to an SDKValidationError so as to not + * leak Zod implementation details to user code. + */ +export function parse( + rawValue: Inp, + fn: (value: Inp) => Out, + errorMessage: string, +): Out { + try { + return fn(rawValue); + } catch (err) { + if (err instanceof ZodError) { + throw new SDKValidationError(errorMessage, err, rawValue); + } + throw err; + } +} + +/** + * Utility function that executes some code which may result in a ZodError. It + * intercepts this error and converts it to an SDKValidationError so as to not + * leak Zod implementation details to user code. + */ +export function safeParse( + rawValue: Inp, + fn: (value: Inp) => Out, + errorMessage: string, +): Result { + try { + return OK(fn(rawValue)); + } catch (err) { + return ERR(new SDKValidationError(errorMessage, err, rawValue)); + } +} + +export function collectExtraKeys< + Shape extends ZodRawShape, + Catchall extends ZodTypeAny, + K extends string, +>( + obj: ZodObject, + extrasKey: K, + optional: boolean, +): ZodEffects< + typeof obj, + & output> + & { + [k in K]: Record>; + } +> { + return obj.transform((val) => { + const extras: Record> = {}; + const { shape } = obj; + for (const [key] of Object.entries(val)) { + if (key in shape) { + continue; + } + + const v = val[key]; + if (typeof v === "undefined") { + continue; + } + + extras[key] = v; + delete val[key]; + } + + if (optional && Object.keys(extras).length === 0) { + return val; + } + + return { ...val, [extrasKey]: extras }; + }); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/sdks.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/sdks.ts new file mode 100644 index 0000000..2229261 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/sdks.ts @@ -0,0 +1,400 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SDKHooks } from "../hooks/hooks.js"; +import { HookContext } from "../hooks/types.js"; +import { + ConnectionError, + InvalidRequestError, + RequestAbortedError, + RequestTimeoutError, + UnexpectedClientError, +} from "../models/errors/httpclienterrors.js"; +import { ERR, OK, Result } from "../types/fp.js"; +import { stringToBase64 } from "./base64.js"; +import { SDK_METADATA, SDKOptions, serverURLFromOptions } from "./config.js"; +import { encodeForm } from "./encodings.js"; +import { env } from "./env.js"; +import { + HTTPClient, + isAbortError, + isConnectionError, + isTimeoutError, + matchContentType, + matchStatusCode, +} from "./http.js"; +import { Logger } from "./logger.js"; +import { retry, RetryConfig } from "./retries.js"; +import { SecurityState } from "./security.js"; + +export type RequestOptions = { + /** + * Sets a timeout, in milliseconds, on HTTP requests made by an SDK method. If + * `fetchOptions.signal` is set then it will take precedence over this option. + */ + timeoutMs?: number; + /** + * Set or override a retry policy on HTTP calls. + */ + retries?: RetryConfig; + /** + * Specifies the status codes which should be retried using the given retry policy. + */ + retryCodes?: string[]; + /** + * Overrides the base server URL that will be used by an operation. + */ + serverURL?: string | URL; + /** + * Sets various request options on the `fetch` call made by an SDK method. + * + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options|Request} + */ + fetchOptions?: Omit; +}; + +type RequestConfig = { + method: string; + path: string; + baseURL?: string | URL | undefined; + query?: string; + body?: RequestInit["body"]; + headers?: HeadersInit; + security?: SecurityState | null; + uaHeader?: string; + timeoutMs?: number; +}; + +const gt: unknown = typeof globalThis === "undefined" ? null : globalThis; +const webWorkerLike = typeof gt === "object" + && gt != null + && "importScripts" in gt + && typeof gt["importScripts"] === "function"; +const isBrowserLike = webWorkerLike + || (typeof navigator !== "undefined" && "serviceWorker" in navigator) + || (typeof window === "object" && typeof window.document !== "undefined"); + +export class ClientSDK { + readonly #httpClient: HTTPClient; + readonly #hooks: SDKHooks; + readonly #logger?: Logger | undefined; + public readonly _baseURL: URL | null; + public readonly _options: SDKOptions & { hooks?: SDKHooks }; + + constructor(options: SDKOptions = {}) { + const opt = options as unknown; + if ( + typeof opt === "object" + && opt != null + && "hooks" in opt + && opt.hooks instanceof SDKHooks + ) { + this.#hooks = opt.hooks; + } else { + this.#hooks = new SDKHooks(); + } + this._options = { ...options, hooks: this.#hooks }; + + const url = serverURLFromOptions(options); + if (url) { + url.pathname = url.pathname.replace(/\/+$/, "") + "/"; + } + const { baseURL, client } = this.#hooks.sdkInit({ + baseURL: url, + client: options.httpClient || new HTTPClient(), + }); + this._baseURL = baseURL; + this.#httpClient = client; + this.#logger = options.debugLogger; + if (!this.#logger && env().SPEAKEASYCOFFEECLIENT_DEBUG) { + this.#logger = console; + } + } + + public _createRequest( + context: HookContext, + conf: RequestConfig, + options?: RequestOptions, + ): Result { + const { method, path, query, headers: opHeaders, security } = conf; + + const base = conf.baseURL ?? this._baseURL; + if (!base) { + return ERR(new InvalidRequestError("No base URL provided for operation")); + } + const reqURL = new URL(base); + const inputURL = new URL(path, reqURL); + + if (path) { + reqURL.pathname += reqURL.pathname.endsWith("/") ? "" : "/"; + reqURL.pathname += inputURL.pathname.replace(/^\/+/, ""); + } + + let finalQuery = query || ""; + + const secQuery: string[] = []; + for (const [k, v] of Object.entries(security?.queryParams || {})) { + const q = encodeForm(k, v, { charEncoding: "percent" }); + if (typeof q !== "undefined") { + secQuery.push(q); + } + } + if (secQuery.length) { + finalQuery += `&${secQuery.join("&")}`; + } + + if (finalQuery) { + const q = finalQuery.startsWith("&") ? finalQuery.slice(1) : finalQuery; + reqURL.search = `?${q}`; + } + + const headers = new Headers(opHeaders); + + const username = security?.basic.username; + const password = security?.basic.password; + if (username != null || password != null) { + const encoded = stringToBase64( + [username || "", password || ""].join(":"), + ); + headers.set("Authorization", `Basic ${encoded}`); + } + + const securityHeaders = new Headers(security?.headers || {}); + for (const [k, v] of securityHeaders) { + headers.set(k, v); + } + + let cookie = headers.get("cookie") || ""; + for (const [k, v] of Object.entries(security?.cookies || {})) { + cookie += `; ${k}=${v}`; + } + cookie = cookie.startsWith("; ") ? cookie.slice(2) : cookie; + headers.set("cookie", cookie); + + const userHeaders = new Headers(options?.fetchOptions?.headers); + for (const [k, v] of userHeaders) { + headers.set(k, v); + } + + // Only set user agent header in non-browser-like environments since CORS + // policy disallows setting it in browsers e.g. Chrome throws an error. + if (!isBrowserLike) { + headers.set(conf.uaHeader ?? "user-agent", SDK_METADATA.userAgent); + } + + let fetchOptions = options?.fetchOptions; + if (!fetchOptions?.signal && conf.timeoutMs && conf.timeoutMs > 0) { + const timeoutSignal = AbortSignal.timeout(conf.timeoutMs); + if (!fetchOptions) { + fetchOptions = { signal: timeoutSignal }; + } else { + fetchOptions.signal = timeoutSignal; + } + } + + if (conf.body instanceof ReadableStream) { + if (!fetchOptions) { + fetchOptions = { + // @ts-expect-error see https://github.com/node-fetch/node-fetch/issues/1769 + duplex: "half", + }; + } else { + // @ts-expect-error see https://github.com/node-fetch/node-fetch/issues/1769 + fetchOptions.duplex = "half"; + } + } + + let input; + try { + input = this.#hooks.beforeCreateRequest(context, { + url: reqURL, + options: { + ...fetchOptions, + body: conf.body ?? null, + headers, + method, + }, + }); + } catch (err: unknown) { + return ERR( + new UnexpectedClientError("Create request hook failed to execute", { + cause: err, + }), + ); + } + + return OK(new Request(input.url, input.options)); + } + + public async _do( + request: Request, + options: { + context: HookContext; + errorCodes: number | string | (number | string)[]; + retryConfig: RetryConfig; + retryCodes: string[]; + }, + ): Promise< + Result< + Response, + | RequestAbortedError + | RequestTimeoutError + | ConnectionError + | UnexpectedClientError + > + > { + const { context, errorCodes } = options; + + return retry( + async () => { + const req = await this.#hooks.beforeRequest(context, request.clone()); + await logRequest(this.#logger, req).catch((e) => + this.#logger?.log("Failed to log request:", e) + ); + + let response = await this.#httpClient.request(req); + + try { + if (matchStatusCode(response, errorCodes)) { + const result = await this.#hooks.afterError( + context, + response, + null, + ); + if (result.error) { + throw result.error; + } + response = result.response || response; + } else { + response = await this.#hooks.afterSuccess(context, response); + } + } finally { + await logResponse(this.#logger, response, req) + .catch(e => this.#logger?.log("Failed to log response:", e)); + } + + return response; + }, + { config: options.retryConfig, statusCodes: options.retryCodes }, + ).then( + (r) => OK(r), + (err) => { + switch (true) { + case isAbortError(err): + return ERR( + new RequestAbortedError("Request aborted by client", { + cause: err, + }), + ); + case isTimeoutError(err): + return ERR( + new RequestTimeoutError("Request timed out", { cause: err }), + ); + case isConnectionError(err): + return ERR( + new ConnectionError("Unable to make request", { cause: err }), + ); + default: + return ERR( + new UnexpectedClientError("Unexpected HTTP client error", { + cause: err, + }), + ); + } + }, + ); + } +} + +const jsonLikeContentTypeRE = /^application\/(?:.{0,100}\+)?json/; +async function logRequest(logger: Logger | undefined, req: Request) { + if (!logger) { + return; + } + + const contentType = req.headers.get("content-type"); + const ct = contentType?.split(";")[0] || ""; + + logger.group(`> Request: ${req.method} ${req.url}`); + + logger.group("Headers:"); + for (const [k, v] of req.headers.entries()) { + logger.log(`${k}: ${v}`); + } + logger.groupEnd(); + + logger.group("Body:"); + switch (true) { + case jsonLikeContentTypeRE.test(ct): + logger.log(await req.clone().json()); + break; + case ct.startsWith("text/"): + logger.log(await req.clone().text()); + break; + case ct === "multipart/form-data": { + const body = await req.clone().formData(); + for (const [k, v] of body) { + const vlabel = v instanceof Blob ? "" : v; + logger.log(`${k}: ${vlabel}`); + } + break; + } + default: + logger.log(`<${contentType}>`); + break; + } + logger.groupEnd(); + + logger.groupEnd(); +} + +async function logResponse( + logger: Logger | undefined, + res: Response, + req: Request, +) { + if (!logger) { + return; + } + + const contentType = res.headers.get("content-type"); + const ct = contentType?.split(";")[0] || ""; + + logger.group(`< Response: ${req.method} ${req.url}`); + logger.log("Status Code:", res.status, res.statusText); + + logger.group("Headers:"); + for (const [k, v] of res.headers.entries()) { + logger.log(`${k}: ${v}`); + } + logger.groupEnd(); + + logger.group("Body:"); + switch (true) { + case matchContentType(res, "application/json") + || jsonLikeContentTypeRE.test(ct): + logger.log(await res.clone().json()); + break; + case matchContentType(res, "text/event-stream"): + logger.log(`<${contentType}>`); + break; + case matchContentType(res, "text/*"): + logger.log(await res.clone().text()); + break; + case matchContentType(res, "multipart/form-data"): { + const body = await res.clone().formData(); + for (const [k, v] of body) { + const vlabel = v instanceof Blob ? "" : v; + logger.log(`${k}: ${vlabel}`); + } + break; + } + default: + logger.log(`<${contentType}>`); + break; + } + logger.groupEnd(); + + logger.groupEnd(); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/security.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/security.ts new file mode 100644 index 0000000..a607d79 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/security.ts @@ -0,0 +1,253 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as components from "../models/components/index.js"; +import { env } from "./env.js"; +type OAuth2PasswordFlow = { + username: string; + password?: string | undefined; + clientID: string; + clientSecret?: string | undefined; + tokenURL: string; +}; + +export enum SecurityErrorCode { + Incomplete = "incomplete", + UnrecognisedSecurityType = "unrecognized_security_type", +} + +export class SecurityError extends Error { + constructor( + public code: SecurityErrorCode, + message: string, + ) { + super(message); + this.name = "SecurityError"; + } + + static incomplete(): SecurityError { + return new SecurityError( + SecurityErrorCode.Incomplete, + "Security requirements not met in order to perform the operation", + ); + } + static unrecognizedType(type: string): SecurityError { + return new SecurityError( + SecurityErrorCode.UnrecognisedSecurityType, + `Unrecognised security type: ${type}`, + ); + } +} + +export type SecurityState = { + basic: { username?: string | undefined; password?: string | undefined }; + headers: Record; + queryParams: Record; + cookies: Record; + oauth2: ({ type: "password" } & OAuth2PasswordFlow) | { type: "none" }; +}; + +type SecurityInputBasic = { + type: "http:basic"; + value: + | { username?: string | undefined; password?: string | undefined } + | null + | undefined; +}; + +type SecurityInputBearer = { + type: "http:bearer"; + value: string | null | undefined; + fieldName: string; +}; + +type SecurityInputAPIKey = { + type: "apiKey:header" | "apiKey:query" | "apiKey:cookie"; + value: string | null | undefined; + fieldName: string; +}; + +type SecurityInputOIDC = { + type: "openIdConnect"; + value: string | null | undefined; + fieldName: string; +}; + +type SecurityInputOAuth2 = { + type: "oauth2"; + value: string | null | undefined; + fieldName: string; +}; + +type SecurityInputOAuth2ClientCredentials = { + type: "oauth2:client_credentials"; + value: + | { clientID?: string | undefined; clientSecret?: string | undefined } + | null + | undefined; +}; + +type SecurityInputOAuth2PasswordCredentials = { + type: "oauth2:password"; + value: + | string + | null + | undefined; + fieldName: string; +}; + +type SecurityInputCustom = { + type: "http:custom"; + value: any | null | undefined; + fieldName: string; +}; + +export type SecurityInput = + | SecurityInputBasic + | SecurityInputBearer + | SecurityInputAPIKey + | SecurityInputOAuth2 + | SecurityInputOAuth2ClientCredentials + | SecurityInputOAuth2PasswordCredentials + | SecurityInputOIDC + | SecurityInputCustom; + +export function resolveSecurity( + ...options: SecurityInput[][] +): SecurityState | null { + const state: SecurityState = { + basic: {}, + headers: {}, + queryParams: {}, + cookies: {}, + oauth2: { type: "none" }, + }; + + const option = options.find((opts) => { + return opts.every((o) => { + if (o.value == null) { + return false; + } else if (o.type === "http:basic") { + return o.value.username != null || o.value.password != null; + } else if (o.type === "http:custom") { + return null; + } else if (o.type === "oauth2:password") { + return ( + typeof o.value === "string" && !!o.value + ); + } else if (o.type === "oauth2:client_credentials") { + return o.value.clientID != null || o.value.clientSecret != null; + } else if (typeof o.value === "string") { + return !!o.value; + } else { + throw new Error( + `Unrecognized security type: ${o.type} (value type: ${typeof o + .value})`, + ); + } + }); + }); + if (option == null) { + return null; + } + + option.forEach((spec) => { + if (spec.value == null) { + return; + } + + const { type } = spec; + + switch (type) { + case "apiKey:header": + state.headers[spec.fieldName] = spec.value; + break; + case "apiKey:query": + state.queryParams[spec.fieldName] = spec.value; + break; + case "apiKey:cookie": + state.cookies[spec.fieldName] = spec.value; + break; + case "http:basic": + applyBasic(state, spec); + break; + case "http:custom": + break; + case "http:bearer": + applyBearer(state, spec); + break; + case "oauth2": + applyBearer(state, spec); + break; + case "oauth2:password": + applyBearer(state, spec); + break; + case "oauth2:client_credentials": + break; + case "openIdConnect": + applyBearer(state, spec); + break; + default: + spec satisfies never; + throw SecurityError.unrecognizedType(type); + } + }); + + return state; +} + +function applyBasic( + state: SecurityState, + spec: SecurityInputBasic, +) { + if (spec.value == null) { + return; + } + + state.basic = spec.value; +} + +function applyBearer( + state: SecurityState, + spec: + | SecurityInputBearer + | SecurityInputOAuth2 + | SecurityInputOIDC + | SecurityInputOAuth2PasswordCredentials, +) { + if (typeof spec.value !== "string" || !spec.value) { + return; + } + + let value = spec.value; + if (value.slice(0, 7).toLowerCase() !== "bearer ") { + value = `Bearer ${value}`; + } + + state.headers[spec.fieldName] = value; +} + +export function resolveGlobalSecurity( + security: Partial | null | undefined, +): SecurityState | null { + return resolveSecurity( + [ + { + fieldName: "X-API-Key", + type: "apiKey:header", + value: security?.apiKeyAuth ?? env().SPEAKEASYCOFFEECLIENT_API_KEY_AUTH, + }, + ], + ); +} + +export async function extractSecurity< + T extends string | Record, +>(sec: T | (() => Promise) | undefined): Promise { + if (sec == null) { + return; + } + + return typeof sec === "function" ? sec() : sec; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/url.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/url.ts new file mode 100644 index 0000000..6bc6356 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/lib/url.ts @@ -0,0 +1,33 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +const hasOwn = Object.prototype.hasOwnProperty; + +export type Params = Partial>; + +export function pathToFunc( + pathPattern: string, + options?: { charEncoding?: "percent" | "none" }, +): (params?: Params) => string { + const paramRE = /\{([a-zA-Z0-9_]+?)\}/g; + + return function buildURLPath(params: Record = {}): string { + return pathPattern.replace(paramRE, function (_, placeholder) { + if (!hasOwn.call(params, placeholder)) { + throw new Error(`Parameter '${placeholder}' is required`); + } + + const value = params[placeholder]; + if (typeof value !== "string" && typeof value !== "number") { + throw new Error( + `Parameter '${placeholder}' must be a string or number`, + ); + } + + return options?.charEncoding === "percent" + ? encodeURIComponent(`${value}`) + : `${value}`; + }); + }; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/build.mts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/build.mts new file mode 100644 index 0000000..a04739f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/build.mts @@ -0,0 +1,16 @@ +/// + +import { build } from "bun"; + +const entrypoint = "./src/mcp-server/mcp-server.ts"; + +await build({ + entrypoints: [entrypoint], + outdir: "./bin", + sourcemap: "linked", + target: "node", + format: "esm", + minify: false, + throw: true, + banner: "#!/usr/bin/env node", +}); diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/cli.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/cli.ts new file mode 100644 index 0000000..b878d8d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/cli.ts @@ -0,0 +1,13 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { CommandContext, StricliProcess } from "@stricli/core"; + +export interface LocalContext extends CommandContext { + readonly process: StricliProcess; +} + +export function buildContext(process: NodeJS.Process): LocalContext { + return { process: process as StricliProcess }; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/cli/start/command.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/cli/start/command.ts new file mode 100644 index 0000000..a4ce9a6 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/cli/start/command.ts @@ -0,0 +1,107 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { buildCommand } from "@stricli/core"; +import { numberParser } from "@stricli/core"; +import * as z from "zod"; +import { consoleLoggerLevels } from "../../console-logger.js"; +import { mcpScopes } from "../../scopes.js"; + +export const startCommand = buildCommand({ + loader: async () => { + const { main } = await import("./impl.js"); + return main; + }, + parameters: { + flags: { + transport: { + kind: "enum", + brief: "The transport to use for communicating with the server", + default: "stdio", + values: ["stdio", "sse"], + }, + port: { + kind: "parsed", + brief: "The port to use when the SSE transport is enabled", + default: "2718", + parse: (val: string) => + z.coerce.number().int().gte(0).lt(65536).parse(val), + }, + tool: { + kind: "parsed", + brief: "Specify tools to mount on the server", + optional: true, + variadic: true, + parse: (value) => { + return z.string().parse(value); + }, + }, + ...(mcpScopes.length + ? { + scope: { + kind: "enum", + brief: + "Mount tools/resources that match given scope (repeatable flag)", + values: mcpScopes, + variadic: true, + optional: true, + }, + } + : {}), + "api-key-auth": { + kind: "parsed", + brief: "Sets the apiKeyAuth auth field for the API", + optional: true, + parse: (value) => { + return z.string().parse(value); + }, + }, + "server-url": { + kind: "parsed", + brief: "Overrides the default server URL used by the SDK", + optional: true, + parse: (value) => new URL(value).toString(), + }, + "server-index": { + kind: "parsed", + brief: "Selects a predefined server used by the SDK", + optional: true, + parse: numberParser, + }, + "log-level": { + kind: "enum", + brief: "The log level to use for the server", + default: "info", + values: consoleLoggerLevels, + }, + env: { + kind: "parsed", + brief: "Environment variables made available to the server", + optional: true, + variadic: true, + parse: (val: string) => { + const sepIdx = val.indexOf("="); + if (sepIdx === -1) { + throw new Error("Invalid environment variable format"); + } + + const key = val.slice(0, sepIdx); + const value = val.slice(sepIdx + 1); + + return [ + z.string().nonempty({ + message: "Environment variable key must be a non-empty string", + }).parse(key), + z.string().nonempty({ + message: "Environment variable value must be a non-empty string", + }).parse(value), + ] satisfies [string, string]; + }, + }, + }, + }, + docs: { + brief: "Run the Model Context Protocol server", + }, +}); diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/cli/start/impl.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/cli/start/impl.ts new file mode 100644 index 0000000..757bca6 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/cli/start/impl.ts @@ -0,0 +1,134 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import express from "express"; +import { SDKOptions } from "../../../lib/config.js"; +import { LocalContext } from "../../cli.js"; +import { + ConsoleLoggerLevel, + createConsoleLogger, +} from "../../console-logger.js"; +import { MCPScope } from "../../scopes.js"; +import { createMCPServer } from "../../server.js"; + +interface StartCommandFlags { + readonly transport: "stdio" | "sse"; + readonly port: number; + readonly tool?: string[]; + readonly scope?: MCPScope[]; + readonly "api-key-auth"?: string | undefined; + readonly "server-url"?: string; + readonly "server-index"?: SDKOptions["serverIdx"]; + readonly "log-level": ConsoleLoggerLevel; + readonly env?: [string, string][]; +} + +export async function main(this: LocalContext, flags: StartCommandFlags) { + flags.env?.forEach(([key, value]) => { + process.env[key] = value; + }); + + switch (flags.transport) { + case "stdio": + await startStdio(flags); + break; + case "sse": + await startSSE(flags); + break; + default: + throw new Error(`Invalid transport: ${flags.transport}`); + } +} + +async function startStdio(flags: StartCommandFlags) { + const logger = createConsoleLogger(flags["log-level"]); + const transport = new StdioServerTransport(); + const server = createMCPServer({ + logger, + allowedTools: flags.tool, + scopes: flags.scope, + ...{ apiKeyAuth: flags["api-key-auth"] }, + serverURL: flags["server-url"], + serverIdx: flags["server-index"], + }); + await server.connect(transport); + + const abort = async () => { + await server.close(); + process.exit(0); + }; + process.on("SIGTERM", abort); + process.on("SIGINT", abort); +} + +async function startSSE(flags: StartCommandFlags) { + const logger = createConsoleLogger(flags["log-level"]); + const app = express(); + const mcpServer = createMCPServer({ + logger, + allowedTools: flags.tool, + scopes: flags.scope, + ...{ apiKeyAuth: flags["api-key-auth"] }, + serverURL: flags["server-url"], + serverIdx: flags["server-index"], + }); + let transport: SSEServerTransport | undefined; + const controller = new AbortController(); + + app.get("/sse", async (_req, res) => { + transport = new SSEServerTransport("/message", res); + + await mcpServer.connect(transport); + + mcpServer.server.onclose = async () => { + res.end(); + }; + }); + + app.post("/message", async (req, res) => { + if (!transport) { + throw new Error("Server transport not initialized"); + } + + await transport.handlePostMessage(req, res); + }); + + const httpServer = app.listen(flags.port, "0.0.0.0", () => { + const ha = httpServer.address(); + const host = typeof ha === "string" ? ha : `${ha?.address}:${ha?.port}`; + logger.info("MCP HTTP server started", { host }); + }); + + let closing = false; + controller.signal.addEventListener("abort", async () => { + if (closing) { + logger.info("Received second signal. Forcing shutdown."); + process.exit(1); + } + closing = true; + + logger.info("Shutting down MCP server"); + + await mcpServer.close(); + + logger.info("Shutting down HTTP server"); + + const timer = setTimeout(() => { + logger.info("Forcing shutdown"); + process.exit(1); + }, 5000); + + httpServer.close(() => { + clearTimeout(timer); + logger.info("Graceful shutdown complete"); + process.exit(0); + }); + }); + + const abort = () => controller.abort(); + process.on("SIGTERM", abort); + process.on("SIGINT", abort); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/console-logger.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/console-logger.ts new file mode 100644 index 0000000..d65a295 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/console-logger.ts @@ -0,0 +1,71 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export const consoleLoggerLevels = [ + "debug", + "warning", + "info", + "error", +] as const; + +export type ConsoleLoggerLevel = (typeof consoleLoggerLevels)[number]; + +export type ConsoleLogger = { + [key in ConsoleLoggerLevel]: ( + message: string, + data?: Record, + ) => void; +}; + +export function createConsoleLogger(level: ConsoleLoggerLevel): ConsoleLogger { + const min = consoleLoggerLevels.indexOf(level); + const noop = () => {}; + + const logger: ConsoleLogger = { + debug: noop, + warning: noop, + info: noop, + error: noop, + }; + + return consoleLoggerLevels.reduce((logger, level, i) => { + if (i < min) { + return logger; + } + + logger[level] = log.bind(null, level); + + return logger; + }, logger); +} + +function log( + level: ConsoleLoggerLevel, + message: string, + data?: Record, +) { + let line = ""; + const allData = [{ msg: message, l: level }, data]; + + for (const ctx of allData) { + for (const [key, value] of Object.entries(ctx || {})) { + if (value == null) { + line += ` ${key}=<${value}>`; + } else if (typeof value === "function") { + line += ` ${key}=`; + } else if (typeof value === "symbol") { + line += ` ${key}=${value.toString()}`; + } else if (typeof value === "string") { + const v = value.search(/\s/g) >= 0 ? JSON.stringify(value) : value; + line += ` ${key}=${v}`; + } else if (typeof value !== "object") { + line += ` ${key}=${value}`; + } else { + line += ` ${key}="${JSON.stringify(value)}"`; + } + } + } + + console.error(line); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/mcp-server.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/mcp-server.ts new file mode 100644 index 0000000..549dc47 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/mcp-server.ts @@ -0,0 +1,26 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { buildApplication, buildRouteMap, run } from "@stricli/core"; +import process from "node:process"; +import { buildContext } from "./cli.js"; +import { startCommand } from "./cli/start/command.js"; + +const routes = buildRouteMap({ + routes: { + start: startCommand, + }, + docs: { + brief: "MCP server CLI", + }, +}); + +export const app = buildApplication(routes, { + name: "mcp", + versionInfo: { + currentVersion: "0.1.0", + }, +}); + +run(app, process.argv.slice(2), buildContext(process)); diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/resources.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/resources.ts new file mode 100644 index 0000000..e2da180 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/resources.ts @@ -0,0 +1,96 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js"; +import { Variables } from "@modelcontextprotocol/sdk/shared/uriTemplate.js"; +import { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js"; +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { Result } from "../types/fp.js"; +import { MCPScope } from "./scopes.js"; +import { isAsyncIterable, isBinaryData, valueToBase64 } from "./shared.js"; + +export type ReadResourceCallback = ( + client: SpeakeasyCoffeeClientCore, + uri: URL, + extra: RequestHandlerExtra, +) => ReadResourceResult | Promise; + +export type ResourceDefinition = { + name: string; + description: string; + scopes?: MCPScope[]; + resource: string; + read: ReadResourceCallback; +}; + +export type ReadResourceTemplateCallback = ( + client: SpeakeasyCoffeeClientCore, + uri: URL, + vars: Variables, + extra: RequestHandlerExtra, +) => ReadResourceResult | Promise; + +export type ResourceTemplateDefinition = { + name: string; + description: string; + scopes?: MCPScope[]; + resource: ResourceTemplate; + read: ReadResourceTemplateCallback; +}; + +export async function formatResult( + result: Result, + uri: URL, + init: { response?: Response | undefined }, +): Promise { + if (!result.ok) { + throw result.error; + } + + const { value } = result; + if (typeof value === "undefined") { + return { contents: [] }; + } + + const { response } = init; + const mimeType = response?.headers.get("content-type") ?? ""; + let contents: ReadResourceResult["contents"] = []; + + if (mimeType.search(/\bjson\b/g)) { + contents = [{ uri: uri.toString(), mimeType, text: JSON.stringify(value) }]; + } else if ( + mimeType.startsWith("text/event-stream") + && isAsyncIterable(value) + ) { + contents = [ + { + uri: uri.toString(), + mimeType: "application/json", + text: await stringifySSEToJSON(value), + }, + ]; + } else if (mimeType.startsWith("text/") && typeof value === "string") { + contents = [{ uri: uri.toString(), mimeType, text: value }]; + } else if (isBinaryData(value)) { + const blob = await valueToBase64(value); + contents = blob == null ? [] : [{ uri: uri.toString(), blob, mimeType }]; + } else { + throw new Error(`Unsupported content type: "${mimeType}"`); + } + + return { contents }; +} + +async function stringifySSEToJSON( + value: AsyncIterable, +): Promise { + const payloads = []; + + for await (const chunk of value) { + payloads.push(chunk); + } + + return JSON.stringify(payloads); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/scopes.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/scopes.ts new file mode 100644 index 0000000..c25696d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/scopes.ts @@ -0,0 +1,7 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export const mcpScopes = [] as const; + +export type MCPScope = (typeof mcpScopes)[number]; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/server.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/server.ts new file mode 100644 index 0000000..098e692 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/server.ts @@ -0,0 +1,62 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { SDKOptions } from "../lib/config.js"; +import type { ConsoleLogger } from "./console-logger.js"; +import { MCPScope, mcpScopes } from "./scopes.js"; +import { createRegisterTool } from "./tools.js"; +import { tool$coffeeTypesCreate } from "./tools/coffeeTypesCreate.js"; +import { tool$coffeeTypesDelete } from "./tools/coffeeTypesDelete.js"; +import { tool$coffeeTypesGetById } from "./tools/coffeeTypesGetById.js"; +import { tool$coffeeTypesList } from "./tools/coffeeTypesList.js"; +import { tool$coffeeTypesUpdate } from "./tools/coffeeTypesUpdate.js"; +import { tool$ordersCreate } from "./tools/ordersCreate.js"; +import { tool$ordersDelete } from "./tools/ordersDelete.js"; +import { tool$ordersGetById } from "./tools/ordersGetById.js"; +import { tool$ordersList } from "./tools/ordersList.js"; +import { tool$ordersUpdate } from "./tools/ordersUpdate.js"; + +export function createMCPServer(deps: { + logger: ConsoleLogger; + allowedTools?: string[] | undefined; + scopes?: MCPScope[] | undefined; + serverURL?: string | undefined; + apiKeyAuth?: SDKOptions["apiKeyAuth"] | undefined; + serverIdx?: SDKOptions["serverIdx"] | undefined; +}) { + const server = new McpServer({ + name: "SpeakeasyCoffeeClient", + version: "0.1.0", + }); + + const client = new SpeakeasyCoffeeClientCore({ + apiKeyAuth: deps.apiKeyAuth, + serverURL: deps.serverURL, + serverIdx: deps.serverIdx, + }); + const scopes = new Set(deps.scopes ?? mcpScopes); + const allowedTools = deps.allowedTools && new Set(deps.allowedTools); + const tool = createRegisterTool( + deps.logger, + server, + client, + scopes, + allowedTools, + ); + + tool(tool$ordersList); + tool(tool$ordersCreate); + tool(tool$ordersGetById); + tool(tool$ordersUpdate); + tool(tool$ordersDelete); + tool(tool$coffeeTypesList); + tool(tool$coffeeTypesCreate); + tool(tool$coffeeTypesGetById); + tool(tool$coffeeTypesUpdate); + tool(tool$coffeeTypesDelete); + + return server; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/shared.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/shared.ts new file mode 100644 index 0000000..9dc6d2f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/shared.ts @@ -0,0 +1,75 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { bytesToBase64 } from "../lib/base64.js"; + +type BinaryData = + | Uint8Array + | ArrayBuffer + | Blob + | ReadableStream + | Response + | string; + +export async function consumeStream( + stream: ReadableStream, +): Promise { + const reader = stream.getReader(); + const chunks: Uint8Array[] = []; + + try { + while (true) { + const { done, value } = await reader.read(); + if (value != null) chunks.push(value); + if (done) break; + } + } finally { + reader.releaseLock(); + } + + return new Uint8Array(await new Blob(chunks).arrayBuffer()); +} + +export function isAsyncIterable( + value: unknown, +): value is AsyncIterable { + return ( + typeof value === "object" && value != null && Symbol.asyncIterator in value + ); +} + +export function isBinaryData(value: unknown): value is BinaryData { + return ( + value instanceof Uint8Array + || value instanceof ArrayBuffer + || value instanceof Blob + || value instanceof ReadableStream + || value instanceof Response + || typeof value === "string" + ); +} + +const base64Schema = z.string().base64(); + +export async function valueToBase64( + value: BinaryData | null | undefined, +): Promise { + if (value == null) { + return null; + } else if (value instanceof Uint8Array) { + return bytesToBase64(value); + } else if (value instanceof ArrayBuffer) { + return bytesToBase64(new Uint8Array(value)); + } else if (value instanceof Response || value instanceof Blob) { + return bytesToBase64(new Uint8Array(await value.arrayBuffer())); + } else if (value instanceof ReadableStream) { + return bytesToBase64(await consumeStream(value)); + } else if (typeof value === "string") { + return base64Schema.parse(value); + } else { + value satisfies never; + throw new Error(`Unsupported image value type: ${typeof value}`); + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools.ts new file mode 100644 index 0000000..af65baa --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools.ts @@ -0,0 +1,121 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js"; +import { CallToolResult } from "@modelcontextprotocol/sdk/types.js"; +import { objectOutputType, ZodRawShape, ZodTypeAny } from "zod"; +import { SpeakeasyCoffeeClientCore } from "../core.js"; +import { ConsoleLogger } from "./console-logger.js"; +import { MCPScope } from "./scopes.js"; +import { isAsyncIterable, isBinaryData, valueToBase64 } from "./shared.js"; + +export type ToolDefinition = + Args extends ZodRawShape ? { + name: string; + description: string; + scopes?: MCPScope[]; + args: Args; + tool: ( + client: SpeakeasyCoffeeClientCore, + args: objectOutputType, + extra: RequestHandlerExtra, + ) => CallToolResult | Promise; + } + : { + name: string; + description: string; + scopes?: MCPScope[]; + args?: undefined; + tool: ( + client: SpeakeasyCoffeeClientCore, + extra: RequestHandlerExtra, + ) => CallToolResult | Promise; + }; + +export async function formatResult( + value: unknown, + init: { response?: Response | undefined }, +): Promise { + if (typeof value === "undefined") { + return { content: [] }; + } + + const { response } = init; + const contentType = response?.headers.get("content-type") ?? ""; + let content: CallToolResult["content"] = []; + + if (contentType.search(/\bjson\b/g)) { + content = [{ type: "text", text: JSON.stringify(value) }]; + } else if ( + contentType.startsWith("text/event-stream") + && isAsyncIterable(value) + ) { + content = await consumeSSE(value); + } else if (contentType.startsWith("text/") && typeof value === "string") { + content = [{ type: "text", text: value }]; + } else if (isBinaryData(value) && contentType.startsWith("image/")) { + const data = await valueToBase64(value); + content = data == null + ? [] + : [{ type: "image", data, mimeType: contentType }]; + } else { + return { + content: [{ + type: "text", + text: `Unsupported content type: "${contentType}"`, + }], + isError: true, + }; + } + + return { content }; +} + +async function consumeSSE( + value: AsyncIterable, +): Promise { + const content: CallToolResult["content"] = []; + + for await (const chunk of value) { + if (typeof chunk === "string") { + content.push({ type: "text", text: chunk }); + } else { + content.push({ type: "text", text: JSON.stringify(chunk) }); + } + } + + return content; +} + +export function createRegisterTool( + logger: ConsoleLogger, + server: McpServer, + sdk: SpeakeasyCoffeeClientCore, + allowedScopes: Set, + allowedTools?: Set, +): (tool: ToolDefinition) => void { + return (tool: ToolDefinition): void => { + if (allowedTools && !allowedTools.has(tool.name)) { + return; + } + + const toolScopes = tool.scopes ?? []; + if (!toolScopes.every((s) => allowedScopes.has(s))) { + return; + } + + if (tool.args) { + server.tool(tool.name, tool.description, tool.args, async (args, ctx) => { + return tool.tool(sdk, args, ctx); + }); + } else { + server.tool(tool.name, tool.description, async (ctx) => { + return tool.tool(sdk, ctx); + }); + } + + logger.debug("Registered tool", { name: tool.name }); + }; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesCreate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesCreate.ts new file mode 100644 index 0000000..5d0337b --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesCreate.ts @@ -0,0 +1,37 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { coffeeTypesCreate } from "../../funcs/coffeeTypesCreate.js"; +import * as components from "../../models/components/index.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +const args = { + request: components.CoffeeType$inboundSchema, +}; + +export const tool$coffeeTypesCreate: ToolDefinition = { + name: "coffee-types_create", + description: `Create Coffee Type + +Create a new coffee type.`, + args, + tool: async (client, args, ctx) => { + const [result, apiCall] = await coffeeTypesCreate( + client, + args.request, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + const value = result.value; + + return formatResult(value, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesDelete.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesDelete.ts new file mode 100644 index 0000000..7a88bf1 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesDelete.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { coffeeTypesDelete } from "../../funcs/coffeeTypesDelete.js"; +import * as operations from "../../models/operations/index.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +const args = { + request: operations.DeleteCoffeeTypeRequest$inboundSchema, +}; + +export const tool$coffeeTypesDelete: ToolDefinition = { + name: "coffee-types_delete", + description: `Delete Coffee Type + +Delete a coffee type.`, + args, + tool: async (client, args, ctx) => { + const [result, apiCall] = await coffeeTypesDelete( + client, + args.request, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + return formatResult(void 0, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesGetById.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesGetById.ts new file mode 100644 index 0000000..eab5f5c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesGetById.ts @@ -0,0 +1,37 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { coffeeTypesGetById } from "../../funcs/coffeeTypesGetById.js"; +import * as operations from "../../models/operations/index.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +const args = { + request: operations.GetCoffeeTypeRequest$inboundSchema, +}; + +export const tool$coffeeTypesGetById: ToolDefinition = { + name: "coffee-types_get-by-id", + description: `Get Coffee Type + +Retrieve a specific coffee type by its ID.`, + args, + tool: async (client, args, ctx) => { + const [result, apiCall] = await coffeeTypesGetById( + client, + args.request, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + const value = result.value; + + return formatResult(value, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesList.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesList.ts new file mode 100644 index 0000000..7383ebe --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesList.ts @@ -0,0 +1,30 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { coffeeTypesList } from "../../funcs/coffeeTypesList.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +export const tool$coffeeTypesList: ToolDefinition = { + name: "coffee-types_list", + description: `Get Coffee Types + +Retrieve all available coffee types.`, + tool: async (client, ctx) => { + const [result, apiCall] = await coffeeTypesList( + client, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + const value = result.value; + + return formatResult(value, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesUpdate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesUpdate.ts new file mode 100644 index 0000000..88aaa37 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/coffeeTypesUpdate.ts @@ -0,0 +1,37 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { coffeeTypesUpdate } from "../../funcs/coffeeTypesUpdate.js"; +import * as operations from "../../models/operations/index.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +const args = { + request: operations.UpdateCoffeeTypeRequest$inboundSchema, +}; + +export const tool$coffeeTypesUpdate: ToolDefinition = { + name: "coffee-types_update", + description: `Update Coffee Type + +Update an existing coffee type.`, + args, + tool: async (client, args, ctx) => { + const [result, apiCall] = await coffeeTypesUpdate( + client, + args.request, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + const value = result.value; + + return formatResult(value, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersCreate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersCreate.ts new file mode 100644 index 0000000..f583660 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersCreate.ts @@ -0,0 +1,39 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ordersCreate } from "../../funcs/ordersCreate.js"; +import * as components from "../../models/components/index.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +const args = { + request: components.CoffeeOrder$inboundSchema, +}; + +export const tool$ordersCreate: ToolDefinition = { + name: "orders_create", + description: `Create Order + +Create a new coffee order. +Validates that the coffee type exists. +`, + args, + tool: async (client, args, ctx) => { + const [result, apiCall] = await ordersCreate( + client, + args.request, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + const value = result.value; + + return formatResult(value, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersDelete.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersDelete.ts new file mode 100644 index 0000000..4c55e77 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersDelete.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ordersDelete } from "../../funcs/ordersDelete.js"; +import * as operations from "../../models/operations/index.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +const args = { + request: operations.DeleteOrderRequest$inboundSchema, +}; + +export const tool$ordersDelete: ToolDefinition = { + name: "orders_delete", + description: `Delete Order + +Delete a coffee order.`, + args, + tool: async (client, args, ctx) => { + const [result, apiCall] = await ordersDelete( + client, + args.request, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + return formatResult(void 0, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersGetById.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersGetById.ts new file mode 100644 index 0000000..5de2302 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersGetById.ts @@ -0,0 +1,37 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ordersGetById } from "../../funcs/ordersGetById.js"; +import * as operations from "../../models/operations/index.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +const args = { + request: operations.GetOrderRequest$inboundSchema, +}; + +export const tool$ordersGetById: ToolDefinition = { + name: "orders_get-by-id", + description: `Get Order + +Retrieve a specific coffee order by its ID.`, + args, + tool: async (client, args, ctx) => { + const [result, apiCall] = await ordersGetById( + client, + args.request, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + const value = result.value; + + return formatResult(value, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersList.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersList.ts new file mode 100644 index 0000000..e8b6748 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersList.ts @@ -0,0 +1,39 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ordersList } from "../../funcs/ordersList.js"; +import * as operations from "../../models/operations/index.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +const args = { + request: operations.GetOrdersRequest$inboundSchema, +}; + +export const tool$ordersList: ToolDefinition = { + name: "orders_list", + description: `Get Orders + +Retrieve all coffee orders. +If 'coffee_type' is provided, returns orders matching that coffee type. +`, + args, + tool: async (client, args, ctx) => { + const [result, apiCall] = await ordersList( + client, + args.request, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + const value = result.value; + + return formatResult(value, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersUpdate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersUpdate.ts new file mode 100644 index 0000000..b21d4ee --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/mcp-server/tools/ordersUpdate.ts @@ -0,0 +1,37 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ordersUpdate } from "../../funcs/ordersUpdate.js"; +import * as operations from "../../models/operations/index.js"; +import { formatResult, ToolDefinition } from "../tools.js"; + +const args = { + request: operations.UpdateOrderRequest$inboundSchema, +}; + +export const tool$ordersUpdate: ToolDefinition = { + name: "orders_update", + description: `Update Order + +Update an existing coffee order.`, + args, + tool: async (client, args, ctx) => { + const [result, apiCall] = await ordersUpdate( + client, + args.request, + { fetchOptions: { signal: ctx.signal } }, + ).$inspect(); + + if (!result.ok) { + return { + content: [{ type: "text", text: result.error.message }], + isError: true, + }; + } + + const value = result.value; + + return formatResult(value, apiCall); + }, +}; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/coffeeorder.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/coffeeorder.ts new file mode 100644 index 0000000..5c8eeaa --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/coffeeorder.ts @@ -0,0 +1,149 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { ClosedEnum } from "../../types/enums.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Size of the coffee order + */ +export const CoffeeOrderSize = { + Small: "Small", + Medium: "Medium", + Large: "Large", +} as const; +/** + * Size of the coffee order + */ +export type CoffeeOrderSize = ClosedEnum; + +/** + * Represents a coffee order in the system + */ +export type CoffeeOrder = { + /** + * Unique identifier for the order + */ + id: number; + /** + * Name of the customer placing the order + */ + customerName: string; + /** + * Type of coffee ordered (must match an existing coffee type) + */ + coffeeType: string; + /** + * Size of the coffee order + */ + size: CoffeeOrderSize; + /** + * Optional additions to the coffee order + */ + extras?: Array | null | undefined; + /** + * Total price of the order + */ + price: number; +}; + +/** @internal */ +export const CoffeeOrderSize$inboundSchema: z.ZodNativeEnum< + typeof CoffeeOrderSize +> = z.nativeEnum(CoffeeOrderSize); + +/** @internal */ +export const CoffeeOrderSize$outboundSchema: z.ZodNativeEnum< + typeof CoffeeOrderSize +> = CoffeeOrderSize$inboundSchema; + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace CoffeeOrderSize$ { + /** @deprecated use `CoffeeOrderSize$inboundSchema` instead. */ + export const inboundSchema = CoffeeOrderSize$inboundSchema; + /** @deprecated use `CoffeeOrderSize$outboundSchema` instead. */ + export const outboundSchema = CoffeeOrderSize$outboundSchema; +} + +/** @internal */ +export const CoffeeOrder$inboundSchema: z.ZodType< + CoffeeOrder, + z.ZodTypeDef, + unknown +> = z.object({ + id: z.number().int(), + customer_name: z.string(), + coffee_type: z.string(), + size: CoffeeOrderSize$inboundSchema, + extras: z.nullable(z.array(z.string())).optional(), + price: z.number(), +}).transform((v) => { + return remap$(v, { + "customer_name": "customerName", + "coffee_type": "coffeeType", + }); +}); + +/** @internal */ +export type CoffeeOrder$Outbound = { + id: number; + customer_name: string; + coffee_type: string; + size: string; + extras?: Array | null | undefined; + price: number; +}; + +/** @internal */ +export const CoffeeOrder$outboundSchema: z.ZodType< + CoffeeOrder$Outbound, + z.ZodTypeDef, + CoffeeOrder +> = z.object({ + id: z.number().int(), + customerName: z.string(), + coffeeType: z.string(), + size: CoffeeOrderSize$outboundSchema, + extras: z.nullable(z.array(z.string())).optional(), + price: z.number(), +}).transform((v) => { + return remap$(v, { + customerName: "customer_name", + coffeeType: "coffee_type", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace CoffeeOrder$ { + /** @deprecated use `CoffeeOrder$inboundSchema` instead. */ + export const inboundSchema = CoffeeOrder$inboundSchema; + /** @deprecated use `CoffeeOrder$outboundSchema` instead. */ + export const outboundSchema = CoffeeOrder$outboundSchema; + /** @deprecated use `CoffeeOrder$Outbound` instead. */ + export type Outbound = CoffeeOrder$Outbound; +} + +export function coffeeOrderToJSON(coffeeOrder: CoffeeOrder): string { + return JSON.stringify(CoffeeOrder$outboundSchema.parse(coffeeOrder)); +} + +export function coffeeOrderFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => CoffeeOrder$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'CoffeeOrder' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/coffeeorderupdate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/coffeeorderupdate.ts new file mode 100644 index 0000000..1170463 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/coffeeorderupdate.ts @@ -0,0 +1,140 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { ClosedEnum } from "../../types/enums.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export const CoffeeOrderUpdateSize = { + Small: "Small", + Medium: "Medium", + Large: "Large", +} as const; +export type CoffeeOrderUpdateSize = ClosedEnum; + +/** + * Model for updating an existing coffee order (all fields optional) + */ +export type CoffeeOrderUpdate = { + /** + * Updated customer name + */ + customerName?: string | null | undefined; + /** + * Updated coffee type (must match an existing coffee type) + */ + coffeeType?: string | null | undefined; + /** + * Updated size of the coffee order + */ + size?: CoffeeOrderUpdateSize | null | undefined; + /** + * Updated optional additions to the coffee order + */ + extras?: Array | null | undefined; + /** + * Updated total price of the order + */ + price?: number | null | undefined; +}; + +/** @internal */ +export const CoffeeOrderUpdateSize$inboundSchema: z.ZodNativeEnum< + typeof CoffeeOrderUpdateSize +> = z.nativeEnum(CoffeeOrderUpdateSize); + +/** @internal */ +export const CoffeeOrderUpdateSize$outboundSchema: z.ZodNativeEnum< + typeof CoffeeOrderUpdateSize +> = CoffeeOrderUpdateSize$inboundSchema; + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace CoffeeOrderUpdateSize$ { + /** @deprecated use `CoffeeOrderUpdateSize$inboundSchema` instead. */ + export const inboundSchema = CoffeeOrderUpdateSize$inboundSchema; + /** @deprecated use `CoffeeOrderUpdateSize$outboundSchema` instead. */ + export const outboundSchema = CoffeeOrderUpdateSize$outboundSchema; +} + +/** @internal */ +export const CoffeeOrderUpdate$inboundSchema: z.ZodType< + CoffeeOrderUpdate, + z.ZodTypeDef, + unknown +> = z.object({ + customer_name: z.nullable(z.string()).optional(), + coffee_type: z.nullable(z.string()).optional(), + size: z.nullable(CoffeeOrderUpdateSize$inboundSchema).optional(), + extras: z.nullable(z.array(z.string())).optional(), + price: z.nullable(z.number()).optional(), +}).transform((v) => { + return remap$(v, { + "customer_name": "customerName", + "coffee_type": "coffeeType", + }); +}); + +/** @internal */ +export type CoffeeOrderUpdate$Outbound = { + customer_name?: string | null | undefined; + coffee_type?: string | null | undefined; + size?: string | null | undefined; + extras?: Array | null | undefined; + price?: number | null | undefined; +}; + +/** @internal */ +export const CoffeeOrderUpdate$outboundSchema: z.ZodType< + CoffeeOrderUpdate$Outbound, + z.ZodTypeDef, + CoffeeOrderUpdate +> = z.object({ + customerName: z.nullable(z.string()).optional(), + coffeeType: z.nullable(z.string()).optional(), + size: z.nullable(CoffeeOrderUpdateSize$outboundSchema).optional(), + extras: z.nullable(z.array(z.string())).optional(), + price: z.nullable(z.number()).optional(), +}).transform((v) => { + return remap$(v, { + customerName: "customer_name", + coffeeType: "coffee_type", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace CoffeeOrderUpdate$ { + /** @deprecated use `CoffeeOrderUpdate$inboundSchema` instead. */ + export const inboundSchema = CoffeeOrderUpdate$inboundSchema; + /** @deprecated use `CoffeeOrderUpdate$outboundSchema` instead. */ + export const outboundSchema = CoffeeOrderUpdate$outboundSchema; + /** @deprecated use `CoffeeOrderUpdate$Outbound` instead. */ + export type Outbound = CoffeeOrderUpdate$Outbound; +} + +export function coffeeOrderUpdateToJSON( + coffeeOrderUpdate: CoffeeOrderUpdate, +): string { + return JSON.stringify( + CoffeeOrderUpdate$outboundSchema.parse(coffeeOrderUpdate), + ); +} + +export function coffeeOrderUpdateFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => CoffeeOrderUpdate$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'CoffeeOrderUpdate' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/coffeetype.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/coffeetype.ts new file mode 100644 index 0000000..c67a58c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/coffeetype.ts @@ -0,0 +1,98 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +/** + * Represents a type of coffee available in the system + */ +export type CoffeeType = { + /** + * Name of the coffee type + */ + name: string; + /** + * Detailed description of the coffee type + */ + description?: string | null | undefined; + /** + * Unique identifier for the coffee type + */ + id: number; + /** + * Price multiplier for this coffee type + */ + priceMultiplier?: number | null | undefined; +}; + +/** @internal */ +export const CoffeeType$inboundSchema: z.ZodType< + CoffeeType, + z.ZodTypeDef, + unknown +> = z.object({ + name: z.string(), + description: z.nullable(z.string()).optional(), + id: z.number().int(), + price_multiplier: z.nullable(z.number()).optional(), +}).transform((v) => { + return remap$(v, { + "price_multiplier": "priceMultiplier", + }); +}); + +/** @internal */ +export type CoffeeType$Outbound = { + name: string; + description?: string | null | undefined; + id: number; + price_multiplier?: number | null | undefined; +}; + +/** @internal */ +export const CoffeeType$outboundSchema: z.ZodType< + CoffeeType$Outbound, + z.ZodTypeDef, + CoffeeType +> = z.object({ + name: z.string(), + description: z.nullable(z.string()).optional(), + id: z.number().int(), + priceMultiplier: z.nullable(z.number()).optional(), +}).transform((v) => { + return remap$(v, { + priceMultiplier: "price_multiplier", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace CoffeeType$ { + /** @deprecated use `CoffeeType$inboundSchema` instead. */ + export const inboundSchema = CoffeeType$inboundSchema; + /** @deprecated use `CoffeeType$outboundSchema` instead. */ + export const outboundSchema = CoffeeType$outboundSchema; + /** @deprecated use `CoffeeType$Outbound` instead. */ + export type Outbound = CoffeeType$Outbound; +} + +export function coffeeTypeToJSON(coffeeType: CoffeeType): string { + return JSON.stringify(CoffeeType$outboundSchema.parse(coffeeType)); +} + +export function coffeeTypeFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => CoffeeType$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'CoffeeType' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/index.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/index.ts new file mode 100644 index 0000000..97b4fdf --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/index.ts @@ -0,0 +1,9 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export * from "./coffeeorder.js"; +export * from "./coffeeorderupdate.js"; +export * from "./coffeetype.js"; +export * from "./security.js"; +export * from "./validationerror.js"; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/security.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/security.ts new file mode 100644 index 0000000..f8ea2f2 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/security.ts @@ -0,0 +1,71 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type Security = { + apiKeyAuth?: string | undefined; +}; + +/** @internal */ +export const Security$inboundSchema: z.ZodType< + Security, + z.ZodTypeDef, + unknown +> = z.object({ + ApiKeyAuth: z.string().optional(), +}).transform((v) => { + return remap$(v, { + "ApiKeyAuth": "apiKeyAuth", + }); +}); + +/** @internal */ +export type Security$Outbound = { + ApiKeyAuth?: string | undefined; +}; + +/** @internal */ +export const Security$outboundSchema: z.ZodType< + Security$Outbound, + z.ZodTypeDef, + Security +> = z.object({ + apiKeyAuth: z.string().optional(), +}).transform((v) => { + return remap$(v, { + apiKeyAuth: "ApiKeyAuth", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace Security$ { + /** @deprecated use `Security$inboundSchema` instead. */ + export const inboundSchema = Security$inboundSchema; + /** @deprecated use `Security$outboundSchema` instead. */ + export const outboundSchema = Security$outboundSchema; + /** @deprecated use `Security$Outbound` instead. */ + export type Outbound = Security$Outbound; +} + +export function securityToJSON(security: Security): string { + return JSON.stringify(Security$outboundSchema.parse(security)); +} + +export function securityFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => Security$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'Security' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/validationerror.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/validationerror.ts new file mode 100644 index 0000000..7889376 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/components/validationerror.ts @@ -0,0 +1,125 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type Loc = string | number; + +/** + * Detailed information about a validation error + */ +export type ValidationError = { + /** + * Type of error + */ + type: string; + /** + * Location of the error in the request + */ + loc: Array; + /** + * Error message + */ + msg: string; +}; + +/** @internal */ +export const Loc$inboundSchema: z.ZodType = z.union( + [z.string(), z.number().int()], +); + +/** @internal */ +export type Loc$Outbound = string | number; + +/** @internal */ +export const Loc$outboundSchema: z.ZodType = z + .union([z.string(), z.number().int()]); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace Loc$ { + /** @deprecated use `Loc$inboundSchema` instead. */ + export const inboundSchema = Loc$inboundSchema; + /** @deprecated use `Loc$outboundSchema` instead. */ + export const outboundSchema = Loc$outboundSchema; + /** @deprecated use `Loc$Outbound` instead. */ + export type Outbound = Loc$Outbound; +} + +export function locToJSON(loc: Loc): string { + return JSON.stringify(Loc$outboundSchema.parse(loc)); +} + +export function locFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => Loc$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'Loc' from JSON`, + ); +} + +/** @internal */ +export const ValidationError$inboundSchema: z.ZodType< + ValidationError, + z.ZodTypeDef, + unknown +> = z.object({ + type: z.string(), + loc: z.array(z.union([z.string(), z.number().int()])), + msg: z.string(), +}); + +/** @internal */ +export type ValidationError$Outbound = { + type: string; + loc: Array; + msg: string; +}; + +/** @internal */ +export const ValidationError$outboundSchema: z.ZodType< + ValidationError$Outbound, + z.ZodTypeDef, + ValidationError +> = z.object({ + type: z.string(), + loc: z.array(z.union([z.string(), z.number().int()])), + msg: z.string(), +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace ValidationError$ { + /** @deprecated use `ValidationError$inboundSchema` instead. */ + export const inboundSchema = ValidationError$inboundSchema; + /** @deprecated use `ValidationError$outboundSchema` instead. */ + export const outboundSchema = ValidationError$outboundSchema; + /** @deprecated use `ValidationError$Outbound` instead. */ + export type Outbound = ValidationError$Outbound; +} + +export function validationErrorToJSON( + validationError: ValidationError, +): string { + return JSON.stringify(ValidationError$outboundSchema.parse(validationError)); +} + +export function validationErrorFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => ValidationError$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'ValidationError' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/apierror.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/apierror.ts new file mode 100644 index 0000000..3a04a1c --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/apierror.ts @@ -0,0 +1,27 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export class APIError extends Error { + public readonly statusCode: number; + public readonly contentType: string; + + constructor( + message: string, + public readonly rawResponse: Response, + public readonly body: string = "", + ) { + const statusCode = rawResponse.status; + const contentType = rawResponse.headers.get("content-type") || ""; + const bodyString = body.length > 0 ? `\n${body}` : ""; + + super( + `${message}: Status ${statusCode} Content-Type ${contentType} Body ${bodyString}`, + ); + + this.statusCode = statusCode; + this.contentType = contentType; + + this.name = "APIError"; + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/errorresponse.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/errorresponse.ts new file mode 100644 index 0000000..ea8877a --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/errorresponse.ts @@ -0,0 +1,81 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; + +/** + * Standard error response format + */ +export type ErrorResponseData = { + /** + * Error detail message + */ + detail: string; +}; + +/** + * Standard error response format + */ +export class ErrorResponse extends Error { + /** + * Error detail message + */ + detail: string; + + /** The original data that was passed to this error instance. */ + data$: ErrorResponseData; + + constructor(err: ErrorResponseData) { + const message = "message" in err && typeof err.message === "string" + ? err.message + : `API error occurred: ${JSON.stringify(err)}`; + super(message); + this.data$ = err; + + this.detail = err.detail; + + this.name = "ErrorResponse"; + } +} + +/** @internal */ +export const ErrorResponse$inboundSchema: z.ZodType< + ErrorResponse, + z.ZodTypeDef, + unknown +> = z.object({ + detail: z.string(), +}) + .transform((v) => { + return new ErrorResponse(v); + }); + +/** @internal */ +export type ErrorResponse$Outbound = { + detail: string; +}; + +/** @internal */ +export const ErrorResponse$outboundSchema: z.ZodType< + ErrorResponse$Outbound, + z.ZodTypeDef, + ErrorResponse +> = z.instanceof(ErrorResponse) + .transform(v => v.data$) + .pipe(z.object({ + detail: z.string(), + })); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace ErrorResponse$ { + /** @deprecated use `ErrorResponse$inboundSchema` instead. */ + export const inboundSchema = ErrorResponse$inboundSchema; + /** @deprecated use `ErrorResponse$outboundSchema` instead. */ + export const outboundSchema = ErrorResponse$outboundSchema; + /** @deprecated use `ErrorResponse$Outbound` instead. */ + export type Outbound = ErrorResponse$Outbound; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/httpclienterrors.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/httpclienterrors.ts new file mode 100644 index 0000000..b34f612 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/httpclienterrors.ts @@ -0,0 +1,62 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +/** + * Base class for all HTTP errors. + */ +export class HTTPClientError extends Error { + /** The underlying cause of the error. */ + override readonly cause: unknown; + override name = "HTTPClientError"; + constructor(message: string, opts?: { cause?: unknown }) { + let msg = message; + if (opts?.cause) { + msg += `: ${opts.cause}`; + } + + super(msg, opts); + // In older runtimes, the cause field would not have been assigned through + // the super() call. + if (typeof this.cause === "undefined") { + this.cause = opts?.cause; + } + } +} + +/** + * An error to capture unrecognised or unexpected errors when making HTTP calls. + */ +export class UnexpectedClientError extends HTTPClientError { + override name = "UnexpectedClientError"; +} + +/** + * An error that is raised when any inputs used to create a request are invalid. + */ +export class InvalidRequestError extends HTTPClientError { + override name = "InvalidRequestError"; +} + +/** + * An error that is raised when a HTTP request was aborted by the client error. + */ +export class RequestAbortedError extends HTTPClientError { + override readonly name = "RequestAbortedError"; +} + +/** + * An error that is raised when a HTTP request timed out due to an AbortSignal + * signal timeout. + */ +export class RequestTimeoutError extends HTTPClientError { + override readonly name = "RequestTimeoutError"; +} + +/** + * An error that is raised when a HTTP client is unable to make a request to + * a server. + */ +export class ConnectionError extends HTTPClientError { + override readonly name = "ConnectionError"; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/httpvalidationerror.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/httpvalidationerror.ts new file mode 100644 index 0000000..71e98a9 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/httpvalidationerror.ts @@ -0,0 +1,82 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import * as components from "../components/index.js"; + +/** + * Error thrown when request validation fails + */ +export type HTTPValidationErrorData = { + /** + * List of validation errors + */ + detail?: Array | undefined; +}; + +/** + * Error thrown when request validation fails + */ +export class HTTPValidationError extends Error { + /** + * List of validation errors + */ + detail?: Array | undefined; + + /** The original data that was passed to this error instance. */ + data$: HTTPValidationErrorData; + + constructor(err: HTTPValidationErrorData) { + const message = "message" in err && typeof err.message === "string" + ? err.message + : `API error occurred: ${JSON.stringify(err)}`; + super(message); + this.data$ = err; + + if (err.detail != null) this.detail = err.detail; + + this.name = "HTTPValidationError"; + } +} + +/** @internal */ +export const HTTPValidationError$inboundSchema: z.ZodType< + HTTPValidationError, + z.ZodTypeDef, + unknown +> = z.object({ + detail: z.array(components.ValidationError$inboundSchema).optional(), +}) + .transform((v) => { + return new HTTPValidationError(v); + }); + +/** @internal */ +export type HTTPValidationError$Outbound = { + detail?: Array | undefined; +}; + +/** @internal */ +export const HTTPValidationError$outboundSchema: z.ZodType< + HTTPValidationError$Outbound, + z.ZodTypeDef, + HTTPValidationError +> = z.instanceof(HTTPValidationError) + .transform(v => v.data$) + .pipe(z.object({ + detail: z.array(components.ValidationError$outboundSchema).optional(), + })); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace HTTPValidationError$ { + /** @deprecated use `HTTPValidationError$inboundSchema` instead. */ + export const inboundSchema = HTTPValidationError$inboundSchema; + /** @deprecated use `HTTPValidationError$outboundSchema` instead. */ + export const outboundSchema = HTTPValidationError$outboundSchema; + /** @deprecated use `HTTPValidationError$Outbound` instead. */ + export type Outbound = HTTPValidationError$Outbound; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/index.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/index.ts new file mode 100644 index 0000000..3a696ed --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/index.ts @@ -0,0 +1,9 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export * from "./apierror.js"; +export * from "./errorresponse.js"; +export * from "./httpclienterrors.js"; +export * from "./httpvalidationerror.js"; +export * from "./sdkvalidationerror.js"; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/sdkvalidationerror.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/sdkvalidationerror.ts new file mode 100644 index 0000000..16929b9 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/errors/sdkvalidationerror.ts @@ -0,0 +1,97 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; + +export class SDKValidationError extends Error { + /** + * The raw value that failed validation. + */ + public readonly rawValue: unknown; + + /** + * The raw message that failed validation. + */ + public readonly rawMessage: unknown; + + constructor(message: string, cause: unknown, rawValue: unknown) { + super(`${message}: ${cause}`); + this.name = "SDKValidationError"; + this.cause = cause; + this.rawValue = rawValue; + this.rawMessage = message; + } + + /** + * Return a pretty-formatted error message if the underlying validation error + * is a ZodError or some other recognized error type, otherwise return the + * default error message. + */ + public pretty(): string { + if (this.cause instanceof z.ZodError) { + return `${this.rawMessage}\n${formatZodError(this.cause)}`; + } else { + return this.toString(); + } + } +} + +export function formatZodError(err: z.ZodError, level = 0): string { + let pre = " ".repeat(level); + pre = level > 0 ? `│${pre}` : pre; + pre += " ".repeat(level); + + let message = ""; + const append = (str: string) => (message += `\n${pre}${str}`); + + const len = err.issues.length; + const headline = len === 1 ? `${len} issue found` : `${len} issues found`; + + if (len) { + append(`┌ ${headline}:`); + } + + for (const issue of err.issues) { + let path = issue.path.join("."); + path = path ? `.${path}` : ""; + append(`│ • [${path}]: ${issue.message} (${issue.code})`); + switch (issue.code) { + case "invalid_literal": + case "invalid_type": { + append(`│ Want: ${issue.expected}`); + append(`│ Got: ${issue.received}`); + break; + } + case "unrecognized_keys": { + append(`│ Keys: ${issue.keys.join(", ")}`); + break; + } + case "invalid_enum_value": { + append(`│ Allowed: ${issue.options.join(", ")}`); + append(`│ Got: ${issue.received}`); + break; + } + case "invalid_union_discriminator": { + append(`│ Allowed: ${issue.options.join(", ")}`); + break; + } + case "invalid_union": { + const len = issue.unionErrors.length; + append( + `│ ✖︎ Attemped to deserialize into one of ${len} union members:`, + ); + issue.unionErrors.forEach((err, i) => { + append(`│ ✖︎ Member ${i + 1} of ${len}`); + append(`${formatZodError(err, level + 1)}`); + }); + } + } + } + + if (err.issues.length) { + append(`└─*`); + } + + return message.slice(1); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/deletecoffeetype.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/deletecoffeetype.ts new file mode 100644 index 0000000..a46e558 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/deletecoffeetype.ts @@ -0,0 +1,78 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type DeleteCoffeeTypeRequest = { + /** + * The ID of the coffee type to operate on + */ + typeId: number; +}; + +/** @internal */ +export const DeleteCoffeeTypeRequest$inboundSchema: z.ZodType< + DeleteCoffeeTypeRequest, + z.ZodTypeDef, + unknown +> = z.object({ + type_id: z.number().int(), +}).transform((v) => { + return remap$(v, { + "type_id": "typeId", + }); +}); + +/** @internal */ +export type DeleteCoffeeTypeRequest$Outbound = { + type_id: number; +}; + +/** @internal */ +export const DeleteCoffeeTypeRequest$outboundSchema: z.ZodType< + DeleteCoffeeTypeRequest$Outbound, + z.ZodTypeDef, + DeleteCoffeeTypeRequest +> = z.object({ + typeId: z.number().int(), +}).transform((v) => { + return remap$(v, { + typeId: "type_id", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace DeleteCoffeeTypeRequest$ { + /** @deprecated use `DeleteCoffeeTypeRequest$inboundSchema` instead. */ + export const inboundSchema = DeleteCoffeeTypeRequest$inboundSchema; + /** @deprecated use `DeleteCoffeeTypeRequest$outboundSchema` instead. */ + export const outboundSchema = DeleteCoffeeTypeRequest$outboundSchema; + /** @deprecated use `DeleteCoffeeTypeRequest$Outbound` instead. */ + export type Outbound = DeleteCoffeeTypeRequest$Outbound; +} + +export function deleteCoffeeTypeRequestToJSON( + deleteCoffeeTypeRequest: DeleteCoffeeTypeRequest, +): string { + return JSON.stringify( + DeleteCoffeeTypeRequest$outboundSchema.parse(deleteCoffeeTypeRequest), + ); +} + +export function deleteCoffeeTypeRequestFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => DeleteCoffeeTypeRequest$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'DeleteCoffeeTypeRequest' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/deleteorder.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/deleteorder.ts new file mode 100644 index 0000000..974d914 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/deleteorder.ts @@ -0,0 +1,78 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type DeleteOrderRequest = { + /** + * The ID of the order to operate on + */ + orderId: number; +}; + +/** @internal */ +export const DeleteOrderRequest$inboundSchema: z.ZodType< + DeleteOrderRequest, + z.ZodTypeDef, + unknown +> = z.object({ + order_id: z.number().int(), +}).transform((v) => { + return remap$(v, { + "order_id": "orderId", + }); +}); + +/** @internal */ +export type DeleteOrderRequest$Outbound = { + order_id: number; +}; + +/** @internal */ +export const DeleteOrderRequest$outboundSchema: z.ZodType< + DeleteOrderRequest$Outbound, + z.ZodTypeDef, + DeleteOrderRequest +> = z.object({ + orderId: z.number().int(), +}).transform((v) => { + return remap$(v, { + orderId: "order_id", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace DeleteOrderRequest$ { + /** @deprecated use `DeleteOrderRequest$inboundSchema` instead. */ + export const inboundSchema = DeleteOrderRequest$inboundSchema; + /** @deprecated use `DeleteOrderRequest$outboundSchema` instead. */ + export const outboundSchema = DeleteOrderRequest$outboundSchema; + /** @deprecated use `DeleteOrderRequest$Outbound` instead. */ + export type Outbound = DeleteOrderRequest$Outbound; +} + +export function deleteOrderRequestToJSON( + deleteOrderRequest: DeleteOrderRequest, +): string { + return JSON.stringify( + DeleteOrderRequest$outboundSchema.parse(deleteOrderRequest), + ); +} + +export function deleteOrderRequestFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => DeleteOrderRequest$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'DeleteOrderRequest' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/getcoffeetype.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/getcoffeetype.ts new file mode 100644 index 0000000..fa80aa4 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/getcoffeetype.ts @@ -0,0 +1,78 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type GetCoffeeTypeRequest = { + /** + * The ID of the coffee type to operate on + */ + typeId: number; +}; + +/** @internal */ +export const GetCoffeeTypeRequest$inboundSchema: z.ZodType< + GetCoffeeTypeRequest, + z.ZodTypeDef, + unknown +> = z.object({ + type_id: z.number().int(), +}).transform((v) => { + return remap$(v, { + "type_id": "typeId", + }); +}); + +/** @internal */ +export type GetCoffeeTypeRequest$Outbound = { + type_id: number; +}; + +/** @internal */ +export const GetCoffeeTypeRequest$outboundSchema: z.ZodType< + GetCoffeeTypeRequest$Outbound, + z.ZodTypeDef, + GetCoffeeTypeRequest +> = z.object({ + typeId: z.number().int(), +}).transform((v) => { + return remap$(v, { + typeId: "type_id", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace GetCoffeeTypeRequest$ { + /** @deprecated use `GetCoffeeTypeRequest$inboundSchema` instead. */ + export const inboundSchema = GetCoffeeTypeRequest$inboundSchema; + /** @deprecated use `GetCoffeeTypeRequest$outboundSchema` instead. */ + export const outboundSchema = GetCoffeeTypeRequest$outboundSchema; + /** @deprecated use `GetCoffeeTypeRequest$Outbound` instead. */ + export type Outbound = GetCoffeeTypeRequest$Outbound; +} + +export function getCoffeeTypeRequestToJSON( + getCoffeeTypeRequest: GetCoffeeTypeRequest, +): string { + return JSON.stringify( + GetCoffeeTypeRequest$outboundSchema.parse(getCoffeeTypeRequest), + ); +} + +export function getCoffeeTypeRequestFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => GetCoffeeTypeRequest$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'GetCoffeeTypeRequest' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/getorder.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/getorder.ts new file mode 100644 index 0000000..258d633 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/getorder.ts @@ -0,0 +1,76 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type GetOrderRequest = { + /** + * The ID of the order to operate on + */ + orderId: number; +}; + +/** @internal */ +export const GetOrderRequest$inboundSchema: z.ZodType< + GetOrderRequest, + z.ZodTypeDef, + unknown +> = z.object({ + order_id: z.number().int(), +}).transform((v) => { + return remap$(v, { + "order_id": "orderId", + }); +}); + +/** @internal */ +export type GetOrderRequest$Outbound = { + order_id: number; +}; + +/** @internal */ +export const GetOrderRequest$outboundSchema: z.ZodType< + GetOrderRequest$Outbound, + z.ZodTypeDef, + GetOrderRequest +> = z.object({ + orderId: z.number().int(), +}).transform((v) => { + return remap$(v, { + orderId: "order_id", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace GetOrderRequest$ { + /** @deprecated use `GetOrderRequest$inboundSchema` instead. */ + export const inboundSchema = GetOrderRequest$inboundSchema; + /** @deprecated use `GetOrderRequest$outboundSchema` instead. */ + export const outboundSchema = GetOrderRequest$outboundSchema; + /** @deprecated use `GetOrderRequest$Outbound` instead. */ + export type Outbound = GetOrderRequest$Outbound; +} + +export function getOrderRequestToJSON( + getOrderRequest: GetOrderRequest, +): string { + return JSON.stringify(GetOrderRequest$outboundSchema.parse(getOrderRequest)); +} + +export function getOrderRequestFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => GetOrderRequest$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'GetOrderRequest' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/getorders.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/getorders.ts new file mode 100644 index 0000000..44fdd1f --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/getorders.ts @@ -0,0 +1,78 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type GetOrdersRequest = { + /** + * Optional filter by coffee type (case-insensitive) + */ + coffeeType?: string | null | undefined; +}; + +/** @internal */ +export const GetOrdersRequest$inboundSchema: z.ZodType< + GetOrdersRequest, + z.ZodTypeDef, + unknown +> = z.object({ + coffee_type: z.nullable(z.string()).optional(), +}).transform((v) => { + return remap$(v, { + "coffee_type": "coffeeType", + }); +}); + +/** @internal */ +export type GetOrdersRequest$Outbound = { + coffee_type?: string | null | undefined; +}; + +/** @internal */ +export const GetOrdersRequest$outboundSchema: z.ZodType< + GetOrdersRequest$Outbound, + z.ZodTypeDef, + GetOrdersRequest +> = z.object({ + coffeeType: z.nullable(z.string()).optional(), +}).transform((v) => { + return remap$(v, { + coffeeType: "coffee_type", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace GetOrdersRequest$ { + /** @deprecated use `GetOrdersRequest$inboundSchema` instead. */ + export const inboundSchema = GetOrdersRequest$inboundSchema; + /** @deprecated use `GetOrdersRequest$outboundSchema` instead. */ + export const outboundSchema = GetOrdersRequest$outboundSchema; + /** @deprecated use `GetOrdersRequest$Outbound` instead. */ + export type Outbound = GetOrdersRequest$Outbound; +} + +export function getOrdersRequestToJSON( + getOrdersRequest: GetOrdersRequest, +): string { + return JSON.stringify( + GetOrdersRequest$outboundSchema.parse(getOrdersRequest), + ); +} + +export function getOrdersRequestFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => GetOrdersRequest$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'GetOrdersRequest' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/index.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/index.ts new file mode 100644 index 0000000..0d1f551 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/index.ts @@ -0,0 +1,11 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export * from "./deletecoffeetype.js"; +export * from "./deleteorder.js"; +export * from "./getcoffeetype.js"; +export * from "./getorder.js"; +export * from "./getorders.js"; +export * from "./updatecoffeetype.js"; +export * from "./updateorder.js"; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/updatecoffeetype.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/updatecoffeetype.ts new file mode 100644 index 0000000..5d03d07 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/updatecoffeetype.ts @@ -0,0 +1,85 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import * as components from "../components/index.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type UpdateCoffeeTypeRequest = { + /** + * The ID of the coffee type to operate on + */ + typeId: number; + coffeeType: components.CoffeeType; +}; + +/** @internal */ +export const UpdateCoffeeTypeRequest$inboundSchema: z.ZodType< + UpdateCoffeeTypeRequest, + z.ZodTypeDef, + unknown +> = z.object({ + type_id: z.number().int(), + CoffeeType: components.CoffeeType$inboundSchema, +}).transform((v) => { + return remap$(v, { + "type_id": "typeId", + "CoffeeType": "coffeeType", + }); +}); + +/** @internal */ +export type UpdateCoffeeTypeRequest$Outbound = { + type_id: number; + CoffeeType: components.CoffeeType$Outbound; +}; + +/** @internal */ +export const UpdateCoffeeTypeRequest$outboundSchema: z.ZodType< + UpdateCoffeeTypeRequest$Outbound, + z.ZodTypeDef, + UpdateCoffeeTypeRequest +> = z.object({ + typeId: z.number().int(), + coffeeType: components.CoffeeType$outboundSchema, +}).transform((v) => { + return remap$(v, { + typeId: "type_id", + coffeeType: "CoffeeType", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace UpdateCoffeeTypeRequest$ { + /** @deprecated use `UpdateCoffeeTypeRequest$inboundSchema` instead. */ + export const inboundSchema = UpdateCoffeeTypeRequest$inboundSchema; + /** @deprecated use `UpdateCoffeeTypeRequest$outboundSchema` instead. */ + export const outboundSchema = UpdateCoffeeTypeRequest$outboundSchema; + /** @deprecated use `UpdateCoffeeTypeRequest$Outbound` instead. */ + export type Outbound = UpdateCoffeeTypeRequest$Outbound; +} + +export function updateCoffeeTypeRequestToJSON( + updateCoffeeTypeRequest: UpdateCoffeeTypeRequest, +): string { + return JSON.stringify( + UpdateCoffeeTypeRequest$outboundSchema.parse(updateCoffeeTypeRequest), + ); +} + +export function updateCoffeeTypeRequestFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => UpdateCoffeeTypeRequest$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'UpdateCoffeeTypeRequest' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/updateorder.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/updateorder.ts new file mode 100644 index 0000000..3a0f1cd --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/models/operations/updateorder.ts @@ -0,0 +1,85 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; +import { remap as remap$ } from "../../lib/primitives.js"; +import { safeParse } from "../../lib/schemas.js"; +import { Result as SafeParseResult } from "../../types/fp.js"; +import * as components from "../components/index.js"; +import { SDKValidationError } from "../errors/sdkvalidationerror.js"; + +export type UpdateOrderRequest = { + /** + * The ID of the order to operate on + */ + orderId: number; + coffeeOrderUpdate: components.CoffeeOrderUpdate; +}; + +/** @internal */ +export const UpdateOrderRequest$inboundSchema: z.ZodType< + UpdateOrderRequest, + z.ZodTypeDef, + unknown +> = z.object({ + order_id: z.number().int(), + CoffeeOrderUpdate: components.CoffeeOrderUpdate$inboundSchema, +}).transform((v) => { + return remap$(v, { + "order_id": "orderId", + "CoffeeOrderUpdate": "coffeeOrderUpdate", + }); +}); + +/** @internal */ +export type UpdateOrderRequest$Outbound = { + order_id: number; + CoffeeOrderUpdate: components.CoffeeOrderUpdate$Outbound; +}; + +/** @internal */ +export const UpdateOrderRequest$outboundSchema: z.ZodType< + UpdateOrderRequest$Outbound, + z.ZodTypeDef, + UpdateOrderRequest +> = z.object({ + orderId: z.number().int(), + coffeeOrderUpdate: components.CoffeeOrderUpdate$outboundSchema, +}).transform((v) => { + return remap$(v, { + orderId: "order_id", + coffeeOrderUpdate: "CoffeeOrderUpdate", + }); +}); + +/** + * @internal + * @deprecated This namespace will be removed in future versions. Use schemas and types that are exported directly from this module. + */ +export namespace UpdateOrderRequest$ { + /** @deprecated use `UpdateOrderRequest$inboundSchema` instead. */ + export const inboundSchema = UpdateOrderRequest$inboundSchema; + /** @deprecated use `UpdateOrderRequest$outboundSchema` instead. */ + export const outboundSchema = UpdateOrderRequest$outboundSchema; + /** @deprecated use `UpdateOrderRequest$Outbound` instead. */ + export type Outbound = UpdateOrderRequest$Outbound; +} + +export function updateOrderRequestToJSON( + updateOrderRequest: UpdateOrderRequest, +): string { + return JSON.stringify( + UpdateOrderRequest$outboundSchema.parse(updateOrderRequest), + ); +} + +export function updateOrderRequestFromJSON( + jsonString: string, +): SafeParseResult { + return safeParse( + jsonString, + (x) => UpdateOrderRequest$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'UpdateOrderRequest' from JSON`, + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/coffeetypes.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/coffeetypes.ts new file mode 100644 index 0000000..9719b0b --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/coffeetypes.ts @@ -0,0 +1,98 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { coffeeTypesCreate } from "../funcs/coffeeTypesCreate.js"; +import { coffeeTypesDelete } from "../funcs/coffeeTypesDelete.js"; +import { coffeeTypesGetById } from "../funcs/coffeeTypesGetById.js"; +import { coffeeTypesList } from "../funcs/coffeeTypesList.js"; +import { coffeeTypesUpdate } from "../funcs/coffeeTypesUpdate.js"; +import { ClientSDK, RequestOptions } from "../lib/sdks.js"; +import * as components from "../models/components/index.js"; +import * as operations from "../models/operations/index.js"; +import { unwrapAsync } from "../types/fp.js"; + +export class CoffeeTypes extends ClientSDK { + /** + * Get Coffee Types + * + * @remarks + * Retrieve all available coffee types. + */ + async list( + options?: RequestOptions, + ): Promise> { + return unwrapAsync(coffeeTypesList( + this, + options, + )); + } + + /** + * Create Coffee Type + * + * @remarks + * Create a new coffee type. + */ + async create( + request: components.CoffeeType, + options?: RequestOptions, + ): Promise { + return unwrapAsync(coffeeTypesCreate( + this, + request, + options, + )); + } + + /** + * Get Coffee Type + * + * @remarks + * Retrieve a specific coffee type by its ID. + */ + async getById( + request: operations.GetCoffeeTypeRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(coffeeTypesGetById( + this, + request, + options, + )); + } + + /** + * Update Coffee Type + * + * @remarks + * Update an existing coffee type. + */ + async update( + request: operations.UpdateCoffeeTypeRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(coffeeTypesUpdate( + this, + request, + options, + )); + } + + /** + * Delete Coffee Type + * + * @remarks + * Delete a coffee type. + */ + async delete( + request: operations.DeleteCoffeeTypeRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(coffeeTypesDelete( + this, + request, + options, + )); + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/index.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/index.ts new file mode 100644 index 0000000..ecac226 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/index.ts @@ -0,0 +1,5 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export * from "./sdk.js"; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/orders.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/orders.ts new file mode 100644 index 0000000..43451a6 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/orders.ts @@ -0,0 +1,102 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ordersCreate } from "../funcs/ordersCreate.js"; +import { ordersDelete } from "../funcs/ordersDelete.js"; +import { ordersGetById } from "../funcs/ordersGetById.js"; +import { ordersList } from "../funcs/ordersList.js"; +import { ordersUpdate } from "../funcs/ordersUpdate.js"; +import { ClientSDK, RequestOptions } from "../lib/sdks.js"; +import * as components from "../models/components/index.js"; +import * as operations from "../models/operations/index.js"; +import { unwrapAsync } from "../types/fp.js"; + +export class Orders extends ClientSDK { + /** + * Get Orders + * + * @remarks + * Retrieve all coffee orders. + * If 'coffee_type' is provided, returns orders matching that coffee type. + */ + async list( + request: operations.GetOrdersRequest, + options?: RequestOptions, + ): Promise> { + return unwrapAsync(ordersList( + this, + request, + options, + )); + } + + /** + * Create Order + * + * @remarks + * Create a new coffee order. + * Validates that the coffee type exists. + */ + async create( + request: components.CoffeeOrder, + options?: RequestOptions, + ): Promise { + return unwrapAsync(ordersCreate( + this, + request, + options, + )); + } + + /** + * Get Order + * + * @remarks + * Retrieve a specific coffee order by its ID. + */ + async getById( + request: operations.GetOrderRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(ordersGetById( + this, + request, + options, + )); + } + + /** + * Update Order + * + * @remarks + * Update an existing coffee order. + */ + async update( + request: operations.UpdateOrderRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(ordersUpdate( + this, + request, + options, + )); + } + + /** + * Delete Order + * + * @remarks + * Delete a coffee order. + */ + async delete( + request: operations.DeleteOrderRequest, + options?: RequestOptions, + ): Promise { + return unwrapAsync(ordersDelete( + this, + request, + options, + )); + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/sdk.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/sdk.ts new file mode 100644 index 0000000..3a89d6d --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/sdk/sdk.ts @@ -0,0 +1,19 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { ClientSDK } from "../lib/sdks.js"; +import { CoffeeTypes } from "./coffeetypes.js"; +import { Orders } from "./orders.js"; + +export class SpeakeasyCoffeeClient extends ClientSDK { + private _orders?: Orders; + get orders(): Orders { + return (this._orders ??= new Orders(this._options)); + } + + private _coffeeTypes?: CoffeeTypes; + get coffeeTypes(): CoffeeTypes { + return (this._coffeeTypes ??= new CoffeeTypes(this._options)); + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/async.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/async.ts new file mode 100644 index 0000000..689dba5 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/async.ts @@ -0,0 +1,68 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export type APICall = + | { + status: "complete"; + request: Request; + response: Response; + } + | { + status: "request-error"; + request: Request; + response?: undefined; + } + | { + status: "invalid"; + request?: undefined; + response?: undefined; + }; + +export class APIPromise implements Promise { + readonly #promise: Promise<[T, APICall]>; + readonly #unwrapped: Promise; + + readonly [Symbol.toStringTag] = "APIPromise"; + + constructor(p: [T, APICall] | Promise<[T, APICall]>) { + this.#promise = p instanceof Promise ? p : Promise.resolve(p); + this.#unwrapped = + p instanceof Promise + ? this.#promise.then(([value]) => value) + : Promise.resolve(p[0]); + } + + then( + onfulfilled?: + | ((value: T) => TResult1 | PromiseLike) + | null + | undefined, + onrejected?: + | ((reason: any) => TResult2 | PromiseLike) + | null + | undefined, + ): Promise { + return this.#promise.then( + onfulfilled ? ([value]) => onfulfilled(value) : void 0, + onrejected, + ); + } + + catch( + onrejected?: + | ((reason: any) => TResult | PromiseLike) + | null + | undefined, + ): Promise { + return this.#unwrapped.catch(onrejected); + } + + finally(onfinally?: (() => void) | null | undefined): Promise { + return this.#unwrapped.finally(onfinally); + } + + $inspect(): Promise<[T, APICall]> { + return this.#promise; + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/blobs.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/blobs.ts new file mode 100644 index 0000000..4ce8460 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/blobs.ts @@ -0,0 +1,31 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; + +export const blobLikeSchema: z.ZodType = + z.custom(isBlobLike, { + message: "expected a Blob, File or Blob-like object", + fatal: true, + }); + +export function isBlobLike(val: unknown): val is Blob { + if (val instanceof Blob) { + return true; + } + + if (typeof val !== "object" || val == null || !(Symbol.toStringTag in val)) { + return false; + } + + const name = val[Symbol.toStringTag]; + if (typeof name !== "string") { + return false; + } + if (name !== "Blob" && name !== "File") { + return false; + } + + return "stream" in val && typeof val.stream === "function"; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/constdatetime.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/constdatetime.ts new file mode 100644 index 0000000..c0a4409 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/constdatetime.ts @@ -0,0 +1,15 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import * as z from "zod"; + +export function constDateTime( + val: string, +): z.ZodType { + return z.custom((v) => { + return ( + typeof v === "string" && new Date(v).getTime() === new Date(val).getTime() + ); + }, `Value must be equivelant to ${val}`); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/enums.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/enums.ts new file mode 100644 index 0000000..6fb6d91 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/enums.ts @@ -0,0 +1,16 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +declare const __brand: unique symbol; +export type Unrecognized = T & { [__brand]: "unrecognized" }; + +export function catchUnrecognizedEnum(value: T): Unrecognized { + return value as Unrecognized; +} + +type Prettify = { [K in keyof T]: T[K] } & {}; +export type ClosedEnum = T[keyof T]; +export type OpenEnum = + | Prettify + | Unrecognized; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/fp.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/fp.ts new file mode 100644 index 0000000..ccbe51e --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/fp.ts @@ -0,0 +1,50 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +/** + * A monad that captures the result of a function call or an error if it was not + * successful. Railway programming, enabled by this type, can be a nicer + * alternative to traditional exception throwing because it allows functions to + * declare all _known_ errors with static types and then check for them + * exhaustively in application code. Thrown exception have a type of `unknown` + * and break out of regular control flow of programs making them harder to + * inspect and more verbose work with due to try-catch blocks. + */ +export type Result = + | { ok: true; value: T; error?: never } + | { ok: false; value?: never; error: E }; + +export function OK(value: V): Result { + return { ok: true, value }; +} + +export function ERR(error: E): Result { + return { ok: false, error }; +} + +/** + * unwrap is a convenience function for extracting a value from a result or + * throwing if there was an error. + */ +export function unwrap(r: Result): T { + if (!r.ok) { + throw r.error; + } + return r.value; +} + +/** + * unwrapAsync is a convenience function for resolving a value from a Promise + * of a result or rejecting if an error occurred. + */ +export async function unwrapAsync( + pr: Promise>, +): Promise { + const r = await pr; + if (!r.ok) { + throw r.error; + } + + return r.value; +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/index.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/index.ts new file mode 100644 index 0000000..e124e81 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/index.ts @@ -0,0 +1,11 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export { blobLikeSchema, isBlobLike } from "./blobs.js"; +export { catchUnrecognizedEnum } from "./enums.js"; +export type { ClosedEnum, OpenEnum, Unrecognized } from "./enums.js"; +export type { Result } from "./fp.js"; +export type { PageIterator, Paginator } from "./operations.js"; +export { createPageIterator } from "./operations.js"; +export { RFCDate } from "./rfcdate.js"; diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/operations.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/operations.ts new file mode 100644 index 0000000..beb81e1 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/operations.ts @@ -0,0 +1,105 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { Result } from "./fp.js"; + +export type Paginator = () => Promise }> | null; + +export type PageIterator = V & { + next: Paginator; + [Symbol.asyncIterator]: () => AsyncIterableIterator; + "~next"?: PageState | undefined; +}; + +export function createPageIterator( + page: V & { next: Paginator }, + halt: (v: V) => boolean, +): { + [Symbol.asyncIterator]: () => AsyncIterableIterator; +} { + return { + [Symbol.asyncIterator]: async function* paginator() { + yield page; + if (halt(page)) { + return; + } + + let p: typeof page | null = page; + for (p = await p.next(); p != null; p = await p.next()) { + yield p; + if (halt(p)) { + return; + } + } + }, + }; +} + +/** + * This utility create a special iterator that yields a single value and + * terminates. It is useful in paginated SDK functions that have early return + * paths when things go wrong. + */ +export function haltIterator( + v: V, +): PageIterator { + return { + ...v, + next: () => null, + [Symbol.asyncIterator]: async function* paginator() { + yield v; + }, + }; +} + +/** + * Converts an async iterator of `Result` into an async iterator of `V`. + * When error results occur, the underlying error value is thrown. + */ +export async function unwrapResultIterator( + iteratorPromise: Promise, PageState>>, +): Promise> { + const resultIter = await iteratorPromise; + + if (!resultIter.ok) { + throw resultIter.error; + } + + return { + ...resultIter.value, + next: unwrapPaginator(resultIter.next), + "~next": resultIter["~next"], + [Symbol.asyncIterator]: async function* paginator() { + for await (const page of resultIter) { + if (!page.ok) { + throw page.error; + } + yield page.value; + } + }, + }; +} + +function unwrapPaginator( + paginator: Paginator>, +): Paginator { + return () => { + const nextResult = paginator(); + if (nextResult == null) { + return null; + } + return nextResult.then((res) => { + if (!res.ok) { + throw res.error; + } + const out = { + ...res.value, + next: unwrapPaginator(res.next), + }; + return out; + }); + }; +} + +export const URL_OVERRIDE = Symbol("URL_OVERRIDE"); diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/rfcdate.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/rfcdate.ts new file mode 100644 index 0000000..c79b3f5 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/rfcdate.ts @@ -0,0 +1,54 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +const dateRE = /^\d{4}-\d{2}-\d{2}$/; + +export class RFCDate { + private serialized: string; + + /** + * Creates a new RFCDate instance using today's date. + */ + static today(): RFCDate { + return new RFCDate(new Date()); + } + + /** + * Creates a new RFCDate instance using the provided input. + * If a string is used then in must be in the format YYYY-MM-DD. + * + * @param date A Date object or a date string in YYYY-MM-DD format + * @example + * new RFCDate("2022-01-01") + * @example + * new RFCDate(new Date()) + */ + constructor(date: Date | string) { + if (typeof date === "string" && !dateRE.test(date)) { + throw new RangeError( + "RFCDate: date strings must be in the format YYYY-MM-DD: " + date, + ); + } + + const value = new Date(date); + if (isNaN(+value)) { + throw new RangeError("RFCDate: invalid date provided: " + date); + } + + this.serialized = value.toISOString().slice(0, "YYYY-MM-DD".length); + if (!dateRE.test(this.serialized)) { + throw new TypeError( + `RFCDate: failed to build valid date with given value: ${date} serialized to ${this.serialized}`, + ); + } + } + + toJSON(): string { + return this.toString(); + } + + toString(): string { + return this.serialized; + } +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/streams.ts b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/streams.ts new file mode 100644 index 0000000..a0163e7 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/src/types/streams.ts @@ -0,0 +1,21 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +export function isReadableStream( + val: unknown, +): val is ReadableStream { + if (typeof val !== "object" || val === null) { + return false; + } + + // Check for the presence of methods specific to ReadableStream + const stream = val as ReadableStream; + + // ReadableStream has methods like getReader, cancel, and tee + return ( + typeof stream.getReader === "function" && + typeof stream.cancel === "function" && + typeof stream.tee === "function" + ); +} diff --git a/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/tsconfig.json b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/tsconfig.json new file mode 100644 index 0000000..94d81a3 --- /dev/null +++ b/oss-migration-guide/sdks/speakeasy-coffee-client-typescript/tsconfig.json @@ -0,0 +1,41 @@ +{ + "compilerOptions": { + "incremental": true, + "tsBuildInfoFile": ".tsbuildinfo", + "target": "ES2020", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "jsx": "react-jsx", + + "module": "Node16", + "moduleResolution": "Node16", + + "allowJs": true, + + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": ".", + + + // https://github.com/tsconfig/bases/blob/a1bf7c0fa2e094b068ca3e1448ca2ece4157977e/bases/strictest.json + "strict": true, + "allowUnusedLabels": false, + "allowUnreachableCode": false, + "exactOptionalPropertyTypes": true, + "useUnknownInCatchVariables": true, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "isolatedModules": true, + "checkJs": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src"], + "exclude": ["node_modules"] +}