diff --git a/.github/workflows/DeploySpecDocs.yml b/.github/workflows/DeploySpecDocs.yml index 20db2c4..7a4d752 100644 --- a/.github/workflows/DeploySpecDocs.yml +++ b/.github/workflows/DeploySpecDocs.yml @@ -49,7 +49,7 @@ jobs: run: | DIST_FILE="swagger-ui/dist/swagger-initializer.js" # Remove the 'url:' property and insert the 'urls:' array - sed -i '/url: /c\ urls: [\n {\n "url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/Data-Gateway.json",\n "name": "Data Gateway"\n },\n {\n "url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/SHIELD.json",\n "name": "SHIELD"\n }\n ],' "$DIST_FILE" + sed -i '/url: /c\ urls: [\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/Data-Gateway.json",\n"name": "Data Gateway"\n},\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/SHIELD.json",\n"name": "SHIELD"\n}\n{\n"url": "https://raw.githubusercontent.com/Software-Hardware-Integration-Lab/OpenAPI/refs/heads/main/specs/Url-Shortener.json",\n"name": "Data Gateway"\n}\n],' "$DIST_FILE" # Uploads the built artifact to github pages - name: Upload Artifact diff --git a/OpenAPI.code-workspace b/OpenAPI.code-workspace index 872042a..b525ac8 100644 --- a/OpenAPI.code-workspace +++ b/OpenAPI.code-workspace @@ -12,6 +12,10 @@ "name": "SHIELD", "path": "src/shield" }, + { + "name": "URL Shortener", + "path": "src/urlShortener" + }, { "name": "GitHub Actions", "path": ".github/workflows" diff --git a/specs/Url-Shortener.json b/specs/Url-Shortener.json new file mode 100644 index 0000000..3b046f5 --- /dev/null +++ b/specs/Url-Shortener.json @@ -0,0 +1,1519 @@ +{ + "components": { + "parameters": { + "id": { + "description": "Object ID that uniquely identifies the record.", + "in": "path", + "name": "id", + "required": true, + "schema": { + "examples": [ + "b2fd105a-2594-437e-b934-1a62a51c28b4" + ], + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + } + } + }, + "responses": { + "204": { + "description": "Request is successful!" + }, + "400": { + "description": "Invalid input!" + }, + "404": { + "description": "The requested object was not found." + }, + "500": { + "description": "Internal Server Error" + } + }, + "schemas": { + "Core.HealthReport": { + "title": "Core System - Health Report", + "description": "Health report that indicates if a service is down or not that the URL Shortener relies on.", + "examples": [ + { + "authClient": true, + "authServer": true, + "database": false + } + ], + "properties": { + "authClient": { + "description": "Flag that indicates if the client side authentication validation is working or not.", + "type": "boolean" + }, + "authServer": { + "description": "Flag that indicates if the server side authentication is working or not.", + "type": "boolean" + }, + "database": { + "description": "Flag that indicates if the ORM (Database) system is down (`false`) or not (`true`). False indicate the service is not working, true indicates the service is working.", + "type": "boolean" + } + }, + "type": "object", + "required": [ + "authClient", + "authServer", + "database" + ] + }, + "Redirect.UrlConfiguration": { + "title": "Redirect - Configuration Record", + "description": "Object representing table entity with all available metadata.", + "examples": [ + { + "id": "7e2b1c8a-4f3d-4e2a-9b1a-2c6e8d7f1a23", + "sourceUrl": "https://www.example.com/vanityUrl", + "createdBy": "3c5a9b7e-2d4f-4c1b-8e6a-7f2b3d1c9e45", + "customUserAgentMatcher": null, + "domainConfigId": "9a1e7b2c-5d3f-4a8b-9c2e-6f1a3d7e8b54", + "updatedBy": "3c5a9b7e-2d4f-4c1b-8e6a-7f2b3d1c9e45", + "targetUrl": "https://www.example.com/very-long-and-complex-url-with_plenty-of-special-characters-and-non-repeated-words", + "targetUrlCustom": null, + "targetUrlMobile": null, + "targetUrlNodeJs": null, + "targetUrlPowershell": null, + "targetUrlPython": null, + "type": "temporary" + } + ], + "properties": { + "id": { + "description": "Object ID that uniquely identifies this record and can be used as a reference in any other table.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$", + "readOnly": true + }, + "sourceUrl": { + "description": "The codified version of the full URL that a user would be navigating to. It has to be unique in the table as it will be used during lookup.", + "type": "string", + "format": "uri" + }, + "createdBy": { + "description": "Object ID of the user who initially creates this record.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$", + "readOnly": true + }, + "customUserAgentMatcher": { + "description": "Custom user agent matcher to be used with the custom target url. Custom target url is non-operable if this is not set. String max char count is 512.", + "type": [ + "string", + "null" + ], + "maxLength": 512 + }, + "domainConfigId": { + "description": "Object ID of the domain configuration that this redirect record is associated with.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$", + "readOnly": true + }, + "updatedBy": { + "description": "Object ID of the last user who updated this record.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "targetUrl": { + "description": "Destination that the client will be redirected to if the source is matched. This is the default URL that will be used when no user agent is matched.", + "type": "string", + "format": "uri" + }, + "targetUrlCustom": { + "description": "Target URL for custom defined and matching user agent clients.", + "type": [ + "string", + "null" + ], + "format": "uri" + }, + "targetUrlMobile": { + "description": "Target URL for various mobile operating systems.", + "type": [ + "string", + "null" + ], + "format": "uri" + }, + "targetUrlNodeJs": { + "description": "Target URL for Node.JS clients.", + "type": [ + "string", + "null" + ], + "format": "uri" + }, + "targetUrlPowershell": { + "description": "Target URL for PowerShell clients.", + "type": [ + "string", + "null" + ], + "format": "uri" + }, + "targetUrlPython": { + "description": "Target URL for Python clients.", + "type": [ + "string", + "null" + ], + "format": "uri" + }, + "type": { + "description": "Type of the redirect. Used to calculate the status code to be sent to the caller.", + "type": "string", + "enum": [ + "temporary", + "permanent" + ] + } + }, + "type": "object", + "required": [ + "id", + "sourceUrl", + "createdBy", + "customUserAgentMatcher", + "domainConfigId", + "updatedBy", + "targetUrl", + "targetUrlCustom", + "targetUrlMobile", + "targetUrlNodeJs", + "targetUrlPowershell", + "targetUrlPython", + "type" + ] + }, + "Redirect.BannedTerm": { + "title": "Redirect - Banned Term Record", + "description": "Object representing a banned term that cannot be used in the vanity URLs.", + "examples": [ + { + "id": "d4f5e6a7-b8c9-4d0e-9f1a-2b3c4d5e6f70", + "name": "admin", + "type": "rootSegment" + } + ], + "properties": { + "id": { + "description": "Unique value that identifies this record and will be used as a reference in any other table.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$", + "readOnly": true + }, + "name": { + "description": "Term or component that is banned in any of the vanity URLs that users can create.", + "type": "string" + }, + "type": { + "description": "Specifies how the name ban operates: `rootSegment` operates matches like `https://example.com//*`, `global` operates matches like `https://example.com/**`.", + "type": "string", + "enum": [ + "rootSegment", + "global" + ] + } + }, + "type": "object", + "required": [ + "id", + "name", + "type" + ] + }, + "Redirect.DomainName": { + "title": "Redirect - Domain Name Record", + "description": "Object representing a domain name entry that will serve as a base for vanity URLs.", + "examples": [ + { + "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", + "allowHttp": false, + "count": 1, + "hidden": false, + "hostName": "example.com", + "type": "vanity" + } + ], + "properties": { + "id": { + "description": "Unique value that identifies this record and will be used as a reference in any other table.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$", + "readOnly": true + }, + "allowHttp": { + "description": "Flag that indicates if the domain accepts unencrypted traffic (`true`) or not (`false`).", + "type": "boolean" + }, + "count": { + "description": "Current increment for the id number if the domain is in ID number mode. Always incremented even if not in ID mode so as to be able to swap to ID mode if requested with no risk for collision.", + "type": "integer", + "format": "int32", + "minimum": 0, + "readOnly": true + }, + "hidden": { + "description": "Flag that indicates if the domain name is hidden from the user interface. The domain will always be visible on the domain name admin config page. This flag is useful for hiding names that are behind load balancers from end users to reduce confusion. Can also be used to `enable` or `disable` end user interaction in the UI with the specified names.", + "type": "boolean" + }, + "hostName": { + "description": "String to be used in matching the host name. Subdomains need to have their own record to be usable.", + "type": "string", + "format": "hostname" + }, + "type": { + "description": "Flag that indicates the type of shortened URL that can be generated on the domain: `vanity` allows any user structure as long as it is unique. Example: `https://example.com/myUrl`, `idNumber` locks out user control of the vanity URL and hard codes it to an ID number. Example: `https://example.com/managedLink?id=123`.", + "type": "string", + "enum": [ + "vanity", + "idNumber" + ] + } + }, + "type": "object", + "required": [ + "id", + "allowHttp", + "count", + "hidden", + "hostName", + "type" + ] + }, + "Redirect.RbacAssignment": { + "title": "Redirect - RBAC Assignment Record", + "description": "Object representing an RBAC assignment entry to control user's AuthZ abilities when dealing with redirects/domains/banned terms records.", + "examples": [ + { + "id": "2e1c4b7a-8d3f-4e2b-9a1c-7f5d2b3e6a9c", + "assignmentTargetType": "RedirectConfig", + "createdAt": "2025-08-20T12:00:00Z", + "targetId": "5a7e2c1b-3d4f-4a8b-9e6a-2c1b7f3d8e4a", + "principalId": "9b2e7a1c-4d3f-5a8b-2c6e-1a7f3d9e8b5c", + "principalType": "user", + "role": "b8e2c7a1-4d3f-4a9b-8e6a-2c1b7f3d8e4a" + } + ], + "properties": { + "id": { + "description": "Unique value that identifies this record and will be used as a reference in any other table.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$", + "readOnly": true + }, + "assignmentTargetType": { + "description": "Type of object that this RBAC assignment is for.", + "type": "string", + "enum": [ + "RedirectConfig", + "DomainName", + "BannedName" + ] + }, + "createdAt": { + "description": "Time stamp of when the assignment was created.", + "type": "string", + "format": "date-time", + "readOnly": true + }, + "targetId": { + "description": "Unique ID of the system that this assignment describes.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "principalId": { + "description": "Object ID of the principal that this assignment targets.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "principalType": { + "description": "Flag used to optimize principal processing.", + "type": "string", + "enum": [ + "user", + "group" + ] + }, + "role": { + "description": "Role ID of the role that is assigned by this assignment.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + } + }, + "type": "object", + "required": [ + "id", + "assignmentTargetType", + "createdAt", + "targetId", + "principalId", + "principalType", + "role" + ] + } + }, + "securitySchemes": { + "EntraID": { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + "description": "The Access Token from Entra ID for the `URL Shortener` Enterprise App (may need to be created from the App Registration)." + } + } + }, + "externalDocs": { + "description": "Official Documentation", + "url": "https://docs.shilab.com" + }, + "info": { + "contact": { + "email": "elliot_huffman@shi.com", + "name": "SHI - Lab" + }, + "description": "Create vanity or numeric short version of your desired URL. Share it digitally, as QR code, or print it.", + "title": "SHI URL Shortener", + "version": "0.0.1" + }, + "openapi": "3.1.1", + "paths": { + "/Api/Auth/Id": { + "get": { + "description": "Provides the Tenant ID and the Application ID of the service principal that access tokens need to be issued against. This is also useful for configuring public clients to be able to authenticate to for auth code flows.", + "operationId": "/Api/Auth/Id/Get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "properties": { + "appId": { + "description": "Application ID that should be used in Access Tokens as the audience and the endpoint necessary for auth code flows.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$", + "readOnly": true + }, + "tenantId": { + "description": "Tenant ID necessary for authority host URL configuration and UI customization.", + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$", + "readOnly": true + } + }, + "type": "object", + "required": [ + "appId", + "tenantId" + ] + } + } + }, + "description": "OK" + }, + "500": { + "$ref": "#/components/responses/500" + } + }, + "tags": [ + "Core" + ], + "security": [], + "summary": "Retrieves the IDs required to authenticate." + } + }, + "/Api/Core/Health": { + "get": { + "summary": "Health of the Service for Probing", + "description": "Check the health of the various components of the URL Shortener and report back. Useful for automated health probing.", + "operationId": "/Api/Core/Health/Get", + "responses": { + "204": { + "description": "Service is operational!" + }, + "500": { + "description": "Service has a failure described with following report.", + "content": { + "application/json": { + "examples": { + "All services operational": { + "description": "Health check report shows all services as available and working.", + "value": { + "authClient": true, + "authServer": true, + "database": true + } + }, + "Database service down": { + "description": "Health check report shows that the database service is down.", + "value": { + "authClient": true, + "authServer": true, + "database": false + } + } + }, + "schema": { + "$ref": "#/components/schemas/Core.HealthReport" + } + } + } + } + }, + "tags": [ + "Core" + ], + "security": [] + } + }, + "/Api/Redirect": { + "get": { + "summary": "Retrieves All Redirect Configuration Records", + "description": "Retrieves all redirect records matching the requested filters, if any.\n\nThis endpoint requires that the principal has an RBAC assignment to view the associated records or have the role `Everything.ReadWrite.All`, or `Redirect.ReadWrite.All` assigned in Entra to view all regardless of RBAC.", + "operationId": "/Api/Redirect/Get", + "parameters": [ + { + "name": "sourceUrl", + "in": "query", + "description": "Filter by the `sourceUrl` field.", + "schema": { + "type": "string", + "format": "uri" + } + }, + { + "name": "createdBy", + "in": "query", + "description": "Filter by the `createdBy` field.", + "schema": { + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + } + }, + { + "name": "customUserAgentMatcher", + "in": "query", + "description": "Filter by the `customUserAgentMatcher` field.", + "schema": { + "type": "string", + "maxLength": 512 + } + }, + { + "name": "domainConfigId", + "in": "query", + "description": "Filter by the `domainConfigId` field.", + "schema": { + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + } + }, + { + "name": "updatedBy", + "in": "query", + "description": "Filter by the `updatedBy` field.", + "schema": { + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + } + }, + { + "name": "targetUrl", + "in": "query", + "description": "Filter by the `targetUrl` field.", + "schema": { + "type": "string", + "format": "uri" + } + }, + { + "name": "targetUrlCustom", + "in": "query", + "description": "Filter by the `targetUrlCustom` field.", + "schema": { + "type": "string", + "format": "uri" + } + }, + { + "name": "targetUrlMobile", + "in": "query", + "description": "Filter by the `targetUrlMobile` field.", + "schema": { + "type": "string", + "format": "uri" + } + }, + { + "name": "targetUrlNodeJs", + "in": "query", + "description": "Filter by the `targetUrlNodeJs` field.", + "schema": { + "type": "string", + "format": "uri" + } + }, + { + "name": "targetUrlPowershell", + "in": "query", + "description": "Filter by the `targetUrlPowershell` field.", + "schema": { + "type": "string", + "format": "uri" + } + }, + { + "name": "targetUrlPython", + "in": "query", + "description": "Filter by the `targetUrlPython` field.", + "schema": { + "type": "string", + "format": "uri" + } + }, + { + "name": "type", + "in": "query", + "description": "Filter by the `type` field.", + "schema": { + "type": "string", + "enum": [ + "temporary", + "permanent" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Redirect.UrlConfiguration" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "URL Redirect" + ] + }, + "post": { + "summary": "Creates New Redirect Configuration Record", + "description": "Creates new URL redirect record in the database and returns information enriched with created metadata.\n\nThis endpoint does not have scope (permission) restrictions. Creating principal is set as RBAC owner of the newly created URL.", + "operationId": "/Api/Redirect/Post", + "requestBody": { + "required": true, + "content": { + "application/json": { + "examples": { + "Missing a required field": { + "description": "Payload is missing one or more of the required fields.", + "value": { + "sourceUrl": "https://www.example.com/long-and-complex-url", + "createdBy": "3c5a9b7e-2d4f-4c1b-8e6a-7f2b3d1c9e45", + "customUserAgentMatcher": null, + "domainConfigId": "9a1e7b2c-5d3f-4a8b-9c2e-6f1a3d7e8b54", + "updatedBy": "3c5a9b7e-2d4f-4c1b-8e6a-7f2b3d1c9e45" + } + }, + "Complete and proper payload": { + "description": "Request where all required fields are present and valid.", + "value": { + "sourceUrl": "https://www.example.com/long-and-complex-url", + "createdBy": "3c5a9b7e-2d4f-4c1b-8e6a-7f2b3d1c9e45", + "customUserAgentMatcher": null, + "domainConfigId": "9a1e7b2c-5d3f-4a8b-9c2e-6f1a3d7e8b54", + "updatedBy": "3c5a9b7e-2d4f-4c1b-8e6a-7f2b3d1c9e45", + "targetUrl": "https://www.example.com/target", + "targetUrlCustom": null, + "targetUrlMobile": null, + "targetUrlNodeJs": null, + "targetUrlPowershell": null, + "targetUrlPython": null, + "type": "temporary" + } + } + }, + "schema": { + "$ref": "#/components/schemas/Redirect.UrlConfiguration" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.UrlConfiguration" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + } + }, + "tags": [ + "URL Redirect" + ] + } + }, + "/Api/Redirect/Check": { + "post": { + "summary": "Checks if Target Name is Available", + "description": "Validates if provided target name is available to be requested. Returns boolean `true` if the name is available, `false` if the name is already recorded.\n\nThis endpoint does not have scope (permission) restrictions.", + "operationId": "/Api/Redirect/Check/Post", + "requestBody": { + "required": true, + "content": { + "application/json": { + "examples": { + "Required field is missing": { + "description": "Payload is missing the required 'sourceName' field.", + "value": {} + }, + "Complete and accurate request": { + "description": "Payload includes all required and valid entries.", + "value": { + "sourceName": "my-vanity-url" + } + } + }, + "schema": { + "type": "object", + "properties": { + "sourceName": { + "description": "URL to check if is taken or not.", + "type": "string" + } + }, + "required": [ + "sourceName" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + } + }, + "tags": [ + "URL Redirect" + ] + } + }, + "/Api/Redirect/{id}": { + "get": { + "summary": "Retrieves Specific Redirect Configuration Record", + "description": "Retrieves all information from the database of the redirect record.\n\nTo view the specific record, the principal has to be a part of an RBAC assignment or one of the following Entra roles: `Everything.ReadWrite.All`, or `Redirect.ReadWrite.All`.", + "operationId": "/Api/Redirect/:id/Get", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.UrlConfiguration" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "URL Redirect" + ] + }, + "patch": { + "summary": "Updates Specific Redirect Configuration Record", + "description": "Updates one or more properties of the redirect record based on which fields are provided.\n\nThis endpoint requires either of the following RBAC assignments: `Owner` or `Contributor` on the specific record, or have the role `Everything.ReadWrite.All`, or `Redirect.ReadWrite.All` assigned in Entra to update regardless of RBAC.", + "operationId": "/Api/Redirect/:id/Patch", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "Sample request to update record": { + "description": "Payload contains one or more fields that need update in the database.", + "value": { + "targetUrl": "https://www.example.com/target-updated", + "targetUrlNodeJs": "https://www.example.com/target-nodejs", + "type": "permanent" + } + } + }, + "schema": { + "$ref": "#/components/schemas/Redirect.UrlConfiguration" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.UrlConfiguration" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "URL Redirect" + ] + }, + "delete": { + "summary": "Removes Specific Redirect Configuration Record", + "description": "Deletes the redirect record from the database.\n\nThis endpoint requires an RBAC assignment of `Owner` or `Contributor` on the specific record, or the `Everything.ReadWrite.All`, or `Redirect.ReadWrite.All` scope (permission) regardless of permissions.", + "operationId": "/Api/Redirect/:id/Delete", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "responses": { + "204": { + "$ref": "#/components/responses/204" + }, + "400": { + "$ref": "#/components/responses/400" + } + }, + "tags": [ + "URL Redirect" + ] + } + }, + "/Api/BannedName": { + "get": { + "summary": "Retrieves All Banned Name Records", + "description": "Retrieves all records of the banned terms that are not allowed to be used as targets.\n\nThis endpoint does not have implicit scope (permission) restrictions but includes an internal check on user's RBAC assignments to be able to view bans.", + "operationId": "/Api/BannedName/Get", + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Filter by the `name` field.", + "schema": { + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "description": "Filter by the `type` field.", + "schema": { + "type": "string", + "enum": [ + "rootSegment", + "global" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Redirect.BannedTerm" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "Banned Name" + ] + }, + "post": { + "summary": "Creates New Banned Name Record", + "description": "Create new record of the banned term.\n\nThis endpoint requires the `BanList.ReadWrite.All` or `Everything.ReadWrite.All` scope (permission).", + "operationId": "/Api/BannedName/Post", + "requestBody": { + "required": true, + "content": { + "application/json": { + "examples": { + "Missing a required field": { + "description": "Payload is missing one or more of the required fields.", + "value": { + "name": "admin" + } + }, + "Complete and proper payload": { + "description": "Request where all required fields are present and valid.", + "value": { + "name": "admin", + "type": "rootSegment" + } + } + }, + "schema": { + "$ref": "#/components/schemas/Redirect.BannedTerm" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.BannedTerm" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + } + }, + "tags": [ + "Banned Name" + ] + } + }, + "/Api/BannedName/{id}": { + "get": { + "summary": "Retrieves Specific Banned Name Record", + "description": "Retrieves all information from the database of the banned name record.\n\nThis endpoint does not have implicit scope (permission) restrictions but includes an internal check on user's RBAC assignments to view the specific ban.", + "operationId": "/Api/BannedName/:id/Get", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.BannedTerm" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "Banned Name" + ] + }, + "delete": { + "summary": "Removes Specific Banned Name Record", + "description": "Deletes the banned name record from the database.\n\nThis endpoint requires an RBAC assignment and the `BanList.ReadWrite.All` or `Everything.ReadWrite.All` scope (permission).", + "operationId": "/Api/BannedName/:id/Delete", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "responses": { + "204": { + "$ref": "#/components/responses/204" + }, + "400": { + "$ref": "#/components/responses/400" + } + }, + "tags": [ + "Banned Name" + ] + } + }, + "/Api/Domain": { + "get": { + "summary": "Retrieves All Domain Name Records", + "description": "Retrieves all domain name records from the database.\n\nThis endpoint does not have implicit scope (permission) restrictions but includes an internal check on user's RBAC assignments.", + "operationId": "/Api/Domain/Get", + "parameters": [ + { + "name": "allowHttp", + "in": "query", + "description": "Filter by the `allowHttp` field.", + "schema": { + "type": "boolean" + } + }, + { + "name": "count", + "in": "query", + "description": "Filter by the `count` field.", + "schema": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + }, + { + "name": "hidden", + "in": "query", + "description": "Filter by the `hidden` field.", + "schema": { + "type": "boolean" + } + }, + { + "name": "hostName", + "in": "query", + "description": "Filter by the `hostName` field.", + "schema": { + "type": "string" + } + }, + { + "name": "type", + "in": "query", + "description": "Filter by the `type` field.", + "schema": { + "type": "string", + "enum": [ + "vanity", + "idNumber" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Redirect.DomainName" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "Domain Configuration" + ] + }, + "post": { + "summary": "Creates New Domain Name Record", + "description": "Creates new domain name record in the database and returns information enriched with created metadata.\n\nThis endpoint requires the `Domain.ReadWrite.All` or `Everything.ReadWrite.All` scope (permission).", + "operationId": "/Api/Domain/Post", + "requestBody": { + "required": true, + "content": { + "application/json": { + "examples": { + "Missing a required field": { + "description": "Payload is missing one or more of the required fields.", + "value": { + "allowHttp": true, + "hostName": "example.com" + } + }, + "Complete and proper payload": { + "description": "Request where all required fields are present and valid.", + "value": { + "allowHttp": false, + "count": 1, + "hidden": false, + "hostName": "example.com", + "type": "vanity" + } + } + }, + "schema": { + "$ref": "#/components/schemas/Redirect.DomainName" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.DomainName" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + } + }, + "tags": [ + "Domain Configuration" + ] + } + }, + "/Api/Domain/{id}": { + "get": { + "summary": "Retrieves Specific Domain Name Record", + "description": "Retrieves all information from the database of the domain name record.\n\nThis endpoint does not have implicit scope (permission) restrictions but includes an internal check on user's RBAC assignments.", + "operationId": "/Api/Domain/:id/Get", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.DomainName" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "Domain Configuration" + ] + }, + "patch": { + "summary": "Updates Specific Domain Name Record", + "description": "Updates one or more properties of the domain name record based on which fields are provided.\n\nThis endpoint requires the `Domain.ReadWrite.All` or `Everything.ReadWrite.All` scope (permission).", + "operationId": "/Api/Domain/:id/Patch", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "requestBody": { + "content": { + "application/json": { + "examples": { + "Sample request to update record": { + "description": "Payload contains one or more fields that need update in the database.", + "value": { + "allowHttp": false, + "type": "idNumber" + } + } + }, + "schema": { + "$ref": "#/components/schemas/Redirect.DomainName" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.DomainName" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "Domain Configuration" + ] + }, + "delete": { + "summary": "Removes Specific Domain Name Record", + "description": "Deletes the domain name record from the database.\n\nThis endpoint requires the `Domain.ReadWrite.All` or `Everything.ReadWrite.All` scope (permission).", + "operationId": "/Api/Domain/:id/Delete", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "responses": { + "204": { + "$ref": "#/components/responses/204" + }, + "400": { + "$ref": "#/components/responses/400" + } + }, + "tags": [ + "Domain Configuration" + ] + } + }, + "/Api/Rbac": { + "get": { + "summary": "Retrieves All RBAC Assignment Records", + "description": "Retrieves all RBAC assignment records from the database.\n\nThis endpoint does not have implicit scope (permission) restrictions but includes an internal check on user's RBAC assignments.", + "operationId": "/Api/Rbac/Get", + "parameters": [ + { + "name": "assignmentTargetType", + "in": "query", + "description": "Filter by the `assignmentTargetType` field.", + "schema": { + "type": "string", + "enum": [ + "RedirectConfig", + "DomainName", + "BannedName" + ] + } + }, + { + "name": "createdAt", + "in": "query", + "description": "Filter by the `createdAt` field.", + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "targetId", + "in": "query", + "description": "Filter by the `targetId` field.", + "schema": { + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + } + }, + { + "name": "principalId", + "in": "query", + "description": "Filter by the `principalId` field.", + "schema": { + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + } + }, + { + "name": "principalType", + "in": "query", + "description": "Filter by the `principalType` field.", + "schema": { + "type": "string", + "enum": [ + "user", + "group" + ] + } + }, + { + "name": "role", + "in": "query", + "description": "Filter by the `role` field.", + "schema": { + "type": "string", + "format": "uuid", + "maxLength": 36, + "minLength": 36, + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Redirect.RbacAssignment" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "RBAC Assignment" + ] + }, + "post": { + "summary": "Creates New RBAC Assignment Record", + "description": "Create new RBAC assignment record in the database and returns information enriched with created metadata.\n\nThis endpoint does not have implicit scope (permission) restrictions but includes an internal check on user's RBAC assignments.", + "operationId": "/Api/Rbac/Post", + "requestBody": { + "required": true, + "content": { + "application/json": { + "examples": { + "Missing a required field": { + "description": "Payload is missing one or more of the required fields.", + "value": { + "targetId": "6f2a1b7e-3d4c-4a8b-9e6a-2c1b7f3d8e4a", + "principalId": "1a7e2b3c-5d4f-4c8b-9a6e-7f2b3d1c9e45", + "principalType": "user" + } + }, + "Complete and proper payload": { + "description": "Request where all required fields are present and valid.", + "value": { + "assignmentTargetType": "RedirectConfig", + "targetId": "8b2e7a1c-4d3f-5a8b-0c6e-1a7f3d9e8b5c", + "principalId": "c7e1a2b3-4d5f-4a8b-9e6a-2c1b7f3d8e4a", + "principalType": "user", + "role": "9e1c7b2a-5d3f-4a8b-9c2e-6f1a3d7e8b54" + } + } + }, + "schema": { + "$ref": "#/components/schemas/Redirect.RbacAssignment" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.RbacAssignment" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + } + }, + "tags": [ + "RBAC Assignment" + ] + } + }, + "/Api/Rbac/{id}": { + "get": { + "summary": "Retrieves Specific RBAC Assignment Record", + "description": "Retrieves all information from the database of the RBAC assignment record.\n\nThis endpoint does not have scope (permission) restrictions.", + "operationId": "/Api/Rbac/:id/Get", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Redirect.RbacAssignment" + } + } + } + }, + "400": { + "$ref": "#/components/responses/400" + }, + "404": { + "$ref": "#/components/responses/404" + } + }, + "tags": [ + "RBAC Assignment" + ] + }, + "delete": { + "summary": "Removes Specific RBAC Assignment Record", + "description": "Deletes the RBAC assignment record from the database.\n\nThis endpoint does not have implicit scope (permission) restrictions but includes an internal check on user's RBAC assignments.", + "operationId": "/Api/Rbac/:id/Delete", + "parameters": [ + { + "$ref": "#/components/parameters/id" + } + ], + "responses": { + "204": { + "$ref": "#/components/responses/204" + }, + "400": { + "$ref": "#/components/responses/400" + } + }, + "tags": [ + "RBAC Assignment" + ] + } + } + }, + "security": [ + { + "EntraID": [] + } + ], + "servers": [ + { + "description": "The service", + "url": "/" + } + ], + "tags": [ + { + "description": "Configures the specified web server to support and process the authentication API routes.", + "name": "Core" + }, + { + "description": "Handles the redirection of short URLs to their target destinations, including support for different types of redirects and tracking.", + "name": "URL Redirect" + }, + { + "description": "Manages the list of terms that are prohibited from being used as targets in short URLs to prevent misuse or inappropriate content.", + "name": "Banned Name" + }, + { + "description": "Manages domain names used for generating short URLs, including support for vanity domains and domain-specific settings.", + "name": "Domain Configuration" + }, + { + "description": "Manages role-based access control (RBAC) assignments, allowing for fine-grained permissions and access management for users and groups within the URL shortening service.", + "name": "RBAC Assignment" + } + ] +} diff --git a/src/urlShortener/TypeScript/.npmignore b/src/urlShortener/TypeScript/.npmignore new file mode 100644 index 0000000..51eb220 --- /dev/null +++ b/src/urlShortener/TypeScript/.npmignore @@ -0,0 +1,9 @@ +# Ignore TypeScript source files while allowing library type descriptions +*.ts +!*.d.ts + +# Ignore the TypeScript config +tsconfig.json + +# Ignore the generated SDK source code +/sdk/ diff --git a/src/urlShortener/TypeScript/LICENSE b/src/urlShortener/TypeScript/LICENSE new file mode 100644 index 0000000..918c40e --- /dev/null +++ b/src/urlShortener/TypeScript/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 SHI International Corp. + +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. diff --git a/src/urlShortener/TypeScript/README.md b/src/urlShortener/TypeScript/README.md new file mode 100644 index 0000000..0d7e1b2 --- /dev/null +++ b/src/urlShortener/TypeScript/README.md @@ -0,0 +1,109 @@ +# URL Shortener - TypeScript SDK + +This SDK provides a convenient TypeScript client for interacting with the SHI URL Shortener service. It is automatically generated from the OpenAPI specification located at [`Url-Shortener.json`](https://github.com/Software-Hardware-Integration-Lab/OpenAPI/blob/main/specs/Url-Shortener.json) using [Kiota](https://github.com/microsoft/kiota). + +All typing data is included in the package. + +## Installation + +Install the SDK using npm: + +```bash +npm install @shi-corp/sdk-url-shortener +``` + +## Usage + +Here's a basic example of how to use the SDK: + +```TypeScript +import { DefaultAzureCredential } from '@azure/identity' +import { urlShortenerClientFactory } from '@shi-corp/sdk-url-shortener'; + +/** Authentication session used to authenticate to URL Shortener. */ +const credential = new DefaultAzureCredential(); + +/** Base URL for your URL Shortener instance. Protocol specifier (`http`/`https`) is required, even for localhost. */ +const baseUrl = new URL('https://url-shortener.example.com'); + +/** + * Configured client for URL Shortener that can make authenticated web requests against backend. + * + * The third param, the scope is the `Application ID` of the `End User Login` app registration. + */ +const urlShortenerClient = urlShortenerClientFactory(credential, baseUrl, ['b9689d4e-0036-4f2f-8430-07adedb9ae7c/.default']); + +/** List of available redirect entries. */ +const results = await urlShortenerClient.api.redirect.get(); + +// Check if list is not empty +if (results?.length > 0) { + // Do something +} +``` + +### Advanced Usage + +You can optionally configure the SDK client with a custom base URL, including support for it being nested deep in a L7 load balancer: + +```TypeScript +/** Custom host and endpoint base to as an example for something behind a layer 7 load balancer, E.g. Azure App Gateway or Azure API Gateway. If in debug mode, run against localhost. */ +const customBaseUrl = debugMode ? new URL('http://localhost:3004') : new URL('https://custom-host.example.com/Ballance/Instance1/'); + +/** Configured instance of the URL Shortener client. */ +const customConfiguredClient = urlShortenerClientFactory(credential, customBaseUrl); +``` + +and/or scope (permission) list: + +```TypeScript +/** + * `.default` and explicit permissions can't exist in the same custom scope list at the same time, Entra ID doesn't support this. + * + * If not providing the `.default` scope, you can have any number of scopes (permissions) listed in different array indexes. + */ +const customScopes = ['your-custom-scope/something.read.all', 'your-custom-scope/everything.readwrite.all']; + +// Initialize the SDK client with custom configuration. +const customConfiguredClient = urlShortenerClientFactory(credential, void 0, customScopes); +``` + +## Project Structure + +- `bin/`: Compiled JavaScript files and type definitions. +- `sdk/`: Source TypeScript files generated by Kiota. + - `api/`: API endpoint definitions. + - `models/`: Data models used by the SDK. + +## Development + +### Prerequisites + +- [Node.js](https://nodejs.org/) - Latest LTS version +- [Kiota](https://github.com/microsoft/kiota) + +### Generating the SDK + +To regenerate the SDK from the OpenAPI specification, run: + +```bash +npm run-script generate:Sdk +``` + +### Building the SDK + +To build the SDK for production, run: + +```bash +npm run-script build:Prod +``` + +## License + +This SDK is licensed under the [MIT License](./LICENSE). + +## Support + +For issues or feature requests, please visit the [GitHub Issues page](https://github.com/Software-Hardware-Integration-Lab/OpenAPI/issues). + +For more information, visit the [official documentation](https://docs.shilab.com). diff --git a/src/urlShortener/TypeScript/index.ts b/src/urlShortener/TypeScript/index.ts new file mode 100644 index 0000000..c331326 --- /dev/null +++ b/src/urlShortener/TypeScript/index.ts @@ -0,0 +1,40 @@ +import { assert, assertGuardEquals } from 'typia'; +import { AzureIdentityAuthenticationProvider } from "@microsoft/kiota-authentication-azure"; +import { FetchRequestAdapter } from "@microsoft/kiota-http-fetchlibrary"; +import type { TokenCredential } from "@azure/core-auth"; +import { createUrlShortenerClient } from "./sdk/urlShortenerClient.js"; + +// Export all of the SDK's types +export type * from './sdk/models/index.js'; + +/** + * Function that initializes the URL Shortener SDK. + * @param credential Configured authentication session from Entra ID. + * @param baseUrl Root of the URL that should have endpoints appended to it by the query building system. + * @param scopeList Where each array item is a different Entra ID standard scope to request on token retrieval. E.g. `['313f3894-325a-4aae-ba2b-bbdfdc1f063b/.default']` + * @returns Configured API client that is able to make requests against the specified URL Shortener instance. + */ +export function urlShortenerClientFactory(credential: TokenCredential, baseUrl: URL, scopeList: string[]) { + // #region Input Validation + assert(credential); + + assertGuardEquals(baseUrl); + + assertGuardEquals(scopeList); + // #endregion Input Validation + + /** List of hosts that are allowed when making API calls, this is used to prevent token leaks to threat actors. */ + const allowedHostList = new Set([baseUrl.host]); + + /** Authentication system that will be used to configure the SDK client. */ + const authProvider = new AzureIdentityAuthenticationProvider(credential, scopeList, void 0, allowedHostList); + + /** Instance of the URL Shortener SDK client initialization configuration. */ + const urlShortenerAdapter = new FetchRequestAdapter(authProvider); + + // Set the base URL to be what is provided, since the host name is unique every deployment + urlShortenerAdapter.baseUrl = baseUrl.href.endsWith('/') ? baseUrl.href.substring(0, baseUrl.href.length - 1) : baseUrl.href; + + /** Instance of the API client that can be used for URL Shortener access. */ + return createUrlShortenerClient(urlShortenerAdapter); +} diff --git a/src/urlShortener/TypeScript/package-lock.json b/src/urlShortener/TypeScript/package-lock.json new file mode 100644 index 0000000..1d70d4a --- /dev/null +++ b/src/urlShortener/TypeScript/package-lock.json @@ -0,0 +1,1210 @@ +{ + "name": "@shi-corp/sdk-url-shortener", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@shi-corp/sdk-url-shortener", + "version": "0.0.1", + "license": "MIT", + "dependencies": { + "@microsoft/kiota-authentication-azure": "~1.0.0-preview.97", + "@microsoft/kiota-bundle": "~1.0.0-preview.97", + "typia": "~9.7.1" + }, + "devDependencies": { + "@azure/core-auth": "~1.10.0", + "@types/node": "~24.3.0", + "ts-patch": "~3.3.0", + "typescript": "~5.9.2" + } + }, + "node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.0.tgz", + "integrity": "sha512-88Djs5vBvGbHQHf5ZZcaoNHo6Y8BKZkt3cw2iuJIQzLEgH4Ox6Tm4hjFhbqOxyYsgIG/eJbFEHpxRIfEEWv5Ow==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-util": "^1.11.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.0.tgz", + "integrity": "sha512-o0psW8QWQ58fq3i24Q1K2XfS/jYTxr7O1HRcyUE9bV9NttLU+kYOH82Ixj8DGlMTOWgxm1Sss2QAfKK5UkSPxw==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.1.tgz", + "integrity": "sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==", + "license": "MIT", + "dependencies": { + "chardet": "^2.1.0", + "iconv-lite": "^0.6.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@microsoft/kiota-abstractions": { + "version": "1.0.0-preview.97", + "resolved": "https://registry.npmjs.org/@microsoft/kiota-abstractions/-/kiota-abstractions-1.0.0-preview.97.tgz", + "integrity": "sha512-ENazW/UmJWG5Si8jea2TfhYEsEmKEY+xDMzQW2tx4D7n7a6h6M6sVWLouz//jZ9oxMDIykXuP/fUcO7pHTdwgA==", + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "^1.7.0", + "@std-uritemplate/std-uritemplate": "^2.0.0", + "tinyduration": "^3.3.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@microsoft/kiota-authentication-azure": { + "version": "1.0.0-preview.97", + "resolved": "https://registry.npmjs.org/@microsoft/kiota-authentication-azure/-/kiota-authentication-azure-1.0.0-preview.97.tgz", + "integrity": "sha512-s567kjpHMXRZx+XGEXGg3fl5xeA3HXIStxAn/xyYv1+Ww8dRgRwudTvc9++4yuKfU+9tOCKopEdMejOb8pXmVQ==", + "license": "MIT", + "dependencies": { + "@azure/core-auth": "^1.5.0", + "@microsoft/kiota-abstractions": "^1.0.0-preview.97", + "@opentelemetry/api": "^1.7.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@microsoft/kiota-bundle": { + "version": "1.0.0-preview.97", + "resolved": "https://registry.npmjs.org/@microsoft/kiota-bundle/-/kiota-bundle-1.0.0-preview.97.tgz", + "integrity": "sha512-3onjFdZpcFHM88gGYePNYj7iSDwlAhxutFXee9Thu+Ytkgegv75OyvbS02SgX71jolQbse/fn8hdyTpyBON5hQ==", + "license": "MIT", + "dependencies": { + "@microsoft/kiota-abstractions": "^1.0.0-preview.97", + "@microsoft/kiota-http-fetchlibrary": "^1.0.0-preview.97", + "@microsoft/kiota-serialization-form": "^1.0.0-preview.97", + "@microsoft/kiota-serialization-json": "^1.0.0-preview.97", + "@microsoft/kiota-serialization-multipart": "^1.0.0-preview.97", + "@microsoft/kiota-serialization-text": "^1.0.0-preview.97" + } + }, + "node_modules/@microsoft/kiota-http-fetchlibrary": { + "version": "1.0.0-preview.97", + "resolved": "https://registry.npmjs.org/@microsoft/kiota-http-fetchlibrary/-/kiota-http-fetchlibrary-1.0.0-preview.97.tgz", + "integrity": "sha512-83+sLY6QEJ8D64+VLbrTzmmAtPq7LdD5+UwuX+E4q1ch4+Ty1EFgx9n61xM5fjG6AOVdqbWaTxhqI3C+5gIuzw==", + "license": "MIT", + "dependencies": { + "@microsoft/kiota-abstractions": "^1.0.0-preview.97", + "@opentelemetry/api": "^1.7.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@microsoft/kiota-serialization-form": { + "version": "1.0.0-preview.97", + "resolved": "https://registry.npmjs.org/@microsoft/kiota-serialization-form/-/kiota-serialization-form-1.0.0-preview.97.tgz", + "integrity": "sha512-yOjiDjhF26WIerLs7kAOE0ij7GwmEg3KED7oAYV6/T5NQwQBIcJ+4O2LaemvqnQRhZmwyuFhWlh1nLt0yHP+7g==", + "license": "MIT", + "dependencies": { + "@microsoft/kiota-abstractions": "^1.0.0-preview.97", + "tslib": "^2.6.2" + } + }, + "node_modules/@microsoft/kiota-serialization-json": { + "version": "1.0.0-preview.97", + "resolved": "https://registry.npmjs.org/@microsoft/kiota-serialization-json/-/kiota-serialization-json-1.0.0-preview.97.tgz", + "integrity": "sha512-U5gGuLPXjdL81qoFzd0Ffi/r1MWyprFS8BBHmHZ032KMF+GWtU4IFe5fy1KCdXheTliKtWu5YtnghXSiUQW8Lw==", + "license": "MIT", + "dependencies": { + "@microsoft/kiota-abstractions": "^1.0.0-preview.97", + "tslib": "^2.6.2" + } + }, + "node_modules/@microsoft/kiota-serialization-multipart": { + "version": "1.0.0-preview.97", + "resolved": "https://registry.npmjs.org/@microsoft/kiota-serialization-multipart/-/kiota-serialization-multipart-1.0.0-preview.97.tgz", + "integrity": "sha512-Srabd69lwtaZT3RP6fC5PELs8B+ct7hJDmRW7t1ZBE7MKRHy7dGi0XtLd19rqIUsRFc7BU1NgcT//LkCSb6ccg==", + "license": "MIT", + "dependencies": { + "@microsoft/kiota-abstractions": "^1.0.0-preview.97", + "tslib": "^2.6.2" + } + }, + "node_modules/@microsoft/kiota-serialization-text": { + "version": "1.0.0-preview.97", + "resolved": "https://registry.npmjs.org/@microsoft/kiota-serialization-text/-/kiota-serialization-text-1.0.0-preview.97.tgz", + "integrity": "sha512-FJLh8Gq9ZfVSqTr/QoltqLEY9oaHvefmI/WZvyGrNHBVQOR+2TBg32ptiGhRzjJQIZGgJdPj9GYApkDvo8T5MQ==", + "license": "MIT", + "dependencies": { + "@microsoft/kiota-abstractions": "^1.0.0-preview.97", + "tslib": "^2.6.2" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@samchon/openapi": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@samchon/openapi/-/openapi-4.7.1.tgz", + "integrity": "sha512-+rkMlSKMt7l3KGWJVWUle1CXEm0vA8FIF2rufHl+T1gN/gGrTEhL1gDK3FHYf8Nl5XReK0r1vL6Q2QTMwQN7xQ==", + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@std-uritemplate/std-uritemplate": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@std-uritemplate/std-uritemplate/-/std-uritemplate-2.0.5.tgz", + "integrity": "sha512-AE3/wSo1J3UwRTN/iOopPKh7aaIjgXZYJ6UkndRL9E9nlEwknpGqGsIoIinWZXsUB6kBVsq0mxfYm4KwEr3VSQ==", + "license": "Apache-2.0" + }, + "node_modules/@types/node": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.0.tgz", + "integrity": "sha512-sOx1PKSuFwnIl7z4RN0Ls7N9AQawmR9r66eI5rFCzLDIs8HTIYrIpH9QjYWoX0lkgGrkLxXhi4QnK7MizPRrIg==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/array-timsort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/chardet": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", + "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "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==", + "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==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/comment-json": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.5.tgz", + "integrity": "sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==", + "license": "MIT", + "dependencies": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.3", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/drange": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", + "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/global-prefix": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-4.0.0.tgz", + "integrity": "sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^4.1.3", + "kind-of": "^6.0.3", + "which": "^4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/inquirer": { + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", + "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC" + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", + "license": "MIT", + "dependencies": { + "quansync": "^0.2.7" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "node_modules/randexp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", + "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", + "license": "MIT", + "dependencies": { + "drange": "^1.0.2", + "ret": "^0.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ret": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "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/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "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==", + "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/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/tinyduration": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tinyduration/-/tinyduration-3.4.1.tgz", + "integrity": "sha512-NemFoamVYn7TmtwZKZ3OiliM9fZkr6EWiTM+wKknco6POSy2gS689xx/pXip0JYp40HXpUw6k65CUYHWYUXdaA==", + "license": "MIT" + }, + "node_modules/ts-patch": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-patch/-/ts-patch-3.3.0.tgz", + "integrity": "sha512-zAOzDnd5qsfEnjd9IGy1IRuvA7ygyyxxdxesbhMdutt8AHFjD8Vw8hU2rMF89HX1BKRWFYqKHrO8Q6lw0NeUZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "global-prefix": "^4.0.0", + "minimist": "^1.2.8", + "resolve": "^1.22.2", + "semver": "^7.6.3", + "strip-ansi": "^6.0.1" + }, + "bin": { + "ts-patch": "bin/ts-patch.js", + "tspc": "bin/tspc.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typia": { + "version": "9.7.1", + "resolved": "https://registry.npmjs.org/typia/-/typia-9.7.1.tgz", + "integrity": "sha512-HY9hhvAPhFvFHfjA3Ny1DmucUyrbsFalt+wr58oBJyNBFUxE6nTF8aJSpLOv1Bav6dZslNh39MEez0s7qLB1jw==", + "license": "MIT", + "dependencies": { + "@samchon/openapi": "^4.7.1", + "@standard-schema/spec": "^1.0.0", + "commander": "^10.0.0", + "comment-json": "^4.2.3", + "inquirer": "^8.2.5", + "package-manager-detector": "^0.2.0", + "randexp": "^0.5.3" + }, + "bin": { + "typia": "lib/executable/typia.js" + }, + "peerDependencies": { + "typescript": ">=4.8.0 <5.10.0" + } + }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/src/urlShortener/TypeScript/package.json b/src/urlShortener/TypeScript/package.json new file mode 100644 index 0000000..f57cb90 --- /dev/null +++ b/src/urlShortener/TypeScript/package.json @@ -0,0 +1,43 @@ +{ + "name": "@shi-corp/sdk-url-shortener", + "version": "0.0.1", + "type": "module", + "main": "bin/index.js", + "description": "SDK client used to interface with the URL Shortener application.", + "keywords": [ + "OpenAPI", + "URL Shortener", + "SDK", + "Automation", + "API", + "SHI" + ], + "homepage": "https://github.com/Software-Hardware-Integration-Lab/OpenAPI#readme", + "bugs": { + "url": "https://github.com/Software-Hardware-Integration-Lab/OpenAPI/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Software-Hardware-Integration-Lab/OpenAPI.git" + }, + "license": "MIT", + "author": "Elliot Huffman (elliot_huffman@shi.com)", + "scripts": { + "build:Dev": "tsc", + "prebuild:Prod": "tsc --sourceMap false --emitDeclarationOnly false", + "build:Prod": "tsc --sourceMap false --removeComments false", + "generate:Sdk": "kiota generate -l typescript -d ../../../specs/Url-Shortener.json -c UrlShortenerClient -o ./sdk/ --exclude-backward-compatible", + "prepare": "ts-patch install" + }, + "devDependencies": { + "@azure/core-auth": "~1.10.0", + "@types/node": "~24.3.0", + "ts-patch": "~3.3.0", + "typescript": "~5.9.2" + }, + "dependencies": { + "@microsoft/kiota-authentication-azure": "~1.0.0-preview.97", + "@microsoft/kiota-bundle": "~1.0.0-preview.97", + "typia": "~9.7.1" + } +} diff --git a/src/urlShortener/TypeScript/tsconfig.json b/src/urlShortener/TypeScript/tsconfig.json new file mode 100644 index 0000000..2380b4d --- /dev/null +++ b/src/urlShortener/TypeScript/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "emitDeclarationOnly": true, + "noImplicitAny": false, + "outDir": "./bin", + "plugins": [ + { + "transform": "typia/lib/transform" + } + ] + }, + "extends": "../../../tsconfig.base.json", + "include": [ + "./**/*" + ] +}