diff --git a/.prettierignore b/.prettierignore index 2d3d01a2..c2163a57 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,4 +2,5 @@ **/gen **/node_modules **/dist +**/.next **/.expo diff --git a/README.md b/README.md index 4f5f2c13..1ee6a4eb 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,12 @@ Use this for Cloudflare Workers as well. [Read the docs](packages/node-sdk/README.md) +## REST API SDK (beta) + +Typed SDK for Reflag's REST API. + +[Read the docs](packages/rest-api-sdk/README.md) + ## Reflag CLI CLI to interact with Reflag and generate types diff --git a/package.json b/package.json index d947068f..9d4d4872 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,8 @@ "license": "MIT", "workspaces": [ "packages/*", + "packages/rest-api-sdk/examples/*", + "packages/react-sdk/dev/*", "packages/react-native-sdk/dev/*", "packages/openfeature-browser-provider/example" ], diff --git a/packages/react-sdk/dev/nextjs-bootstrap-demo/app/client.ts b/packages/react-sdk/dev/nextjs-bootstrap-demo/app/client.ts index 7f024393..1e8663f4 100644 --- a/packages/react-sdk/dev/nextjs-bootstrap-demo/app/client.ts +++ b/packages/react-sdk/dev/nextjs-bootstrap-demo/app/client.ts @@ -1,7 +1,7 @@ import { ReflagClient as ReflagNodeClient } from "@reflag/node-sdk"; -const secretKey = process.env.REFLAG_SECRET_KEY || ""; -const offline = process.env.CI === "true"; +const secretKey = process.env.REFLAG_SECRET_KEY; +const offline = process.env.CI === "true" || !secretKey; declare global { var serverClient: ReflagNodeClient; diff --git a/packages/rest-api-sdk/.prettierignore b/packages/rest-api-sdk/.prettierignore new file mode 100644 index 00000000..71e1d20f --- /dev/null +++ b/packages/rest-api-sdk/.prettierignore @@ -0,0 +1,3 @@ +dist/ +src/generated/ +**/.next/ diff --git a/packages/rest-api-sdk/README.md b/packages/rest-api-sdk/README.md new file mode 100644 index 00000000..bcd62a51 --- /dev/null +++ b/packages/rest-api-sdk/README.md @@ -0,0 +1,315 @@ +# @reflag/rest-api-sdk (beta) + +Typed SDK for Reflag's REST API. + +## Installation + +```bash +npm install @reflag/rest-api-sdk +# or +yarn add @reflag/rest-api-sdk +``` + +## Create a client + +Initialize the SDK with a [Reflag REST API Key](https://app.reflag.com/env-current/settings/org-api-access). + +```typescript +import { Api } from "@reflag/rest-api-sdk"; + +const api = new Api({ + accessToken: process.env.REFLAG_API_KEY, +}); +``` + +## API surface + +Main exports: + +- `Api`: base client +- `createAppClient(appId, config)`: app-scoped client +- `ReflagApiError`: normalized API error type +- Generated request/response types and models from `@reflag/rest-api-sdk` + +Core method groups: + +- Applications: `listApps`, `getApp` +- Environments: `listEnvironments`, `getEnvironment` +- Flags: `listFlags`, `createFlag`, `updateFlag` +- User/company evaluation: `getUserFlags`, `updateUserFlags`, `getCompanyFlags`, `updateCompanyFlags` + +## Quick start + +```typescript +const apps = await api.listApps(); +console.log(apps.data); +// [ +// { +// "org": { "id": "org-1", "name": "Acme Org" }, +// "id": "app-123", +// "name": "Acme App", +// "demo": false, +// "flagKeyFormat": "kebabCaseLower", +// "environments": [ +// { "id": "env-123", "name": "Development", "isProduction": false, "order": 0 }, +// { "id": "env-456", "name": "Production", "isProduction": true, "order": 1 } +// ] +// } +// ] + +const app = apps.data[0]; +const appId = app?.id; + +if (appId) { + const environments = await api.listEnvironments({ + appId, + sortBy: "order", + sortOrder: "asc", + }); + + console.log(environments.data); + // [ + // { "id": "env-456", "name": "Production", "isProduction": true, "order": 1 } + // ] +} +``` + +## App-scoped client + +If most calls are for one app, use `createAppClient` to avoid repeating `appId`. + +```typescript +import { createAppClient } from "@reflag/rest-api-sdk"; + +const appApi = createAppClient("app-123", { + accessToken: process.env.REFLAG_API_KEY, +}); + +const environments = await appApi.listEnvironments({ + sortBy: "order", + sortOrder: "asc", +}); +console.log(environments.data); +// [ +// { "id": "env-456", "name": "Production", "isProduction": true, "order": 1 } +// ] + +const flags = await appApi.listFlags({}); +console.log(flags.data); +// [ +// { +// "id": "flag-1", +// "key": "new-checkout", +// "name": "New checkout", +// "description": "Rollout for redesigned checkout flow", +// "stage": { "id": "stage-1", "name": "Beta", "color": "#4f46e5", "order": 2 }, +// "owner": { +// "id": "user-99", +// "name": "Jane Doe", +// "email": "jane@acme.com", +// "avatarUrl": "https://example.com/avatar.png" +// }, +// "archived": false, +// "stale": false, +// "permanent": false, +// "createdAt": "2026-03-03T09:00:00.000Z", +// "lastCheckAt": "2026-03-03T09:30:00.000Z", +// "lastTrackAt": "2026-03-03T09:31:00.000Z" +// } +// ] +``` + +## Common workflows + +### Create and update a flag + +`createFlag` and `updateFlag` return `{ flag }` with the latest flag details. + +Use `null` to clear nullable fields like `description` or `ownerUserId` on update. + +```typescript +const created = await api.createFlag({ + appId: "app-123", + key: "new-checkout", + name: "New checkout", + description: "Rollout for redesigned checkout flow", + secret: false, +}); + +const updated = await api.updateFlag({ + appId: "app-123", + flagId: created.flag.id, + name: "New checkout experience", + ownerUserId: null, +}); +console.log(updated.flag); +// { +// "id": "flag-1", +// "key": "new-checkout", +// "name": "New checkout experience", +// "description": "Rollout for redesigned checkout flow", +// "stage": { "id": "stage-1", "name": "Beta", "color": "#4f46e5", "order": 2 }, +// "owner": { +// "id": "user-99", +// "name": "Jane Doe", +// "email": "jane@acme.com", +// "avatarUrl": "https://example.com/avatar.png" +// }, +// "archived": false, +// "stale": false, +// "permanent": false, +// "createdAt": "2026-03-03T09:00:00.000Z", +// "lastCheckAt": "2026-03-03T09:35:00.000Z", +// "lastTrackAt": "2026-03-03T09:36:00.000Z", +// "rolledOutToEveryoneAt": "2026-03-10T12:00:00.000Z", +// "parentFlagId": "flag-parent-1" +// } +``` + +### Read user flags for an environment + +`getUserFlags` evaluates flag results for one user in one environment and returns +the user’s current values plus exposure/check metadata for each flag. + +```typescript +const userFlags = await api.getUserFlags({ + appId: "app-123", + envId: "env-456", + userId: "user-1", +}); + +console.log(userFlags.data); +// [ +// { +// "id": "flag-1", +// "key": "new-checkout", +// "name": "New checkout", +// "createdAt": "2026-03-03T09:00:00.000Z", +// "value": true, +// "specificTargetValue": true, +// "firstExposureAt": "2026-03-03T09:05:00.000Z", +// "lastExposureAt": "2026-03-03T09:30:00.000Z", +// "lastCheckAt": "2026-03-03T09:31:00.000Z", +// "exposureCount": 12, +// "firstTrackAt": "2026-03-03T09:06:00.000Z", +// "lastTrackAt": "2026-03-03T09:32:00.000Z", +// "trackCount": 5 +// } +// ] +``` + +### Toggle a user flag + +Use `true` to explicitly target on, and `null` to remove specific targeting. + +```typescript +const updatedUserFlags = await api.updateUserFlags({ + appId: "app-123", + envId: "env-456", + userId: "user-1", + updates: [{ flagKey: "new-checkout", specificTargetValue: true }], +}); +console.log(updatedUserFlags.data); +// [ +// { +// "id": "flag-1", +// "key": "new-checkout", +// "name": "New checkout", +// "createdAt": "2026-03-03T09:00:00.000Z", +// "value": true, +// "specificTargetValue": true, +// "firstExposureAt": "2026-03-03T09:05:00.000Z", +// "lastExposureAt": "2026-03-03T09:35:00.000Z", +// "lastCheckAt": "2026-03-03T09:36:00.000Z", +// "exposureCount": 13, +// "firstTrackAt": "2026-03-03T09:06:00.000Z", +// "lastTrackAt": "2026-03-03T09:37:00.000Z", +// "trackCount": 6 +// } +// ] +``` + +### Read company flags for an environment + +```typescript +const companyFlags = await api.getCompanyFlags({ + appId: "app-123", + envId: "env-456", + companyId: "company-1", +}); +console.log(companyFlags.data); +// [ +// { +// "id": "flag-1", +// "key": "new-checkout", +// "name": "New checkout", +// "createdAt": "2026-03-03T09:00:00.000Z", +// "value": false, +// "specificTargetValue": null, +// "firstExposureAt": null, +// "lastExposureAt": null, +// "lastCheckAt": "2026-03-03T09:31:00.000Z", +// "exposureCount": 0, +// "firstTrackAt": null, +// "lastTrackAt": null, +// "trackCount": 0 +// } +// ] +``` + +### Toggle a company flag + +Use `true` to explicitly target on, and `null` to remove specific targeting. + +```typescript +const updatedCompanyFlags = await api.updateCompanyFlags({ + appId: "app-123", + envId: "env-456", + companyId: "company-1", + // Use `null` to stop targeting the company specifically for that flag. + updates: [{ flagKey: "new-checkout", specificTargetValue: null }], +}); +console.log(updatedCompanyFlags.data); +// [ +// { +// "id": "flag-1", +// "key": "new-checkout", +// "name": "New checkout", +// "createdAt": "2026-03-03T09:00:00.000Z", +// "value": false, +// "specificTargetValue": null, +// "firstExposureAt": null, +// "lastExposureAt": null, +// "lastCheckAt": "2026-03-03T09:36:00.000Z", +// "exposureCount": 0, +// "firstTrackAt": null, +// "lastTrackAt": null, +// "trackCount": 0 +// } +// ] +``` + +## Error handling + +The SDK throws `ReflagApiError` for non-2xx API responses. + +```typescript +import { ReflagApiError } from "@reflag/rest-api-sdk"; + +try { + await api.listApps(); +} catch (error) { + if (error instanceof ReflagApiError) { + console.error(error.status, error.code, error.message, error.details); + } + throw error; +} +``` + +## Example app + +See `packages/rest-api-sdk/examples/customer-admin-panel/README.md` for a small Next.js app using this SDK in server actions. + +## License + +MIT diff --git a/packages/rest-api-sdk/eslint.config.js b/packages/rest-api-sdk/eslint.config.js new file mode 100644 index 00000000..85c50578 --- /dev/null +++ b/packages/rest-api-sdk/eslint.config.js @@ -0,0 +1,8 @@ +const base = require("@reflag/eslint-config"); + +module.exports = [ + ...base, + { + ignores: ["dist/", "src/generated/", "examples/**", "**/.next/**"], + }, +]; diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/README.md b/packages/rest-api-sdk/examples/customer-admin-panel/README.md new file mode 100644 index 00000000..873c6ea0 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/README.md @@ -0,0 +1,25 @@ +# Customer Admin Panel + +Small Next.js (App Router) app that uses `@reflag/rest-api-sdk` with server actions to view and toggle flags for users and companies. + +![Company Flags Screenshot](docs/company-flags-screenshot.png) + +## Setup + +Create a `.env.local` file in this folder with: + +``` +REFLAG_API_KEY=your-api-key +# Optional +REFLAG_BASE_URL=https://app.reflag.com/api +``` + +## Run + +```bash +yarn dev +``` + +Visit: + +- http://localhost:3000/ diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/AppEnvForm.tsx b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/AppEnvForm.tsx new file mode 100644 index 00000000..a87cff56 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/AppEnvForm.tsx @@ -0,0 +1,70 @@ +"use client"; + +type Option = { + id: string; + name: string; +}; + +type AppEnvFormProps = { + apps: Option[]; + envs: Option[]; + selectedAppId: string; + selectedEnvId: string; +}; + +export default function AppEnvForm({ + apps, + envs, + selectedAppId, + selectedEnvId, +}: AppEnvFormProps) { + return ( +
{ + if (event.target instanceof HTMLSelectElement) { + event.currentTarget.requestSubmit(); + } + }} + > + + + +
+ ); +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/EntityFlagsFilterForm.tsx b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/EntityFlagsFilterForm.tsx new file mode 100644 index 00000000..f8721d44 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/EntityFlagsFilterForm.tsx @@ -0,0 +1,89 @@ +"use client"; + +type Option = { + id: string; + name: string; +}; + +type EntityFlagsFilterFormProps = { + action: "/flags/user" | "/flags/company"; + apps: Option[]; + envs: Option[]; + selectedAppId: string; + selectedEnvId: string; + entityIdName: "userId" | "companyId"; + entityIdLabel: string; + entityIdValue: string; + submitLabel: string; +}; + +export default function EntityFlagsFilterForm({ + action, + apps, + envs, + selectedAppId, + selectedEnvId, + entityIdName, + entityIdLabel, + entityIdValue, + submitLabel, +}: EntityFlagsFilterFormProps) { + return ( +
{ + if (event.target instanceof HTMLSelectElement) { + event.currentTarget.requestSubmit(); + } + }} + > + + + +
+ + +
+
+ ); +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/actions.ts b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/actions.ts new file mode 100644 index 00000000..8bbaf6d5 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/actions.ts @@ -0,0 +1,133 @@ +"use server"; + +import type { + AppHeaderCollection, + EnvironmentHeaderCollection, + EntityFlagsResponse, + FlagHeaderCollection, +} from "@reflag/rest-api-sdk"; +import { Api, createAppClient } from "@reflag/rest-api-sdk"; + +const apiKey = process.env.REFLAG_API_KEY; +const basePath = process.env.REFLAG_BASE_URL ?? "https://app.reflag.com/api"; + +function getClient() { + if (!apiKey) { + throw new Error("REFLAG_API_KEY is not set"); + } + return new Api({ + accessToken: apiKey, + basePath, + }); +} + +function getAppClient(appId: string) { + if (!appId) { + throw new Error("appId is required"); + } + if (!apiKey) { + throw new Error("REFLAG_API_KEY is not set"); + } + return createAppClient(appId, { + accessToken: apiKey, + basePath, + }); +} + +export async function listApps(): Promise { + const client = getClient(); + return await client.listApps(); +} + +export async function listEnvironments( + appId: string, +): Promise { + const client = getAppClient(appId); + return await client.listEnvironments({ + sortBy: "order", + sortOrder: "asc", + }); +} + +export async function listFlags(appId: string): Promise { + const client = getAppClient(appId); + return await client.listFlags({}); +} + +export async function fetchUserFlags( + appId: string, + envId: string, + userId: string, +): Promise { + if (!envId) { + throw new Error("envId is required"); + } + if (!userId) { + throw new Error("userId is required"); + } + const client = getAppClient(appId); + return await client.getUserFlags({ + envId, + userId, + }); +} + +export async function toggleUserFlag( + appId: string, + envId: string, + userId: string, + flagKey: string, + enabled: boolean, +): Promise { + if (!envId) { + throw new Error("envId is required"); + } + if (!userId || !flagKey) { + throw new Error("userId and flagKey are required"); + } + const client = getAppClient(appId); + await client.updateUserFlags({ + envId, + userId, + updates: [{ flagKey, specificTargetValue: enabled ? true : null }], + }); +} + +export async function fetchCompanyFlags( + appId: string, + envId: string, + companyId: string, +): Promise { + if (!envId) { + throw new Error("envId is required"); + } + if (!companyId) { + throw new Error("companyId is required"); + } + const client = getAppClient(appId); + return await client.getCompanyFlags({ + envId, + companyId, + }); +} + +export async function toggleCompanyFlag( + appId: string, + envId: string, + companyId: string, + flagKey: string, + enabled: boolean, +): Promise { + if (!envId) { + throw new Error("envId is required"); + } + if (!companyId || !flagKey) { + throw new Error("companyId and flagKey are required"); + } + const client = getAppClient(appId); + await client.updateCompanyFlags({ + envId, + companyId, + updates: [{ flagKey, specificTargetValue: enabled ? true : null }], + }); +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/company/page.tsx b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/company/page.tsx new file mode 100644 index 00000000..bbbcb275 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/company/page.tsx @@ -0,0 +1,154 @@ +import Link from "next/link"; +import { redirect } from "next/navigation"; +import { revalidatePath } from "next/cache"; +import EntityFlagsFilterForm from "../EntityFlagsFilterForm"; +import { + fetchCompanyFlags, + listApps, + listEnvironments, + toggleCompanyFlag, +} from "../actions"; + +export const dynamic = "force-dynamic"; + +type QueryValue = string | string[] | undefined; + +type PageProps = { + searchParams?: { + appId?: QueryValue; + envId?: QueryValue; + companyId?: QueryValue; + }; +}; + +function getQueryValue(value: QueryValue) { + return Array.isArray(value) ? (value[0] ?? "") : (value ?? ""); +} + +export default async function CompanyFlagsPage({ searchParams }: PageProps) { + const apps = (await listApps()).data ?? []; + const requestedAppId = getQueryValue(searchParams?.appId); + const selectedAppId = + apps.find((app) => app.id === requestedAppId)?.id ?? apps[0]?.id ?? ""; + + const envs = selectedAppId + ? ((await listEnvironments(selectedAppId)).data ?? []) + : []; + + const requestedEnvId = getQueryValue(searchParams?.envId); + const selectedEnvId = + envs.find((env) => env.id === requestedEnvId)?.id ?? envs[0]?.id ?? ""; + + const companyId = getQueryValue(searchParams?.companyId); + + const flags = + selectedAppId && selectedEnvId && companyId + ? ((await fetchCompanyFlags(selectedAppId, selectedEnvId, companyId)) + .data ?? []) + : []; + + async function updateCompanyFlagAction(formData: FormData) { + "use server"; + + const appId = String(formData.get("appId") ?? ""); + const envId = String(formData.get("envId") ?? ""); + const nextCompanyId = String(formData.get("companyId") ?? ""); + const flagKey = String(formData.get("flagKey") ?? ""); + const nextValue = String(formData.get("nextValue") ?? "") === "true"; + + await toggleCompanyFlag(appId, envId, nextCompanyId, flagKey, nextValue); + + const query = new URLSearchParams({ + appId, + envId, + companyId: nextCompanyId, + }); + revalidatePath("/flags/company"); + redirect(`/flags/company?${query.toString()}`); + } + + return ( +
+ Back to flags +

Company Flags

+ + + + {!companyId ?

Enter a company ID to load flags.

: null} + {companyId && flags.length === 0 ?

No flags loaded.

: null} + + {flags.length > 0 ? ( + + + + + + + + + + + {flags.map((flag) => { + const isInherited = + flag.value && flag.specificTargetValue === null; + + return ( + + + + + + + ); + })} + +
FlagKeyEnabledAction
{flag.name}{flag.key} + {flag.value + ? isInherited + ? "Yes (implicitly)" + : "Yes" + : "No"} + + {!isInherited && ( +
+ + + + + + +
+ )} +
+ ) : null} +
+ ); +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/page.tsx b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/page.tsx new file mode 100644 index 00000000..ca33c750 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/page.tsx @@ -0,0 +1,128 @@ +import Link from "next/link"; +import AppEnvForm from "./AppEnvForm"; +import { listApps, listEnvironments, listFlags } from "./actions"; + +export const dynamic = "force-dynamic"; + +type QueryValue = string | string[] | undefined; + +type PageProps = { + searchParams?: { + appId?: QueryValue; + envId?: QueryValue; + }; +}; + +function getQueryValue(value: QueryValue) { + return Array.isArray(value) ? (value[0] ?? "") : (value ?? ""); +} + +export default async function FlagsPage({ searchParams }: PageProps) { + const apps = (await listApps()).data ?? []; + const requestedAppId = getQueryValue(searchParams?.appId); + const selectedAppId = + apps.find((app) => app.id === requestedAppId)?.id ?? apps[0]?.id ?? ""; + + const envs = selectedAppId + ? ((await listEnvironments(selectedAppId)).data ?? []) + : []; + + const requestedEnvId = getQueryValue(searchParams?.envId); + const selectedEnvId = + envs.find((env) => env.id === requestedEnvId)?.id ?? envs[0]?.id ?? ""; + + const flags = selectedAppId + ? ((await listFlags(selectedAppId)).data ?? []) + : []; + + return ( +
+

Flags

+ + + +
+
+ + + + +
+ +
+ + + + +
+
+ + {flags.length === 0 ?

No flags loaded.

: null} + {flags.length > 0 ? ( + + + + + + + + + + {flags.map((flag) => ( + + + + + + ))} + +
FlagKeyOpen
{flag.name}{flag.key} + + User + + {" / "} + + Company + +
+ ) : null} +
+ ); +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/user/page.tsx b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/user/page.tsx new file mode 100644 index 00000000..e50ea01e --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/app/flags/user/page.tsx @@ -0,0 +1,146 @@ +import Link from "next/link"; +import { redirect } from "next/navigation"; +import { revalidatePath } from "next/cache"; +import EntityFlagsFilterForm from "../EntityFlagsFilterForm"; +import { + fetchUserFlags, + listApps, + listEnvironments, + toggleUserFlag, +} from "../actions"; + +export const dynamic = "force-dynamic"; + +type QueryValue = string | string[] | undefined; + +type PageProps = { + searchParams?: { + appId?: QueryValue; + envId?: QueryValue; + userId?: QueryValue; + }; +}; + +function getQueryValue(value: QueryValue) { + return Array.isArray(value) ? (value[0] ?? "") : (value ?? ""); +} + +export default async function UserFlagsPage({ searchParams }: PageProps) { + const apps = (await listApps()).data ?? []; + const requestedAppId = getQueryValue(searchParams?.appId); + const selectedAppId = + apps.find((app) => app.id === requestedAppId)?.id ?? apps[0]?.id ?? ""; + + const envs = selectedAppId + ? ((await listEnvironments(selectedAppId)).data ?? []) + : []; + + const requestedEnvId = getQueryValue(searchParams?.envId); + const selectedEnvId = + envs.find((env) => env.id === requestedEnvId)?.id ?? envs[0]?.id ?? ""; + + const userId = getQueryValue(searchParams?.userId); + + const flags = + selectedAppId && selectedEnvId && userId + ? ((await fetchUserFlags(selectedAppId, selectedEnvId, userId)).data ?? + []) + : []; + + async function updateUserFlagAction(formData: FormData) { + "use server"; + + const appId = String(formData.get("appId") ?? ""); + const envId = String(formData.get("envId") ?? ""); + const nextUserId = String(formData.get("userId") ?? ""); + const flagKey = String(formData.get("flagKey") ?? ""); + const nextValue = String(formData.get("nextValue") ?? "") === "true"; + + await toggleUserFlag(appId, envId, nextUserId, flagKey, nextValue); + + const query = new URLSearchParams({ appId, envId, userId: nextUserId }); + revalidatePath("/flags/user"); + redirect(`/flags/user?${query.toString()}`); + } + + return ( +
+ Back to flags +

User Flags

+ + + + {!userId ?

Enter a user ID to load flags.

: null} + {userId && flags.length === 0 ?

No flags loaded.

: null} + + {flags.length > 0 ? ( + + + + + + + + + + + {flags.map((flag) => { + const isInherited = + flag.value && flag.specificTargetValue === null; + + return ( + + + + + + + ); + })} + +
FlagKeyEnabledAction
{flag.name}{flag.key} + {flag.value + ? isInherited + ? "Yes (implicitly)" + : "Yes" + : "No"} + + {!isInherited && ( +
+ + + + + + +
+ )} +
+ ) : null} +
+ ); +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/app/globals.css b/packages/rest-api-sdk/examples/customer-admin-panel/app/globals.css new file mode 100644 index 00000000..18ac133d --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/app/globals.css @@ -0,0 +1,82 @@ +:root { + color-scheme: light; + font-family: + "Inter", + "SF Pro Text", + system-ui, + -apple-system, + sans-serif; + line-height: 1.5; + background: #f7f7f8; + color: #111827; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + background: #f7f7f8; +} + +main { + background: #ffffff; + border: 1px solid #e5e7eb; + border-radius: 16px; + box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06); +} + +h1 { + margin-top: 0; +} + +label span { + font-size: 0.9rem; + color: #4b5563; +} + +input, +select, +button { + font: inherit; + border-radius: 10px; + border: 1px solid #d1d5db; + padding: 8px 12px; +} + +button { + background: #111827; + color: #ffffff; + cursor: pointer; +} + +button:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +a { + color: #111827; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +table { + width: 100%; + border-collapse: collapse; +} + +thead th { + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 0.04em; + color: #6b7280; +} + +tbody tr:nth-child(even) { + background: #f9fafb; +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/app/layout.tsx b/packages/rest-api-sdk/examples/customer-admin-panel/app/layout.tsx new file mode 100644 index 00000000..c797f32b --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/app/layout.tsx @@ -0,0 +1,19 @@ +import "./globals.css"; + +export const metadata = { + title: "Customer Admin Panel", + description: + "Customer admin panel example app powered by the Reflag REST API SDK", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/app/page.tsx b/packages/rest-api-sdk/examples/customer-admin-panel/app/page.tsx new file mode 100644 index 00000000..fa5397a9 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/app/page.tsx @@ -0,0 +1,7 @@ +import FlagsPage from "./flags/page"; + +export const dynamic = "force-dynamic"; + +export default function Home() { + return ; +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/docs/company-flags-screenshot.png b/packages/rest-api-sdk/examples/customer-admin-panel/docs/company-flags-screenshot.png new file mode 100644 index 00000000..f2f208b5 Binary files /dev/null and b/packages/rest-api-sdk/examples/customer-admin-panel/docs/company-flags-screenshot.png differ diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/next-env.d.ts b/packages/rest-api-sdk/examples/customer-admin-panel/next-env.d.ts new file mode 100644 index 00000000..fd36f949 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/next.config.js b/packages/rest-api-sdk/examples/customer-admin-panel/next.config.js new file mode 100644 index 00000000..22a21b45 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/next.config.js @@ -0,0 +1,7 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + transpilePackages: ["@reflag/rest-api-sdk"], + reactStrictMode: true, +}; + +module.exports = nextConfig; diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/package.json b/packages/rest-api-sdk/examples/customer-admin-panel/package.json new file mode 100644 index 00000000..ccab0eba --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/package.json @@ -0,0 +1,17 @@ +{ + "name": "customer-admin-panel", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "echo 'No lint configured for customer-admin-panel example; skipping.'" + }, + "dependencies": { + "@reflag/rest-api-sdk": "workspace:*", + "next": "14.2.5", + "react": "18.3.1", + "react-dom": "18.3.1" + } +} diff --git a/packages/rest-api-sdk/examples/customer-admin-panel/tsconfig.json b/packages/rest-api-sdk/examples/customer-admin-panel/tsconfig.json new file mode 100644 index 00000000..8e906d60 --- /dev/null +++ b/packages/rest-api-sdk/examples/customer-admin-panel/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "@reflag/tsconfig/library", + "compilerOptions": { + "lib": ["ES2020", "DOM"], + "module": "ESNext", + "jsx": "preserve", + "noEmit": true, + "moduleResolution": "Bundler", + "allowJs": true, + "skipLibCheck": true, + "incremental": true, + "isolatedModules": true, + "plugins": [ + { + "name": "next" + } + ], + "strictNullChecks": true + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/packages/rest-api-sdk/openapi-generator.config.yaml b/packages/rest-api-sdk/openapi-generator.config.yaml new file mode 100644 index 00000000..d0adc698 --- /dev/null +++ b/packages/rest-api-sdk/openapi-generator.config.yaml @@ -0,0 +1,15 @@ +generatorName: typescript-fetch +inputSpec: https://app.reflag.com/openapi.json +outputDir: src/generated +templateDir: ./openapi-templates +additionalProperties: + supportsES6: true + typescriptThreePlus: true + useSingleRequestParameter: true + withInterfaces: true + useTags: false +globalProperties: + apiDocs: false + modelDocs: false + apiTests: false + modelTests: false diff --git a/packages/rest-api-sdk/openapi-templates/apis.mustache b/packages/rest-api-sdk/openapi-templates/apis.mustache new file mode 100644 index 00000000..33c8ddf6 --- /dev/null +++ b/packages/rest-api-sdk/openapi-templates/apis.mustache @@ -0,0 +1,485 @@ +/* tslint:disable */ +/* eslint-disable */ +{{>licenseInfo}} + + +import * as runtime from '../runtime{{importFileExtension}}'; +{{#imports.0}} +import type { + {{#imports}} + {{className}}, + {{/imports}} +} from '../models/index{{importFileExtension}}'; +{{^withoutRuntimeChecks}} +import { + {{#imports}} + {{className}}FromJSON, + {{className}}ToJSON, + {{/imports}} +} from '../models/index{{importFileExtension}}'; +{{/withoutRuntimeChecks}} +{{/imports.0}} + +{{#operations}} +{{#operation}} +{{#allParams.0}} +export interface {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}Request {{#bodyParam}}extends {{{dataType}}} {{/bodyParam}}{ +{{#allParams}} + {{^isBodyParam}} + {{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{#hasReadOnly}}Omit<{{{dataType}}}, {{#readOnlyVars}}'{{baseName}}'{{^-last}}|{{/-last}}{{/readOnlyVars}}>{{/hasReadOnly}}{{^hasReadOnly}}{{{dataType}}}{{/hasReadOnly}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}; + {{/isBodyParam}} +{{/allParams}} +} + +{{/allParams.0}} +{{/operation}} +{{/operations}} +{{#withInterfaces}} +{{#operations}} +/** + * {{classname}} - interface + * {{#lambda.indented_1}}{{{unescapedDescription}}}{{/lambda.indented_1}} + * @export + * @interface {{classname}}Interface + */ +export interface {{classname}}Interface { +{{#operation}} + /** + * {{¬es}} + {{#summary}} + * @summary {{&summary}} + {{/summary}} + {{#allParams}} + {{#isBodyParam}} + {{#vars}} + * @param {{=<% %>=}}{<%&dataType%>}<%={{ }}=%> {{^required}}[{{/required}}{{name}}{{^required}}]{{/required}} {{description}} + {{/vars}} + {{/isBodyParam}} + {{^isBodyParam}} + * @param {{=<% %>=}}{<%&dataType%>}<%={{ }}=%> {{^required}}[{{/required}}{{paramName}}{{^required}}]{{/required}} {{description}} + {{/isBodyParam}} + {{/allParams}} + * @param {*} [options] Override http request option. + {{#isDeprecated}} + * @deprecated + {{/isDeprecated}} + * @throws {RequiredError} + * @memberof {{classname}}Interface + */ + {{nickname}}Raw({{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}Request, {{/allParams.0}}initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + {{#notes}} + * {{¬es}} + {{/notes}} + {{#summary}} + * {{&summary}} + {{/summary}} + {{#isDeprecated}} + * @deprecated + {{/isDeprecated}} + */ + {{^useSingleRequestParameter}} + {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{{{returnType}}}{{#returnType}}{{#isResponseOptional}} | null | undefined {{/isResponseOptional}}{{/returnType}}{{^returnType}}void{{/returnType}}>; + {{/useSingleRequestParameter}} + {{#useSingleRequestParameter}} + {{nickname}}({{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}Request, {{/allParams.0}}initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{{{returnType}}}{{#returnType}}{{#isResponseOptional}} | null | undefined {{/isResponseOptional}}{{/returnType}}{{^returnType}}void{{/returnType}}>; + {{/useSingleRequestParameter}} + +{{/operation}} +} + +{{/operations}} +{{/withInterfaces}} +{{#operations}} +/** + * {{#lambda.indented_star_1}}{{{unescapedDescription}}}{{/lambda.indented_star_1}} + */ +{{#withInterfaces}} +export class {{classname}} extends runtime.BaseAPI implements {{classname}}Interface { +{{/withInterfaces}} +{{^withInterfaces}} +export class {{classname}} extends runtime.BaseAPI { +{{/withInterfaces}} + + {{#operation}} + /** + {{#notes}} + * {{¬es}} + {{/notes}} + {{#summary}} + * {{&summary}} + {{/summary}} + {{#isDeprecated}} + * @deprecated + {{/isDeprecated}} + */ + async {{nickname}}Raw({{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}Request, {{/allParams.0}}initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + {{#allParams}} + {{#required}} + if (requestParameters['{{paramName}}'] == null) { + throw new runtime.RequiredError( + '{{paramName}}', + 'Required parameter "{{paramName}}" was null or undefined when calling {{nickname}}().' + ); + } + + {{/required}} + {{/allParams}} + const queryParameters: any = {}; + + {{#queryParams}} + {{#isArray}} + if (requestParameters['{{paramName}}'] != null) { + {{#isCollectionFormatMulti}} + queryParameters['{{baseName}}'] = requestParameters['{{paramName}}']; + {{/isCollectionFormatMulti}} + {{^isCollectionFormatMulti}} + queryParameters['{{baseName}}'] = {{#uniqueItems}}Array.from({{/uniqueItems}}requestParameters['{{paramName}}']{{#uniqueItems}}){{/uniqueItems}}!.join(runtime.COLLECTION_FORMATS["{{collectionFormat}}"]); + {{/isCollectionFormatMulti}} + } + + {{/isArray}} + {{^isArray}} + if (requestParameters['{{paramName}}'] != null) { + {{#isExplode}} + {{#isContainer}} + for (let key of Object.keys(requestParameters['{{paramName}}'])) { + queryParameters[key] = requestParameters['{{paramName}}'][key]; + } + {{/isContainer}} + {{^isContainer}} +{{>apisAssignQueryParam}} + {{/isContainer}} + {{/isExplode}} + {{^isExplode}} +{{>apisAssignQueryParam}} + {{/isExplode}} + } + + {{/isArray}} + {{/queryParams}} + const headerParameters: runtime.HTTPHeaders = {}; + + {{#bodyParam}} + {{^consumes}} + headerParameters['Content-Type'] = 'application/json'; + + {{/consumes}} + {{#consumes.0}} + headerParameters['Content-Type'] = '{{{mediaType}}}'; + + {{/consumes.0}} + {{/bodyParam}} + {{#headerParams}} + {{#isArray}} + if (requestParameters['{{paramName}}'] != null) { + headerParameters['{{baseName}}'] = {{#uniqueItems}}Array.from({{/uniqueItems}}requestParameters['{{paramName}}']{{#uniqueItems}}){{/uniqueItems}}!.join(runtime.COLLECTION_FORMATS["{{collectionFormat}}"]); + } + + {{/isArray}} + {{^isArray}} + if (requestParameters['{{paramName}}'] != null) { + headerParameters['{{baseName}}'] = String(requestParameters['{{paramName}}']); + } + + {{/isArray}} + {{/headerParams}} + {{#authMethods}} + {{#isBasic}} + {{#isBasicBasic}} + if (this.configuration && (this.configuration.username !== undefined || this.configuration.password !== undefined)) { + headerParameters["Authorization"] = "Basic " + btoa(this.configuration.username + ":" + this.configuration.password); + } + {{/isBasicBasic}} + {{#isBasicBearer}} + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("{{name}}", [{{#scopes}}"{{{scope}}}"{{^-last}}, {{/-last}}{{/scopes}}]); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + {{/isBasicBearer}} + {{/isBasic}} + {{#isApiKey}} + {{#isKeyInHeader}} + if (this.configuration && this.configuration.apiKey) { + headerParameters["{{keyParamName}}"] = await this.configuration.apiKey("{{keyParamName}}"); // {{name}} authentication + } + + {{/isKeyInHeader}} + {{#isKeyInQuery}} + if (this.configuration && this.configuration.apiKey) { + queryParameters["{{keyParamName}}"] = await this.configuration.apiKey("{{keyParamName}}"); // {{name}} authentication + } + + {{/isKeyInQuery}} + {{/isApiKey}} + {{#isOAuth}} + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("{{name}}", [{{#scopes}}"{{{scope}}}"{{^-last}}, {{/-last}}{{/scopes}}]); + } + + {{/isOAuth}} + {{/authMethods}} + {{#hasFormParams}} + const consumes: runtime.Consume[] = [ + {{#consumes}} + { contentType: '{{{mediaType}}}' }, + {{/consumes}} + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + {{#formParams}} + {{#isFile}} + // use FormData to transmit files using content-type "multipart/form-data" + useForm = canConsumeForm; + {{/isFile}} + {{/formParams}} + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + {{#formParams}} + {{#isArray}} + if (requestParameters['{{paramName}}'] != null) { + {{#isCollectionFormatMulti}} + requestParameters['{{paramName}}'].forEach((element) => { + formParams.append('{{baseName}}{{#useSquareBracketsInArrayNames}}[]{{/useSquareBracketsInArrayNames}}', element as any); + }) + {{/isCollectionFormatMulti}} + {{^isCollectionFormatMulti}} + formParams.append('{{baseName}}{{#useSquareBracketsInArrayNames}}[]{{/useSquareBracketsInArrayNames}}', {{#uniqueItems}}Array.from({{/uniqueItems}}requestParameters['{{paramName}}']{{#uniqueItems}}){{/uniqueItems}}!.join(runtime.COLLECTION_FORMATS["{{collectionFormat}}"])); + {{/isCollectionFormatMulti}} + } + + {{/isArray}} + {{^isArray}} + if (requestParameters['{{paramName}}'] != null) { + {{#isDateTimeType}} + formParams.append('{{baseName}}', (requestParameters['{{paramName}}'] as any).toISOString()); + {{/isDateTimeType}} + {{^isDateTimeType}} + {{#isPrimitiveType}} + formParams.append('{{baseName}}', requestParameters['{{paramName}}'] as any); + {{/isPrimitiveType}} + {{^isPrimitiveType}} + {{#isEnumRef}} + formParams.append('{{baseName}}', requestParameters['{{paramName}}'] as any); + {{/isEnumRef}} + {{^isEnumRef}} + {{^withoutRuntimeChecks}} + formParams.append('{{baseName}}', new Blob([JSON.stringify({{{dataType}}}ToJSON(requestParameters['{{paramName}}']))], { type: "application/json", })); + {{/withoutRuntimeChecks}}{{#withoutRuntimeChecks}} + formParams.append('{{baseName}}', new Blob([JSON.stringify(requestParameters['{{paramName}}'])], { type: "application/json", })); + {{/withoutRuntimeChecks}} + {{/isEnumRef}} + {{/isPrimitiveType}} + {{/isDateTimeType}} + } + + {{/isArray}} + {{/formParams}} + {{/hasFormParams}} + + let urlPath = `{{{path}}}`; + {{#pathParams}} + {{#isDateTimeType}} + if (requestParameters['{{paramName}}'] instanceof Date) { + urlPath = urlPath.replace(`{${"{{baseName}}"}}`, encodeURIComponent(requestParameters['{{paramName}}'].toISOString())); + } else { + urlPath = urlPath.replace(`{${"{{baseName}}"}}`, encodeURIComponent(String(requestParameters['{{paramName}}']))); + } + {{/isDateTimeType}} + {{^isDateTimeType}} + {{#isDateType}} + if (requestParameters['{{paramName}}'] instanceof Date) { + urlPath = urlPath.replace(`{${"{{baseName}}"}}`, encodeURIComponent(requestParameters['{{paramName}}'].toISOString().substring(0,10))); + } else { + urlPath = urlPath.replace(`{${"{{baseName}}"}}`, encodeURIComponent(String(requestParameters['{{paramName}}']))); + } + {{/isDateType}} + {{^isDateType}} + urlPath = urlPath.replace(`{${"{{baseName}}"}}`, encodeURIComponent(String(requestParameters['{{paramName}}']))); + {{/isDateType}} + {{/isDateTimeType}} + {{/pathParams}} + + const response = await this.request({ + path: urlPath, + method: '{{httpMethod}}', + headers: headerParameters, + query: queryParameters, + {{#hasBodyParam}} + {{#bodyParam}} + {{^withoutRuntimeChecks}} + body: {{dataType}}ToJSON({ + {{#vars}} + {{name}}: requestParameters['{{name}}'], + {{/vars}} + }), + {{/withoutRuntimeChecks}} + {{#withoutRuntimeChecks}} + body: { + {{#vars}} + {{name}}: requestParameters['{{name}}'], + {{/vars}} + }, + {{/withoutRuntimeChecks}} + {{/bodyParam}} + {{/hasBodyParam}} + {{#hasFormParams}} + body: formParams, + {{/hasFormParams}} + }, initOverrides); + + {{#returnType}} + {{#isResponseFile}} + return new runtime.BlobApiResponse(response); + {{/isResponseFile}} + {{^isResponseFile}} + {{#returnTypeIsPrimitive}} + {{#isMap}} + return new runtime.JSONApiResponse(response); + {{/isMap}} + {{#isArray}} + return new runtime.JSONApiResponse(response); + {{/isArray}} + {{#returnSimpleType}} + if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse<{{returnType}}>(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + {{/returnSimpleType}} + {{/returnTypeIsPrimitive}} + {{^returnTypeIsPrimitive}} + {{#isArray}} + return new runtime.JSONApiResponse(response{{^withoutRuntimeChecks}}, (jsonValue) => {{#uniqueItems}}new Set({{/uniqueItems}}jsonValue.map({{returnBaseType}}FromJSON){{/withoutRuntimeChecks}}){{#uniqueItems}}){{/uniqueItems}}; + {{/isArray}} + {{^isArray}} + {{#isMap}} + return new runtime.JSONApiResponse(response{{^withoutRuntimeChecks}}, (jsonValue) => runtime.mapValues(jsonValue, {{returnBaseType}}FromJSON){{/withoutRuntimeChecks}}); + {{/isMap}} + {{^isMap}} + return new runtime.JSONApiResponse(response{{^withoutRuntimeChecks}}, (jsonValue) => {{returnBaseType}}FromJSON(jsonValue){{/withoutRuntimeChecks}}); + {{/isMap}} + {{/isArray}} + {{/returnTypeIsPrimitive}} + {{/isResponseFile}} + {{/returnType}} + {{^returnType}} + return new runtime.VoidApiResponse(response); + {{/returnType}} + } + + /** + {{#notes}} + * {{¬es}} + {{/notes}} + {{#summary}} + * {{&summary}} + {{/summary}} + {{#isDeprecated}} + * @deprecated + {{/isDeprecated}} + */ + {{^useSingleRequestParameter}} + async {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}}, {{/allParams}}initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{{{returnType}}}{{#returnType}}{{#isResponseOptional}} | null | undefined {{/isResponseOptional}}{{/returnType}}{{^returnType}}void{{/returnType}}> { + {{#returnType}} + const response = await this.{{nickname}}Raw({{#allParams.0}}{ {{#allParams}}{{paramName}}: {{paramName}}{{^-last}}, {{/-last}}{{/allParams}} }, {{/allParams.0}}initOverrides); + {{#isResponseOptional}} + switch (response.raw.status) { + {{#responses}} + {{#is2xx}} + case {{code}}: + return {{#dataType}}await response.value(){{/dataType}}{{^dataType}}null{{/dataType}}; + {{/is2xx}} + {{/responses}} + default: + return await response.value(); + } + {{/isResponseOptional}} + {{^isResponseOptional}} + return await response.value(); + {{/isResponseOptional}} + {{/returnType}} + {{^returnType}} + await this.{{nickname}}Raw({{#allParams.0}}{ {{#allParams}}{{paramName}}: {{paramName}}{{^-last}}, {{/-last}}{{/allParams}} }, {{/allParams.0}}initOverrides); + {{/returnType}} + } + {{/useSingleRequestParameter}} + {{#useSingleRequestParameter}} + async {{nickname}}({{#allParams.0}}requestParameters: {{#prefixParameterInterfaces}}{{classname}}{{/prefixParameterInterfaces}}{{operationIdCamelCase}}Request{{^hasRequiredParams}} = {}{{/hasRequiredParams}}, {{/allParams.0}}initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{{{returnType}}}{{#returnType}}{{#isResponseOptional}} | null | undefined {{/isResponseOptional}}{{/returnType}}{{^returnType}}void{{/returnType}}> { + {{#returnType}} + const response = await this.{{nickname}}Raw({{#allParams.0}}requestParameters, {{/allParams.0}}initOverrides); + {{#isResponseOptional}} + switch (response.raw.status) { + {{#responses}} + {{#is2xx}} + case {{code}}: + return {{#dataType}}await response.value(){{/dataType}}{{^dataType}}null{{/dataType}}; + {{/is2xx}} + {{/responses}} + default: + return await response.value(); + } + {{/isResponseOptional}} + {{^isResponseOptional}} + return await response.value(); + {{/isResponseOptional}} + {{/returnType}} + {{^returnType}} + await this.{{nickname}}Raw({{#allParams.0}}requestParameters, {{/allParams.0}}initOverrides); + {{/returnType}} + } + {{/useSingleRequestParameter}} + + {{/operation}} +} +{{/operations}} +{{#hasEnums}} + +{{#operations}} +{{#operation}} +{{#allParams}} +{{#isEnum}} +{{#stringEnums}} +/** + * @export + * @enum {string} + */ +export enum {{operationIdCamelCase}}{{enumName}} { +{{#allowableValues}} + {{#enumVars}} + {{{name}}} = {{{value}}}{{^-last}},{{/-last}} + {{/enumVars}} +{{/allowableValues}} +} +{{/stringEnums}} +{{^stringEnums}} +/** + * @export + */ +export const {{operationIdCamelCase}}{{enumName}} = { +{{#allowableValues}} + {{#enumVars}} + {{{name}}}: {{{value}}}{{^-last}},{{/-last}} + {{/enumVars}} +{{/allowableValues}} +} as const; +export type {{operationIdCamelCase}}{{enumName}} = typeof {{operationIdCamelCase}}{{enumName}}[keyof typeof {{operationIdCamelCase}}{{enumName}}]; +{{/stringEnums}} +{{/isEnum}} +{{/allParams}} +{{/operation}} +{{/operations}} +{{/hasEnums}} diff --git a/packages/rest-api-sdk/openapi.json b/packages/rest-api-sdk/openapi.json new file mode 100644 index 00000000..e69de29b diff --git a/packages/rest-api-sdk/openapitools.json b/packages/rest-api-sdk/openapitools.json new file mode 100644 index 00000000..dae25538 --- /dev/null +++ b/packages/rest-api-sdk/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.19.0" + } +} diff --git a/packages/rest-api-sdk/package.json b/packages/rest-api-sdk/package.json new file mode 100644 index 00000000..114484e8 --- /dev/null +++ b/packages/rest-api-sdk/package.json @@ -0,0 +1,41 @@ +{ + "name": "@reflag/rest-api-sdk", + "version": "0.0.2", + "description": "Reflag REST API SDK", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/reflagcom/javascript.git" + }, + "scripts": { + "generate": "rm -rf src/generated && npx @openapitools/openapi-generator-cli generate -c openapi-generator.config.yaml", + "build": "yarn generate && tsc --project tsconfig.build.json", + "test": "vitest run --passWithNoTests", + "test:watch": "vitest", + "test:ci": "yarn test --reporter=default --reporter=junit --outputFile=junit.xml", + "lint": "eslint .", + "lint:ci": "eslint --max-warnings=0 --output-file eslint-report.json --format json .", + "prettier": "prettier --check .", + "format": "yarn lint --fix && yarn prettier --write", + "preversion": "yarn lint && yarn prettier && yarn test && yarn build" + }, + "files": [ + "dist" + ], + "publishConfig": { + "access": "public" + }, + "main": "./dist/index.js", + "types": "./dist/types/index.d.ts", + "devDependencies": { + "@openapitools/openapi-generator-cli": "^2.13.5", + "@reflag/eslint-config": "~0.0.2", + "@reflag/tsconfig": "~0.0.2", + "@types/node": "^22.12.0", + "@vitest/coverage-v8": "~1.6.0", + "eslint": "^9.21.0", + "prettier": "^3.5.2", + "typescript": "^5.7.3", + "vitest": "~1.6.0" + } +} diff --git a/packages/rest-api-sdk/src/api.ts b/packages/rest-api-sdk/src/api.ts new file mode 100644 index 00000000..64dce4b5 --- /dev/null +++ b/packages/rest-api-sdk/src/api.ts @@ -0,0 +1,162 @@ +import type { + ConfigurationParameters, + InitOverrideFunction, + RequestOpts, +} from "./generated/runtime"; +import { ResponseError } from "./generated/runtime"; +import { Configuration, DefaultApi } from "./generated"; + +type OmitAppIdParam = F extends ( + arg1: infer A, + ...rest: infer R +) => infer Ret + ? A extends { appId: string } + ? (arg1: Omit, ...rest: R) => Ret + : F + : F; + +export type AppScopedApi = { + [K in keyof T]: OmitAppIdParam; +}; + +export class ReflagApiError extends Error { + status: number; + code?: string; + details?: unknown; + + constructor( + status: number, + message: string, + code?: string, + details?: unknown, + ) { + super(message); + this.name = "ReflagApiError"; + this.status = status; + this.code = code; + this.details = details; + } +} + +async function buildApiError(response: Response) { + const status = response.status; + const contentType = response.headers.get("content-type") ?? ""; + let details: unknown = undefined; + let message = `Request failed with ${status}`; + let code: string | undefined; + + if (contentType.includes("application/json")) { + try { + details = await response.clone().json(); + const maybeError = ( + details as { error?: { message?: string; code?: string } } + )?.error; + if (maybeError?.message) { + message = maybeError.message; + } + if (maybeError?.code) { + code = maybeError.code; + } + } catch { + details = undefined; + } + } else { + try { + const text = await response.clone().text(); + if (text) { + details = text; + message = `Request failed with ${status}: ${text}`; + } + } catch { + details = undefined; + } + } + + return new ReflagApiError(status, message, code, details); +} + +export class Api extends DefaultApi { + constructor(config?: ConfigurationParameters) { + super(new Configuration(config)); + } + + protected async request( + context: RequestOpts, + initOverrides?: RequestInit | InitOverrideFunction, + ): Promise { + try { + return await super.request(context, initOverrides); + } catch (error) { + if (error instanceof ResponseError) { + throw await buildApiError(error.response); + } + throw error; + } + } +} + +function isPlainObject( + value: unknown, +): value is Record | Record { + if (!value || typeof value !== "object" || Array.isArray(value)) { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === Object.prototype || prototype === null; +} + +function scopeApiToAppId( + api: T, + appId: string, + scopedCache: WeakMap = new WeakMap(), +): AppScopedApi { + const cached = scopedCache.get(api as object); + if (cached) { + return cached as AppScopedApi; + } + + const scopedApi = new Proxy(api, { + get(target, prop, receiver) { + const value = Reflect.get(target, prop, receiver); + if (typeof value !== "function") return value; + + const wrapResult = (result: unknown) => { + if (result instanceof Api) { + return scopeApiToAppId(result, appId, scopedCache); + } + return result; + }; + + return (arg1: unknown, ...rest: unknown[]) => { + const isWithMethod = + typeof prop === "string" && prop.startsWith("with"); + if (!isWithMethod && isPlainObject(arg1)) { + const args = "appId" in arg1 ? arg1 : { ...arg1, appId }; + const result = (value as (...args: unknown[]) => unknown).call( + target, + args, + ...rest, + ); + return wrapResult(result); + } + const result = (value as (...args: unknown[]) => unknown).call( + target, + arg1, + ...rest, + ); + return wrapResult(result); + }; + }, + }) as AppScopedApi; + + scopedCache.set(api as object, scopedApi as object); + return scopedApi; +} + +export function createAppClient( + appId: string, + config?: ConfigurationParameters, +) { + return scopeApiToAppId(new Api(config), appId); +} diff --git a/packages/rest-api-sdk/src/generated/.openapi-generator-ignore b/packages/rest-api-sdk/src/generated/.openapi-generator-ignore new file mode 100644 index 00000000..7484ee59 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/.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/packages/rest-api-sdk/src/generated/.openapi-generator/FILES b/packages/rest-api-sdk/src/generated/.openapi-generator/FILES new file mode 100644 index 00000000..f8105a66 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/.openapi-generator/FILES @@ -0,0 +1,36 @@ +.openapi-generator-ignore +apis/DefaultApi.ts +apis/index.ts +index.ts +models/App.ts +models/AppHeader.ts +models/AppHeaderCollection.ts +models/CreateFlag200Response.ts +models/CreateFlag200ResponseFlag.ts +models/CreateFlagRequest.ts +models/EntityFlag.ts +models/EntityFlagUpdate.ts +models/EntityFlagsResponse.ts +models/Environment.ts +models/EnvironmentHeader.ts +models/EnvironmentHeaderCollection.ts +models/EnvironmentHeaderSortByColumn.ts +models/EnvironmentSdkAccess.ts +models/ErrorResponse.ts +models/ErrorResponseError.ts +models/FlagHeader.ts +models/FlagHeaderCollection.ts +models/FlagKeyFormat.ts +models/FlagTargeting.ts +models/FlagValue.ts +models/FlagValueTargeting.ts +models/OrgHeader.ts +models/ReflagUserHeader.ts +models/SegmentHeader.ts +models/SegmentType.ts +models/SortOrder.ts +models/StageHeader.ts +models/UpdateEntityFlagsBody.ts +models/UpdateFlagRequest.ts +models/index.ts +runtime.ts diff --git a/packages/rest-api-sdk/src/generated/.openapi-generator/VERSION b/packages/rest-api-sdk/src/generated/.openapi-generator/VERSION new file mode 100644 index 00000000..3821090f --- /dev/null +++ b/packages/rest-api-sdk/src/generated/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.19.0 diff --git a/packages/rest-api-sdk/src/generated/apis/DefaultApi.ts b/packages/rest-api-sdk/src/generated/apis/DefaultApi.ts new file mode 100644 index 00000000..b2b1452e --- /dev/null +++ b/packages/rest-api-sdk/src/generated/apis/DefaultApi.ts @@ -0,0 +1,1066 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 * as runtime from '../runtime'; +import type { + App, + AppHeaderCollection, + CreateFlag200Response, + CreateFlagRequest, + EntityFlagsResponse, + Environment, + EnvironmentHeaderCollection, + EnvironmentHeaderSortByColumn, + ErrorResponse, + FlagHeaderCollection, + FlagTargeting, + SortOrder, + UpdateEntityFlagsBody, + UpdateFlagRequest, +} from '../models/index'; +import { + AppFromJSON, + AppToJSON, + AppHeaderCollectionFromJSON, + AppHeaderCollectionToJSON, + CreateFlag200ResponseFromJSON, + CreateFlag200ResponseToJSON, + CreateFlagRequestFromJSON, + CreateFlagRequestToJSON, + EntityFlagsResponseFromJSON, + EntityFlagsResponseToJSON, + EnvironmentFromJSON, + EnvironmentToJSON, + EnvironmentHeaderCollectionFromJSON, + EnvironmentHeaderCollectionToJSON, + EnvironmentHeaderSortByColumnFromJSON, + EnvironmentHeaderSortByColumnToJSON, + ErrorResponseFromJSON, + ErrorResponseToJSON, + FlagHeaderCollectionFromJSON, + FlagHeaderCollectionToJSON, + FlagTargetingFromJSON, + FlagTargetingToJSON, + SortOrderFromJSON, + SortOrderToJSON, + UpdateEntityFlagsBodyFromJSON, + UpdateEntityFlagsBodyToJSON, + UpdateFlagRequestFromJSON, + UpdateFlagRequestToJSON, +} from '../models/index'; + +export interface CreateFlagOperationRequest extends CreateFlagRequest { + appId: string; +} + +export interface GetAppRequest { + appId: string; +} + +export interface GetCompanyFlagsRequest { + appId: string; + envId: string; + companyId: string; +} + +export interface GetEnvironmentRequest { + appId: string; + envId: string; +} + +export interface GetFlagTargetingRequest { + appId: string; + flagKey: string; + envId: string; +} + +export interface GetUserFlagsRequest { + appId: string; + envId: string; + userId: string; +} + +export interface ListAppsRequest { + orgId?: string; +} + +export interface ListEnvironmentsRequest { + appId: string; + sortOrder?: SortOrder; + sortBy?: EnvironmentHeaderSortByColumn; +} + +export interface ListFlagsRequest { + appId: string; +} + +export interface UpdateCompanyFlagsRequest extends UpdateEntityFlagsBody { + appId: string; + envId: string; + companyId: string; +} + +export interface UpdateFlagOperationRequest extends UpdateFlagRequest { + appId: string; + flagId: string; +} + +export interface UpdateUserFlagsRequest extends UpdateEntityFlagsBody { + appId: string; + envId: string; + userId: string; +} + +/** + * DefaultApi - interface + * + * @export + * @interface DefaultApiInterface + */ +export interface DefaultApiInterface { + /** + * Create a new flag in the application. Returns the created flag details. + * @summary Create a flag + * @param {string} appId App identifier + * @param {string} key Key of the flag + * @param {string} name Name of the flag + * @param {string} [description] + * @param {string} [stageId] Stage ID of the flag + * @param {string} [ownerUserId] + * @param {boolean} [permanent] + * @param {boolean} [secret] Whether the flag is secret + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + createFlagRaw(requestParameters: CreateFlagOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Create a new flag in the application. Returns the created flag details. + * Create a flag + */ + createFlag(requestParameters: CreateFlagOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Retrieve a specific application by its identifier + * @summary Get details of an application + * @param {string} appId App identifier + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + getAppRaw(requestParameters: GetAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve a specific application by its identifier + * Get details of an application + */ + getApp(requestParameters: GetAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Retrieve all flags with their targeting status for a specific company + * @summary Get flags for a company + * @param {string} appId App identifier + * @param {string} envId Environment identifier + * @param {string} companyId Company ID within your application + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + getCompanyFlagsRaw(requestParameters: GetCompanyFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve all flags with their targeting status for a specific company + * Get flags for a company + */ + getCompanyFlags(requestParameters: GetCompanyFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Retrieve details for a specific environment + * @summary Get environment details + * @param {string} appId App identifier + * @param {string} envId Environment identifier + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + getEnvironmentRaw(requestParameters: GetEnvironmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve details for a specific environment + * Get environment details + */ + getEnvironment(requestParameters: GetEnvironmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Retrieve targeting for a flag in an environment + * @summary Get flag targeting for an environment + * @param {string} appId App identifier + * @param {string} flagKey Unique flag key + * @param {string} envId Environment identifier + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + getFlagTargetingRaw(requestParameters: GetFlagTargetingRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve targeting for a flag in an environment + * Get flag targeting for an environment + */ + getFlagTargeting(requestParameters: GetFlagTargetingRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Retrieve all flags with their targeting status for a specific user + * @summary Get flags for a user + * @param {string} appId App identifier + * @param {string} envId Environment identifier + * @param {string} userId User ID within your application + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + getUserFlagsRaw(requestParameters: GetUserFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve all flags with their targeting status for a specific user + * Get flags for a user + */ + getUserFlags(requestParameters: GetUserFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Retrieve all accessible applications + * @summary List of applications + * @param {string} [orgId] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + listAppsRaw(requestParameters: ListAppsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve all accessible applications + * List of applications + */ + listApps(requestParameters: ListAppsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Retrieve all environments for a specific application + * @summary List environments for application + * @param {string} appId App identifier + * @param {SortOrder} [sortOrder] Sort order applied to the sorting column + * @param {EnvironmentHeaderSortByColumn} [sortBy] The column to sort by + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + listEnvironmentsRaw(requestParameters: ListEnvironmentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve all environments for a specific application + * List environments for application + */ + listEnvironments(requestParameters: ListEnvironmentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Retrieve all flags for a specific application + * @summary List flags for application + * @param {string} appId App identifier + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + listFlagsRaw(requestParameters: ListFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Retrieve all flags for a specific application + * List flags for application + */ + listFlags(requestParameters: ListFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Update specific targeting for flags for a company in an environment + * @summary Update flag targeting for a company + * @param {string} appId App identifier + * @param {string} envId Environment identifier + * @param {string} companyId Company ID within your application + * @param {Array} updates List of flag updates to apply + * @param {string} [changeDescription] Description of the change for audit history + * @param {boolean} [notifications] Whether to send notifications about the change (default: true) + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + updateCompanyFlagsRaw(requestParameters: UpdateCompanyFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Update specific targeting for flags for a company in an environment + * Update flag targeting for a company + */ + updateCompanyFlags(requestParameters: UpdateCompanyFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Update an existing flag + * @summary Update a flag + * @param {string} appId App identifier + * @param {string} flagId Flag ID + * @param {string} [name] Name of the flag + * @param {string} [description] + * @param {string} [ownerUserId] + * @param {boolean} [permanent] + * @param {boolean} [secret] Whether the flag is secret + * @param {boolean} [isArchived] + * @param {string} [stageId] Stage ID of the flag + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + updateFlagRaw(requestParameters: UpdateFlagOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Update an existing flag + * Update a flag + */ + updateFlag(requestParameters: UpdateFlagOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + + /** + * Update specific targeting for flags for a user in an environment + * @summary Update flag targeting for a user + * @param {string} appId App identifier + * @param {string} envId Environment identifier + * @param {string} userId User ID within your application + * @param {Array} updates List of flag updates to apply + * @param {string} [changeDescription] Description of the change for audit history + * @param {boolean} [notifications] Whether to send notifications about the change (default: true) + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + updateUserFlagsRaw(requestParameters: UpdateUserFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; + + /** + * Update specific targeting for flags for a user in an environment + * Update flag targeting for a user + */ + updateUserFlags(requestParameters: UpdateUserFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; + +} + +/** + * + */ +export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { + + /** + * Create a new flag in the application. Returns the created flag details. + * Create a flag + */ + async createFlagRaw(requestParameters: CreateFlagOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling createFlag().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/flags`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + + const response = await this.request({ + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateFlagRequestToJSON({ + key: requestParameters['key'], + name: requestParameters['name'], + description: requestParameters['description'], + stageId: requestParameters['stageId'], + ownerUserId: requestParameters['ownerUserId'], + permanent: requestParameters['permanent'], + secret: requestParameters['secret'], + }), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateFlag200ResponseFromJSON(jsonValue)); + } + + /** + * Create a new flag in the application. Returns the created flag details. + * Create a flag + */ + async createFlag(requestParameters: CreateFlagOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createFlagRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve a specific application by its identifier + * Get details of an application + */ + async getAppRaw(requestParameters: GetAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling getApp().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AppFromJSON(jsonValue)); + } + + /** + * Retrieve a specific application by its identifier + * Get details of an application + */ + async getApp(requestParameters: GetAppRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getAppRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve all flags with their targeting status for a specific company + * Get flags for a company + */ + async getCompanyFlagsRaw(requestParameters: GetCompanyFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling getCompanyFlags().' + ); + } + + if (requestParameters['envId'] == null) { + throw new runtime.RequiredError( + 'envId', + 'Required parameter "envId" was null or undefined when calling getCompanyFlags().' + ); + } + + if (requestParameters['companyId'] == null) { + throw new runtime.RequiredError( + 'companyId', + 'Required parameter "companyId" was null or undefined when calling getCompanyFlags().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/envs/{envId}/companies/{companyId}/flags`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + urlPath = urlPath.replace(`{${"envId"}}`, encodeURIComponent(String(requestParameters['envId']))); + urlPath = urlPath.replace(`{${"companyId"}}`, encodeURIComponent(String(requestParameters['companyId']))); + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => EntityFlagsResponseFromJSON(jsonValue)); + } + + /** + * Retrieve all flags with their targeting status for a specific company + * Get flags for a company + */ + async getCompanyFlags(requestParameters: GetCompanyFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getCompanyFlagsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve details for a specific environment + * Get environment details + */ + async getEnvironmentRaw(requestParameters: GetEnvironmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling getEnvironment().' + ); + } + + if (requestParameters['envId'] == null) { + throw new runtime.RequiredError( + 'envId', + 'Required parameter "envId" was null or undefined when calling getEnvironment().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/environments/{envId}`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + urlPath = urlPath.replace(`{${"envId"}}`, encodeURIComponent(String(requestParameters['envId']))); + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => EnvironmentFromJSON(jsonValue)); + } + + /** + * Retrieve details for a specific environment + * Get environment details + */ + async getEnvironment(requestParameters: GetEnvironmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getEnvironmentRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve targeting for a flag in an environment + * Get flag targeting for an environment + */ + async getFlagTargetingRaw(requestParameters: GetFlagTargetingRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling getFlagTargeting().' + ); + } + + if (requestParameters['flagKey'] == null) { + throw new runtime.RequiredError( + 'flagKey', + 'Required parameter "flagKey" was null or undefined when calling getFlagTargeting().' + ); + } + + if (requestParameters['envId'] == null) { + throw new runtime.RequiredError( + 'envId', + 'Required parameter "envId" was null or undefined when calling getFlagTargeting().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/flags/{flagKey}/targeting/{envId}`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + urlPath = urlPath.replace(`{${"flagKey"}}`, encodeURIComponent(String(requestParameters['flagKey']))); + urlPath = urlPath.replace(`{${"envId"}}`, encodeURIComponent(String(requestParameters['envId']))); + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => FlagTargetingFromJSON(jsonValue)); + } + + /** + * Retrieve targeting for a flag in an environment + * Get flag targeting for an environment + */ + async getFlagTargeting(requestParameters: GetFlagTargetingRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getFlagTargetingRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve all flags with their targeting status for a specific user + * Get flags for a user + */ + async getUserFlagsRaw(requestParameters: GetUserFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling getUserFlags().' + ); + } + + if (requestParameters['envId'] == null) { + throw new runtime.RequiredError( + 'envId', + 'Required parameter "envId" was null or undefined when calling getUserFlags().' + ); + } + + if (requestParameters['userId'] == null) { + throw new runtime.RequiredError( + 'userId', + 'Required parameter "userId" was null or undefined when calling getUserFlags().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/envs/{envId}/users/{userId}/flags`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + urlPath = urlPath.replace(`{${"envId"}}`, encodeURIComponent(String(requestParameters['envId']))); + urlPath = urlPath.replace(`{${"userId"}}`, encodeURIComponent(String(requestParameters['userId']))); + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => EntityFlagsResponseFromJSON(jsonValue)); + } + + /** + * Retrieve all flags with their targeting status for a specific user + * Get flags for a user + */ + async getUserFlags(requestParameters: GetUserFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getUserFlagsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve all accessible applications + * List of applications + */ + async listAppsRaw(requestParameters: ListAppsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters['orgId'] != null) { + queryParameters['orgId'] = requestParameters['orgId']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps`; + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AppHeaderCollectionFromJSON(jsonValue)); + } + + /** + * Retrieve all accessible applications + * List of applications + */ + async listApps(requestParameters: ListAppsRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.listAppsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve all environments for a specific application + * List environments for application + */ + async listEnvironmentsRaw(requestParameters: ListEnvironmentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling listEnvironments().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['sortOrder'] != null) { + queryParameters['sortOrder'] = requestParameters['sortOrder']; + } + + if (requestParameters['sortBy'] != null) { + queryParameters['sortBy'] = requestParameters['sortBy']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/environments`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => EnvironmentHeaderCollectionFromJSON(jsonValue)); + } + + /** + * Retrieve all environments for a specific application + * List environments for application + */ + async listEnvironments(requestParameters: ListEnvironmentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.listEnvironmentsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Retrieve all flags for a specific application + * List flags for application + */ + async listFlagsRaw(requestParameters: ListFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling listFlags().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/flags`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + + const response = await this.request({ + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => FlagHeaderCollectionFromJSON(jsonValue)); + } + + /** + * Retrieve all flags for a specific application + * List flags for application + */ + async listFlags(requestParameters: ListFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.listFlagsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Update specific targeting for flags for a company in an environment + * Update flag targeting for a company + */ + async updateCompanyFlagsRaw(requestParameters: UpdateCompanyFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling updateCompanyFlags().' + ); + } + + if (requestParameters['envId'] == null) { + throw new runtime.RequiredError( + 'envId', + 'Required parameter "envId" was null or undefined when calling updateCompanyFlags().' + ); + } + + if (requestParameters['companyId'] == null) { + throw new runtime.RequiredError( + 'companyId', + 'Required parameter "companyId" was null or undefined when calling updateCompanyFlags().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/envs/{envId}/companies/{companyId}/flags`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + urlPath = urlPath.replace(`{${"envId"}}`, encodeURIComponent(String(requestParameters['envId']))); + urlPath = urlPath.replace(`{${"companyId"}}`, encodeURIComponent(String(requestParameters['companyId']))); + + const response = await this.request({ + path: urlPath, + method: 'PATCH', + headers: headerParameters, + query: queryParameters, + body: UpdateEntityFlagsBodyToJSON({ + updates: requestParameters['updates'], + changeDescription: requestParameters['changeDescription'], + notifications: requestParameters['notifications'], + }), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => EntityFlagsResponseFromJSON(jsonValue)); + } + + /** + * Update specific targeting for flags for a company in an environment + * Update flag targeting for a company + */ + async updateCompanyFlags(requestParameters: UpdateCompanyFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateCompanyFlagsRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Update an existing flag + * Update a flag + */ + async updateFlagRaw(requestParameters: UpdateFlagOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling updateFlag().' + ); + } + + if (requestParameters['flagId'] == null) { + throw new runtime.RequiredError( + 'flagId', + 'Required parameter "flagId" was null or undefined when calling updateFlag().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/flags/{flagId}`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + urlPath = urlPath.replace(`{${"flagId"}}`, encodeURIComponent(String(requestParameters['flagId']))); + + const response = await this.request({ + path: urlPath, + method: 'PATCH', + headers: headerParameters, + query: queryParameters, + body: UpdateFlagRequestToJSON({ + name: requestParameters['name'], + description: requestParameters['description'], + ownerUserId: requestParameters['ownerUserId'], + permanent: requestParameters['permanent'], + secret: requestParameters['secret'], + isArchived: requestParameters['isArchived'], + stageId: requestParameters['stageId'], + }), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateFlag200ResponseFromJSON(jsonValue)); + } + + /** + * Update an existing flag + * Update a flag + */ + async updateFlag(requestParameters: UpdateFlagOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateFlagRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + * Update specific targeting for flags for a user in an environment + * Update flag targeting for a user + */ + async updateUserFlagsRaw(requestParameters: UpdateUserFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters['appId'] == null) { + throw new runtime.RequiredError( + 'appId', + 'Required parameter "appId" was null or undefined when calling updateUserFlags().' + ); + } + + if (requestParameters['envId'] == null) { + throw new runtime.RequiredError( + 'envId', + 'Required parameter "envId" was null or undefined when calling updateUserFlags().' + ); + } + + if (requestParameters['userId'] == null) { + throw new runtime.RequiredError( + 'userId', + 'Required parameter "userId" was null or undefined when calling updateUserFlags().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + const token = this.configuration.accessToken; + const tokenString = await token("APIKey", []); + + if (tokenString) { + headerParameters["Authorization"] = `Bearer ${tokenString}`; + } + } + + let urlPath = `/apps/{appId}/envs/{envId}/users/{userId}/flags`; + urlPath = urlPath.replace(`{${"appId"}}`, encodeURIComponent(String(requestParameters['appId']))); + urlPath = urlPath.replace(`{${"envId"}}`, encodeURIComponent(String(requestParameters['envId']))); + urlPath = urlPath.replace(`{${"userId"}}`, encodeURIComponent(String(requestParameters['userId']))); + + const response = await this.request({ + path: urlPath, + method: 'PATCH', + headers: headerParameters, + query: queryParameters, + body: UpdateEntityFlagsBodyToJSON({ + updates: requestParameters['updates'], + changeDescription: requestParameters['changeDescription'], + notifications: requestParameters['notifications'], + }), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => EntityFlagsResponseFromJSON(jsonValue)); + } + + /** + * Update specific targeting for flags for a user in an environment + * Update flag targeting for a user + */ + async updateUserFlags(requestParameters: UpdateUserFlagsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateUserFlagsRaw(requestParameters, initOverrides); + return await response.value(); + } + +} diff --git a/packages/rest-api-sdk/src/generated/apis/index.ts b/packages/rest-api-sdk/src/generated/apis/index.ts new file mode 100644 index 00000000..69c44c00 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/apis/index.ts @@ -0,0 +1,3 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './DefaultApi'; diff --git a/packages/rest-api-sdk/src/generated/index.ts b/packages/rest-api-sdk/src/generated/index.ts new file mode 100644 index 00000000..bebe8bbb --- /dev/null +++ b/packages/rest-api-sdk/src/generated/index.ts @@ -0,0 +1,5 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './runtime'; +export * from './apis/index'; +export * from './models/index'; diff --git a/packages/rest-api-sdk/src/generated/models/App.ts b/packages/rest-api-sdk/src/generated/models/App.ts new file mode 100644 index 00000000..d928c112 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/App.ts @@ -0,0 +1,167 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { SegmentHeader } from './SegmentHeader'; +import { + SegmentHeaderFromJSON, + SegmentHeaderFromJSONTyped, + SegmentHeaderToJSON, + SegmentHeaderToJSONTyped, +} from './SegmentHeader'; +import type { StageHeader } from './StageHeader'; +import { + StageHeaderFromJSON, + StageHeaderFromJSONTyped, + StageHeaderToJSON, + StageHeaderToJSONTyped, +} from './StageHeader'; +import type { Environment } from './Environment'; +import { + EnvironmentFromJSON, + EnvironmentFromJSONTyped, + EnvironmentToJSON, + EnvironmentToJSONTyped, +} from './Environment'; +import type { FlagKeyFormat } from './FlagKeyFormat'; +import { + FlagKeyFormatFromJSON, + FlagKeyFormatFromJSONTyped, + FlagKeyFormatToJSON, + FlagKeyFormatToJSONTyped, +} from './FlagKeyFormat'; +import type { OrgHeader } from './OrgHeader'; +import { + OrgHeaderFromJSON, + OrgHeaderFromJSONTyped, + OrgHeaderToJSON, + OrgHeaderToJSONTyped, +} from './OrgHeader'; + +/** + * App information with related collections + * @export + * @interface App + */ +export interface App { + /** + * + * @type {OrgHeader} + * @memberof App + */ + org: OrgHeader; + /** + * App identifier + * @type {string} + * @memberof App + */ + id: string; + /** + * App name + * @type {string} + * @memberof App + */ + name: string; + /** + * Whether the app is a demo app + * @type {boolean} + * @memberof App + */ + demo: boolean; + /** + * + * @type {FlagKeyFormat} + * @memberof App + */ + flagKeyFormat: FlagKeyFormat; + /** + * Environments within the app + * @type {Array} + * @memberof App + */ + environments: Array; + /** + * Stages within the app + * @type {Array} + * @memberof App + */ + stages: Array; + /** + * Segments within the app + * @type {Array} + * @memberof App + */ + segments: Array; +} + + + +/** + * Check if a given object implements the App interface. + */ +export function instanceOfApp(value: object): value is App { + if (!('org' in value) || value['org'] === undefined) return false; + if (!('id' in value) || value['id'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('demo' in value) || value['demo'] === undefined) return false; + if (!('flagKeyFormat' in value) || value['flagKeyFormat'] === undefined) return false; + if (!('environments' in value) || value['environments'] === undefined) return false; + if (!('stages' in value) || value['stages'] === undefined) return false; + if (!('segments' in value) || value['segments'] === undefined) return false; + return true; +} + +export function AppFromJSON(json: any): App { + return AppFromJSONTyped(json, false); +} + +export function AppFromJSONTyped(json: any, ignoreDiscriminator: boolean): App { + if (json == null) { + return json; + } + return { + + 'org': OrgHeaderFromJSON(json['org']), + 'id': json['id'], + 'name': json['name'], + 'demo': json['demo'], + 'flagKeyFormat': FlagKeyFormatFromJSON(json['flagKeyFormat']), + 'environments': ((json['environments'] as Array).map(EnvironmentFromJSON)), + 'stages': ((json['stages'] as Array).map(StageHeaderFromJSON)), + 'segments': ((json['segments'] as Array).map(SegmentHeaderFromJSON)), + }; +} + +export function AppToJSON(json: any): App { + return AppToJSONTyped(json, false); +} + +export function AppToJSONTyped(value?: App | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'org': OrgHeaderToJSON(value['org']), + 'id': value['id'], + 'name': value['name'], + 'demo': value['demo'], + 'flagKeyFormat': FlagKeyFormatToJSON(value['flagKeyFormat']), + 'environments': ((value['environments'] as Array).map(EnvironmentToJSON)), + 'stages': ((value['stages'] as Array).map(StageHeaderToJSON)), + 'segments': ((value['segments'] as Array).map(SegmentHeaderToJSON)), + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/AppHeader.ts b/packages/rest-api-sdk/src/generated/models/AppHeader.ts new file mode 100644 index 00000000..cbff7d45 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/AppHeader.ts @@ -0,0 +1,135 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { EnvironmentHeader } from './EnvironmentHeader'; +import { + EnvironmentHeaderFromJSON, + EnvironmentHeaderFromJSONTyped, + EnvironmentHeaderToJSON, + EnvironmentHeaderToJSONTyped, +} from './EnvironmentHeader'; +import type { FlagKeyFormat } from './FlagKeyFormat'; +import { + FlagKeyFormatFromJSON, + FlagKeyFormatFromJSONTyped, + FlagKeyFormatToJSON, + FlagKeyFormatToJSONTyped, +} from './FlagKeyFormat'; +import type { OrgHeader } from './OrgHeader'; +import { + OrgHeaderFromJSON, + OrgHeaderFromJSONTyped, + OrgHeaderToJSON, + OrgHeaderToJSONTyped, +} from './OrgHeader'; + +/** + * Basic app information + * @export + * @interface AppHeader + */ +export interface AppHeader { + /** + * + * @type {OrgHeader} + * @memberof AppHeader + */ + org: OrgHeader; + /** + * App identifier + * @type {string} + * @memberof AppHeader + */ + id: string; + /** + * App name + * @type {string} + * @memberof AppHeader + */ + name: string; + /** + * Whether the app is a demo app + * @type {boolean} + * @memberof AppHeader + */ + demo: boolean; + /** + * + * @type {FlagKeyFormat} + * @memberof AppHeader + */ + flagKeyFormat: FlagKeyFormat; + /** + * Environments within the app + * @type {Array} + * @memberof AppHeader + */ + environments: Array; +} + + + +/** + * Check if a given object implements the AppHeader interface. + */ +export function instanceOfAppHeader(value: object): value is AppHeader { + if (!('org' in value) || value['org'] === undefined) return false; + if (!('id' in value) || value['id'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('demo' in value) || value['demo'] === undefined) return false; + if (!('flagKeyFormat' in value) || value['flagKeyFormat'] === undefined) return false; + if (!('environments' in value) || value['environments'] === undefined) return false; + return true; +} + +export function AppHeaderFromJSON(json: any): AppHeader { + return AppHeaderFromJSONTyped(json, false); +} + +export function AppHeaderFromJSONTyped(json: any, ignoreDiscriminator: boolean): AppHeader { + if (json == null) { + return json; + } + return { + + 'org': OrgHeaderFromJSON(json['org']), + 'id': json['id'], + 'name': json['name'], + 'demo': json['demo'], + 'flagKeyFormat': FlagKeyFormatFromJSON(json['flagKeyFormat']), + 'environments': ((json['environments'] as Array).map(EnvironmentHeaderFromJSON)), + }; +} + +export function AppHeaderToJSON(json: any): AppHeader { + return AppHeaderToJSONTyped(json, false); +} + +export function AppHeaderToJSONTyped(value?: AppHeader | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'org': OrgHeaderToJSON(value['org']), + 'id': value['id'], + 'name': value['name'], + 'demo': value['demo'], + 'flagKeyFormat': FlagKeyFormatToJSON(value['flagKeyFormat']), + 'environments': ((value['environments'] as Array).map(EnvironmentHeaderToJSON)), + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/AppHeaderCollection.ts b/packages/rest-api-sdk/src/generated/models/AppHeaderCollection.ts new file mode 100644 index 00000000..56a0b502 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/AppHeaderCollection.ts @@ -0,0 +1,74 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { AppHeader } from './AppHeader'; +import { + AppHeaderFromJSON, + AppHeaderFromJSONTyped, + AppHeaderToJSON, + AppHeaderToJSONTyped, +} from './AppHeader'; + +/** + * Collection of Basic app information + * @export + * @interface AppHeaderCollection + */ +export interface AppHeaderCollection { + /** + * The individual items in the collection + * @type {Array} + * @memberof AppHeaderCollection + */ + data: Array; +} + +/** + * Check if a given object implements the AppHeaderCollection interface. + */ +export function instanceOfAppHeaderCollection(value: object): value is AppHeaderCollection { + if (!('data' in value) || value['data'] === undefined) return false; + return true; +} + +export function AppHeaderCollectionFromJSON(json: any): AppHeaderCollection { + return AppHeaderCollectionFromJSONTyped(json, false); +} + +export function AppHeaderCollectionFromJSONTyped(json: any, ignoreDiscriminator: boolean): AppHeaderCollection { + if (json == null) { + return json; + } + return { + + 'data': ((json['data'] as Array).map(AppHeaderFromJSON)), + }; +} + +export function AppHeaderCollectionToJSON(json: any): AppHeaderCollection { + return AppHeaderCollectionToJSONTyped(json, false); +} + +export function AppHeaderCollectionToJSONTyped(value?: AppHeaderCollection | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'data': ((value['data'] as Array).map(AppHeaderToJSON)), + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/CreateFlag200Response.ts b/packages/rest-api-sdk/src/generated/models/CreateFlag200Response.ts new file mode 100644 index 00000000..e0f4f943 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/CreateFlag200Response.ts @@ -0,0 +1,74 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { CreateFlag200ResponseFlag } from './CreateFlag200ResponseFlag'; +import { + CreateFlag200ResponseFlagFromJSON, + CreateFlag200ResponseFlagFromJSONTyped, + CreateFlag200ResponseFlagToJSON, + CreateFlag200ResponseFlagToJSONTyped, +} from './CreateFlag200ResponseFlag'; + +/** + * + * @export + * @interface CreateFlag200Response + */ +export interface CreateFlag200Response { + /** + * + * @type {CreateFlag200ResponseFlag} + * @memberof CreateFlag200Response + */ + flag: CreateFlag200ResponseFlag; +} + +/** + * Check if a given object implements the CreateFlag200Response interface. + */ +export function instanceOfCreateFlag200Response(value: object): value is CreateFlag200Response { + if (!('flag' in value) || value['flag'] === undefined) return false; + return true; +} + +export function CreateFlag200ResponseFromJSON(json: any): CreateFlag200Response { + return CreateFlag200ResponseFromJSONTyped(json, false); +} + +export function CreateFlag200ResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateFlag200Response { + if (json == null) { + return json; + } + return { + + 'flag': CreateFlag200ResponseFlagFromJSON(json['flag']), + }; +} + +export function CreateFlag200ResponseToJSON(json: any): CreateFlag200Response { + return CreateFlag200ResponseToJSONTyped(json, false); +} + +export function CreateFlag200ResponseToJSONTyped(value?: CreateFlag200Response | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'flag': CreateFlag200ResponseFlagToJSON(value['flag']), + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/CreateFlag200ResponseFlag.ts b/packages/rest-api-sdk/src/generated/models/CreateFlag200ResponseFlag.ts new file mode 100644 index 00000000..5475f725 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/CreateFlag200ResponseFlag.ts @@ -0,0 +1,190 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { StageHeader } from './StageHeader'; +import { + StageHeaderFromJSON, + StageHeaderFromJSONTyped, + StageHeaderToJSON, + StageHeaderToJSONTyped, +} from './StageHeader'; +import type { ReflagUserHeader } from './ReflagUserHeader'; +import { + ReflagUserHeaderFromJSON, + ReflagUserHeaderFromJSONTyped, + ReflagUserHeaderToJSON, + ReflagUserHeaderToJSONTyped, +} from './ReflagUserHeader'; + +/** + * + * @export + * @interface CreateFlag200ResponseFlag + */ +export interface CreateFlag200ResponseFlag { + /** + * Flag ID + * @type {string} + * @memberof CreateFlag200ResponseFlag + */ + id: string; + /** + * Unique flag key + * @type {string} + * @memberof CreateFlag200ResponseFlag + */ + key: string; + /** + * Flag name + * @type {string} + * @memberof CreateFlag200ResponseFlag + */ + name: string; + /** + * Flag description + * @type {string} + * @memberof CreateFlag200ResponseFlag + */ + description?: string; + /** + * + * @type {StageHeader} + * @memberof CreateFlag200ResponseFlag + */ + stage?: StageHeader; + /** + * + * @type {ReflagUserHeader} + * @memberof CreateFlag200ResponseFlag + */ + owner?: ReflagUserHeader; + /** + * Whether the flag is archived + * @type {boolean} + * @memberof CreateFlag200ResponseFlag + */ + archived: boolean; + /** + * Whether the flag is stale + * @type {boolean} + * @memberof CreateFlag200ResponseFlag + */ + stale: boolean; + /** + * Whether the flag is permanent + * @type {boolean} + * @memberof CreateFlag200ResponseFlag + */ + permanent: boolean; + /** + * Timestamp when the flag was created + * @type {string} + * @memberof CreateFlag200ResponseFlag + */ + createdAt?: string; + /** + * Timestamp when the flag was last checked + * @type {string} + * @memberof CreateFlag200ResponseFlag + */ + lastCheckAt?: string; + /** + * Timestamp when the flag was last tracked + * @type {string} + * @memberof CreateFlag200ResponseFlag + */ + lastTrackAt?: string; + /** + * Timestamp when the flag was rolled out to everyone + * @type {string} + * @memberof CreateFlag200ResponseFlag + */ + rolledOutToEveryoneAt?: string; + /** + * Parent flag ID + * @type {string} + * @memberof CreateFlag200ResponseFlag + */ + parentFlagId?: string; +} + +/** + * Check if a given object implements the CreateFlag200ResponseFlag interface. + */ +export function instanceOfCreateFlag200ResponseFlag(value: object): value is CreateFlag200ResponseFlag { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('key' in value) || value['key'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('archived' in value) || value['archived'] === undefined) return false; + if (!('stale' in value) || value['stale'] === undefined) return false; + if (!('permanent' in value) || value['permanent'] === undefined) return false; + return true; +} + +export function CreateFlag200ResponseFlagFromJSON(json: any): CreateFlag200ResponseFlag { + return CreateFlag200ResponseFlagFromJSONTyped(json, false); +} + +export function CreateFlag200ResponseFlagFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateFlag200ResponseFlag { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'key': json['key'], + 'name': json['name'], + 'description': json['description'] == null ? undefined : json['description'], + 'stage': json['stage'] == null ? undefined : StageHeaderFromJSON(json['stage']), + 'owner': json['owner'] == null ? undefined : ReflagUserHeaderFromJSON(json['owner']), + 'archived': json['archived'], + 'stale': json['stale'], + 'permanent': json['permanent'], + 'createdAt': json['createdAt'] == null ? undefined : json['createdAt'], + 'lastCheckAt': json['lastCheckAt'] == null ? undefined : json['lastCheckAt'], + 'lastTrackAt': json['lastTrackAt'] == null ? undefined : json['lastTrackAt'], + 'rolledOutToEveryoneAt': json['rolledOutToEveryoneAt'] == null ? undefined : json['rolledOutToEveryoneAt'], + 'parentFlagId': json['parentFlagId'] == null ? undefined : json['parentFlagId'], + }; +} + +export function CreateFlag200ResponseFlagToJSON(json: any): CreateFlag200ResponseFlag { + return CreateFlag200ResponseFlagToJSONTyped(json, false); +} + +export function CreateFlag200ResponseFlagToJSONTyped(value?: CreateFlag200ResponseFlag | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'key': value['key'], + 'name': value['name'], + 'description': value['description'], + 'stage': StageHeaderToJSON(value['stage']), + 'owner': ReflagUserHeaderToJSON(value['owner']), + 'archived': value['archived'], + 'stale': value['stale'], + 'permanent': value['permanent'], + 'createdAt': value['createdAt'], + 'lastCheckAt': value['lastCheckAt'], + 'lastTrackAt': value['lastTrackAt'], + 'rolledOutToEveryoneAt': value['rolledOutToEveryoneAt'], + 'parentFlagId': value['parentFlagId'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/CreateFlagRequest.ts b/packages/rest-api-sdk/src/generated/models/CreateFlagRequest.ts new file mode 100644 index 00000000..9b58ee5a --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/CreateFlagRequest.ts @@ -0,0 +1,115 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateFlagRequest + */ +export interface CreateFlagRequest { + /** + * Key of the flag + * @type {string} + * @memberof CreateFlagRequest + */ + key: string; + /** + * Name of the flag + * @type {string} + * @memberof CreateFlagRequest + */ + name: string; + /** + * + * @type {string} + * @memberof CreateFlagRequest + */ + description?: string | null; + /** + * Stage ID of the flag + * @type {string} + * @memberof CreateFlagRequest + */ + stageId?: string; + /** + * + * @type {string} + * @memberof CreateFlagRequest + */ + ownerUserId?: string | null; + /** + * + * @type {boolean} + * @memberof CreateFlagRequest + */ + permanent?: boolean; + /** + * Whether the flag is secret + * @type {boolean} + * @memberof CreateFlagRequest + */ + secret?: boolean; +} + +/** + * Check if a given object implements the CreateFlagRequest interface. + */ +export function instanceOfCreateFlagRequest(value: object): value is CreateFlagRequest { + if (!('key' in value) || value['key'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + return true; +} + +export function CreateFlagRequestFromJSON(json: any): CreateFlagRequest { + return CreateFlagRequestFromJSONTyped(json, false); +} + +export function CreateFlagRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateFlagRequest { + if (json == null) { + return json; + } + return { + + 'key': json['key'], + 'name': json['name'], + 'description': json['description'] == null ? undefined : json['description'], + 'stageId': json['stageId'] == null ? undefined : json['stageId'], + 'ownerUserId': json['ownerUserId'] == null ? undefined : json['ownerUserId'], + 'permanent': json['permanent'] == null ? undefined : json['permanent'], + 'secret': json['secret'] == null ? undefined : json['secret'], + }; +} + +export function CreateFlagRequestToJSON(json: any): CreateFlagRequest { + return CreateFlagRequestToJSONTyped(json, false); +} + +export function CreateFlagRequestToJSONTyped(value?: CreateFlagRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'key': value['key'], + 'name': value['name'], + 'description': value['description'], + 'stageId': value['stageId'], + 'ownerUserId': value['ownerUserId'], + 'permanent': value['permanent'], + 'secret': value['secret'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/EntityFlag.ts b/packages/rest-api-sdk/src/generated/models/EntityFlag.ts new file mode 100644 index 00000000..fc2aede7 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/EntityFlag.ts @@ -0,0 +1,174 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * Flag information with enabled status for an entity + * @export + * @interface EntityFlag + */ +export interface EntityFlag { + /** + * Flag ID + * @type {string} + * @memberof EntityFlag + */ + id: string; + /** + * Unique flag key + * @type {string} + * @memberof EntityFlag + */ + key: string; + /** + * Flag name + * @type {string} + * @memberof EntityFlag + */ + name: string; + /** + * Timestamp when the flag was created + * @type {string} + * @memberof EntityFlag + */ + createdAt: string; + /** + * Whether the flag is enabled for this entity + * @type {boolean} + * @memberof EntityFlag + */ + value: boolean; + /** + * + * @type {boolean} + * @memberof EntityFlag + */ + specificTargetValue: boolean | null; + /** + * + * @type {string} + * @memberof EntityFlag + */ + firstExposureAt: string | null; + /** + * + * @type {string} + * @memberof EntityFlag + */ + lastExposureAt: string | null; + /** + * + * @type {string} + * @memberof EntityFlag + */ + lastCheckAt: string | null; + /** + * Number of times the entity was exposed to this flag + * @type {number} + * @memberof EntityFlag + */ + exposureCount: number; + /** + * + * @type {string} + * @memberof EntityFlag + */ + firstTrackAt: string | null; + /** + * + * @type {string} + * @memberof EntityFlag + */ + lastTrackAt: string | null; + /** + * Number of track events for this flag + * @type {number} + * @memberof EntityFlag + */ + trackCount: number; +} + +/** + * Check if a given object implements the EntityFlag interface. + */ +export function instanceOfEntityFlag(value: object): value is EntityFlag { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('key' in value) || value['key'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('createdAt' in value) || value['createdAt'] === undefined) return false; + if (!('value' in value) || value['value'] === undefined) return false; + if (!('specificTargetValue' in value) || value['specificTargetValue'] === undefined) return false; + if (!('firstExposureAt' in value) || value['firstExposureAt'] === undefined) return false; + if (!('lastExposureAt' in value) || value['lastExposureAt'] === undefined) return false; + if (!('lastCheckAt' in value) || value['lastCheckAt'] === undefined) return false; + if (!('exposureCount' in value) || value['exposureCount'] === undefined) return false; + if (!('firstTrackAt' in value) || value['firstTrackAt'] === undefined) return false; + if (!('lastTrackAt' in value) || value['lastTrackAt'] === undefined) return false; + if (!('trackCount' in value) || value['trackCount'] === undefined) return false; + return true; +} + +export function EntityFlagFromJSON(json: any): EntityFlag { + return EntityFlagFromJSONTyped(json, false); +} + +export function EntityFlagFromJSONTyped(json: any, ignoreDiscriminator: boolean): EntityFlag { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'key': json['key'], + 'name': json['name'], + 'createdAt': json['createdAt'], + 'value': json['value'], + 'specificTargetValue': json['specificTargetValue'], + 'firstExposureAt': json['firstExposureAt'], + 'lastExposureAt': json['lastExposureAt'], + 'lastCheckAt': json['lastCheckAt'], + 'exposureCount': json['exposureCount'], + 'firstTrackAt': json['firstTrackAt'], + 'lastTrackAt': json['lastTrackAt'], + 'trackCount': json['trackCount'], + }; +} + +export function EntityFlagToJSON(json: any): EntityFlag { + return EntityFlagToJSONTyped(json, false); +} + +export function EntityFlagToJSONTyped(value?: EntityFlag | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'key': value['key'], + 'name': value['name'], + 'createdAt': value['createdAt'], + 'value': value['value'], + 'specificTargetValue': value['specificTargetValue'], + 'firstExposureAt': value['firstExposureAt'], + 'lastExposureAt': value['lastExposureAt'], + 'lastCheckAt': value['lastCheckAt'], + 'exposureCount': value['exposureCount'], + 'firstTrackAt': value['firstTrackAt'], + 'lastTrackAt': value['lastTrackAt'], + 'trackCount': value['trackCount'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/EntityFlagUpdate.ts b/packages/rest-api-sdk/src/generated/models/EntityFlagUpdate.ts new file mode 100644 index 00000000..7c84b1d6 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/EntityFlagUpdate.ts @@ -0,0 +1,85 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * Update for a single flag's explicit targeting override + * @export + * @interface EntityFlagUpdate + */ +export interface EntityFlagUpdate { + /** + * Unique flag key + * @type {string} + * @memberof EntityFlagUpdate + */ + flagKey: string; + /** + * + * @type {boolean} + * @memberof EntityFlagUpdate + */ + specificTargetValue: EntityFlagUpdateSpecificTargetValueEnum | null; +} + + +/** + * @export + */ +export const EntityFlagUpdateSpecificTargetValueEnum = { + True: true +} as const; +export type EntityFlagUpdateSpecificTargetValueEnum = typeof EntityFlagUpdateSpecificTargetValueEnum[keyof typeof EntityFlagUpdateSpecificTargetValueEnum]; + + +/** + * Check if a given object implements the EntityFlagUpdate interface. + */ +export function instanceOfEntityFlagUpdate(value: object): value is EntityFlagUpdate { + if (!('flagKey' in value) || value['flagKey'] === undefined) return false; + if (!('specificTargetValue' in value) || value['specificTargetValue'] === undefined) return false; + return true; +} + +export function EntityFlagUpdateFromJSON(json: any): EntityFlagUpdate { + return EntityFlagUpdateFromJSONTyped(json, false); +} + +export function EntityFlagUpdateFromJSONTyped(json: any, ignoreDiscriminator: boolean): EntityFlagUpdate { + if (json == null) { + return json; + } + return { + + 'flagKey': json['flagKey'], + 'specificTargetValue': json['specificTargetValue'], + }; +} + +export function EntityFlagUpdateToJSON(json: any): EntityFlagUpdate { + return EntityFlagUpdateToJSONTyped(json, false); +} + +export function EntityFlagUpdateToJSONTyped(value?: EntityFlagUpdate | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'flagKey': value['flagKey'], + 'specificTargetValue': value['specificTargetValue'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/EntityFlagsResponse.ts b/packages/rest-api-sdk/src/generated/models/EntityFlagsResponse.ts new file mode 100644 index 00000000..b7c1fd11 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/EntityFlagsResponse.ts @@ -0,0 +1,101 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { EntityFlag } from './EntityFlag'; +import { + EntityFlagFromJSON, + EntityFlagFromJSONTyped, + EntityFlagToJSON, + EntityFlagToJSONTyped, +} from './EntityFlag'; + +/** + * Response containing flags for an entity + * @export + * @interface EntityFlagsResponse + */ +export interface EntityFlagsResponse { + /** + * List of flags with their enabled status + * @type {Array} + * @memberof EntityFlagsResponse + */ + data: Array; + /** + * Total number of flags + * @type {number} + * @memberof EntityFlagsResponse + */ + totalCount: number; + /** + * Page size + * @type {number} + * @memberof EntityFlagsResponse + */ + pageSize: number; + /** + * Page index + * @type {number} + * @memberof EntityFlagsResponse + */ + pageIndex: number; +} + +/** + * Check if a given object implements the EntityFlagsResponse interface. + */ +export function instanceOfEntityFlagsResponse(value: object): value is EntityFlagsResponse { + if (!('data' in value) || value['data'] === undefined) return false; + if (!('totalCount' in value) || value['totalCount'] === undefined) return false; + if (!('pageSize' in value) || value['pageSize'] === undefined) return false; + if (!('pageIndex' in value) || value['pageIndex'] === undefined) return false; + return true; +} + +export function EntityFlagsResponseFromJSON(json: any): EntityFlagsResponse { + return EntityFlagsResponseFromJSONTyped(json, false); +} + +export function EntityFlagsResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): EntityFlagsResponse { + if (json == null) { + return json; + } + return { + + 'data': ((json['data'] as Array).map(EntityFlagFromJSON)), + 'totalCount': json['totalCount'], + 'pageSize': json['pageSize'], + 'pageIndex': json['pageIndex'], + }; +} + +export function EntityFlagsResponseToJSON(json: any): EntityFlagsResponse { + return EntityFlagsResponseToJSONTyped(json, false); +} + +export function EntityFlagsResponseToJSONTyped(value?: EntityFlagsResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'data': ((value['data'] as Array).map(EntityFlagToJSON)), + 'totalCount': value['totalCount'], + 'pageSize': value['pageSize'], + 'pageIndex': value['pageIndex'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/Environment.ts b/packages/rest-api-sdk/src/generated/models/Environment.ts new file mode 100644 index 00000000..53f93a66 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/Environment.ts @@ -0,0 +1,110 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { EnvironmentSdkAccess } from './EnvironmentSdkAccess'; +import { + EnvironmentSdkAccessFromJSON, + EnvironmentSdkAccessFromJSONTyped, + EnvironmentSdkAccessToJSON, + EnvironmentSdkAccessToJSONTyped, +} from './EnvironmentSdkAccess'; + +/** + * Environment details + * @export + * @interface Environment + */ +export interface Environment { + /** + * Environment identifier + * @type {string} + * @memberof Environment + */ + id: string; + /** + * Environment name + * @type {string} + * @memberof Environment + */ + name: string; + /** + * Whether the environment is a production environment + * @type {boolean} + * @memberof Environment + */ + isProduction: boolean; + /** + * Environment order in the app (zero-indexed) + * @type {number} + * @memberof Environment + */ + order: number; + /** + * + * @type {EnvironmentSdkAccess} + * @memberof Environment + */ + sdkAccess: EnvironmentSdkAccess; +} + +/** + * Check if a given object implements the Environment interface. + */ +export function instanceOfEnvironment(value: object): value is Environment { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('isProduction' in value) || value['isProduction'] === undefined) return false; + if (!('order' in value) || value['order'] === undefined) return false; + if (!('sdkAccess' in value) || value['sdkAccess'] === undefined) return false; + return true; +} + +export function EnvironmentFromJSON(json: any): Environment { + return EnvironmentFromJSONTyped(json, false); +} + +export function EnvironmentFromJSONTyped(json: any, ignoreDiscriminator: boolean): Environment { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'name': json['name'], + 'isProduction': json['isProduction'], + 'order': json['order'], + 'sdkAccess': EnvironmentSdkAccessFromJSON(json['sdkAccess']), + }; +} + +export function EnvironmentToJSON(json: any): Environment { + return EnvironmentToJSONTyped(json, false); +} + +export function EnvironmentToJSONTyped(value?: Environment | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'name': value['name'], + 'isProduction': value['isProduction'], + 'order': value['order'], + 'sdkAccess': EnvironmentSdkAccessToJSON(value['sdkAccess']), + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/EnvironmentHeader.ts b/packages/rest-api-sdk/src/generated/models/EnvironmentHeader.ts new file mode 100644 index 00000000..f790394b --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/EnvironmentHeader.ts @@ -0,0 +1,93 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * Basic environment information + * @export + * @interface EnvironmentHeader + */ +export interface EnvironmentHeader { + /** + * Environment identifier + * @type {string} + * @memberof EnvironmentHeader + */ + id: string; + /** + * Environment name + * @type {string} + * @memberof EnvironmentHeader + */ + name: string; + /** + * Whether the environment is a production environment + * @type {boolean} + * @memberof EnvironmentHeader + */ + isProduction: boolean; + /** + * Environment order in the app (zero-indexed) + * @type {number} + * @memberof EnvironmentHeader + */ + order: number; +} + +/** + * Check if a given object implements the EnvironmentHeader interface. + */ +export function instanceOfEnvironmentHeader(value: object): value is EnvironmentHeader { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('isProduction' in value) || value['isProduction'] === undefined) return false; + if (!('order' in value) || value['order'] === undefined) return false; + return true; +} + +export function EnvironmentHeaderFromJSON(json: any): EnvironmentHeader { + return EnvironmentHeaderFromJSONTyped(json, false); +} + +export function EnvironmentHeaderFromJSONTyped(json: any, ignoreDiscriminator: boolean): EnvironmentHeader { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'name': json['name'], + 'isProduction': json['isProduction'], + 'order': json['order'], + }; +} + +export function EnvironmentHeaderToJSON(json: any): EnvironmentHeader { + return EnvironmentHeaderToJSONTyped(json, false); +} + +export function EnvironmentHeaderToJSONTyped(value?: EnvironmentHeader | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'name': value['name'], + 'isProduction': value['isProduction'], + 'order': value['order'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/EnvironmentHeaderCollection.ts b/packages/rest-api-sdk/src/generated/models/EnvironmentHeaderCollection.ts new file mode 100644 index 00000000..798fb3a5 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/EnvironmentHeaderCollection.ts @@ -0,0 +1,108 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { EnvironmentHeaderSortByColumn } from './EnvironmentHeaderSortByColumn'; +import { + EnvironmentHeaderSortByColumnFromJSON, + EnvironmentHeaderSortByColumnFromJSONTyped, + EnvironmentHeaderSortByColumnToJSON, + EnvironmentHeaderSortByColumnToJSONTyped, +} from './EnvironmentHeaderSortByColumn'; +import type { EnvironmentHeader } from './EnvironmentHeader'; +import { + EnvironmentHeaderFromJSON, + EnvironmentHeaderFromJSONTyped, + EnvironmentHeaderToJSON, + EnvironmentHeaderToJSONTyped, +} from './EnvironmentHeader'; +import type { SortOrder } from './SortOrder'; +import { + SortOrderFromJSON, + SortOrderFromJSONTyped, + SortOrderToJSON, + SortOrderToJSONTyped, +} from './SortOrder'; + +/** + * Collection of Basic environment information + * @export + * @interface EnvironmentHeaderCollection + */ +export interface EnvironmentHeaderCollection { + /** + * The individual items in the collection + * @type {Array} + * @memberof EnvironmentHeaderCollection + */ + data: Array; + /** + * + * @type {SortOrder} + * @memberof EnvironmentHeaderCollection + */ + sortOrder: SortOrder; + /** + * + * @type {EnvironmentHeaderSortByColumn} + * @memberof EnvironmentHeaderCollection + */ + sortBy: EnvironmentHeaderSortByColumn; +} + + + +/** + * Check if a given object implements the EnvironmentHeaderCollection interface. + */ +export function instanceOfEnvironmentHeaderCollection(value: object): value is EnvironmentHeaderCollection { + if (!('data' in value) || value['data'] === undefined) return false; + if (!('sortOrder' in value) || value['sortOrder'] === undefined) return false; + if (!('sortBy' in value) || value['sortBy'] === undefined) return false; + return true; +} + +export function EnvironmentHeaderCollectionFromJSON(json: any): EnvironmentHeaderCollection { + return EnvironmentHeaderCollectionFromJSONTyped(json, false); +} + +export function EnvironmentHeaderCollectionFromJSONTyped(json: any, ignoreDiscriminator: boolean): EnvironmentHeaderCollection { + if (json == null) { + return json; + } + return { + + 'data': ((json['data'] as Array).map(EnvironmentHeaderFromJSON)), + 'sortOrder': SortOrderFromJSON(json['sortOrder']), + 'sortBy': EnvironmentHeaderSortByColumnFromJSON(json['sortBy']), + }; +} + +export function EnvironmentHeaderCollectionToJSON(json: any): EnvironmentHeaderCollection { + return EnvironmentHeaderCollectionToJSONTyped(json, false); +} + +export function EnvironmentHeaderCollectionToJSONTyped(value?: EnvironmentHeaderCollection | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'data': ((value['data'] as Array).map(EnvironmentHeaderToJSON)), + 'sortOrder': SortOrderToJSON(value['sortOrder']), + 'sortBy': EnvironmentHeaderSortByColumnToJSON(value['sortBy']), + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/EnvironmentHeaderSortByColumn.ts b/packages/rest-api-sdk/src/generated/models/EnvironmentHeaderSortByColumn.ts new file mode 100644 index 00000000..358ec424 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/EnvironmentHeaderSortByColumn.ts @@ -0,0 +1,53 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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. + */ + + +/** + * The column to sort by + * @export + */ +export const EnvironmentHeaderSortByColumn = { + Name: 'name', + Order: 'order' +} as const; +export type EnvironmentHeaderSortByColumn = typeof EnvironmentHeaderSortByColumn[keyof typeof EnvironmentHeaderSortByColumn]; + + +export function instanceOfEnvironmentHeaderSortByColumn(value: any): boolean { + for (const key in EnvironmentHeaderSortByColumn) { + if (Object.prototype.hasOwnProperty.call(EnvironmentHeaderSortByColumn, key)) { + if (EnvironmentHeaderSortByColumn[key as keyof typeof EnvironmentHeaderSortByColumn] === value) { + return true; + } + } + } + return false; +} + +export function EnvironmentHeaderSortByColumnFromJSON(json: any): EnvironmentHeaderSortByColumn { + return EnvironmentHeaderSortByColumnFromJSONTyped(json, false); +} + +export function EnvironmentHeaderSortByColumnFromJSONTyped(json: any, ignoreDiscriminator: boolean): EnvironmentHeaderSortByColumn { + return json as EnvironmentHeaderSortByColumn; +} + +export function EnvironmentHeaderSortByColumnToJSON(value?: EnvironmentHeaderSortByColumn | null): any { + return value as any; +} + +export function EnvironmentHeaderSortByColumnToJSONTyped(value: any, ignoreDiscriminator: boolean): EnvironmentHeaderSortByColumn { + return value as EnvironmentHeaderSortByColumn; +} + diff --git a/packages/rest-api-sdk/src/generated/models/EnvironmentSdkAccess.ts b/packages/rest-api-sdk/src/generated/models/EnvironmentSdkAccess.ts new file mode 100644 index 00000000..cb03ea10 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/EnvironmentSdkAccess.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * SDK access details + * @export + * @interface EnvironmentSdkAccess + */ +export interface EnvironmentSdkAccess { + /** + * Publishable key + * @type {string} + * @memberof EnvironmentSdkAccess + */ + publishableKey: string; + /** + * Secret key + * @type {string} + * @memberof EnvironmentSdkAccess + */ + secretKey: string; +} + +/** + * Check if a given object implements the EnvironmentSdkAccess interface. + */ +export function instanceOfEnvironmentSdkAccess(value: object): value is EnvironmentSdkAccess { + if (!('publishableKey' in value) || value['publishableKey'] === undefined) return false; + if (!('secretKey' in value) || value['secretKey'] === undefined) return false; + return true; +} + +export function EnvironmentSdkAccessFromJSON(json: any): EnvironmentSdkAccess { + return EnvironmentSdkAccessFromJSONTyped(json, false); +} + +export function EnvironmentSdkAccessFromJSONTyped(json: any, ignoreDiscriminator: boolean): EnvironmentSdkAccess { + if (json == null) { + return json; + } + return { + + 'publishableKey': json['publishableKey'], + 'secretKey': json['secretKey'], + }; +} + +export function EnvironmentSdkAccessToJSON(json: any): EnvironmentSdkAccess { + return EnvironmentSdkAccessToJSONTyped(json, false); +} + +export function EnvironmentSdkAccessToJSONTyped(value?: EnvironmentSdkAccess | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'publishableKey': value['publishableKey'], + 'secretKey': value['secretKey'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/ErrorResponse.ts b/packages/rest-api-sdk/src/generated/models/ErrorResponse.ts new file mode 100644 index 00000000..b90d1d0e --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/ErrorResponse.ts @@ -0,0 +1,82 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { ErrorResponseError } from './ErrorResponseError'; +import { + ErrorResponseErrorFromJSON, + ErrorResponseErrorFromJSONTyped, + ErrorResponseErrorToJSON, + ErrorResponseErrorToJSONTyped, +} from './ErrorResponseError'; + +/** + * The error response, including individual issues, if applicable + * @export + * @interface ErrorResponse + */ +export interface ErrorResponse { + /** + * + * @type {ErrorResponseError} + * @memberof ErrorResponse + */ + error: ErrorResponseError; + /** + * Individual validation issues, if applicable + * @type {{ [key: string]: Array; }} + * @memberof ErrorResponse + */ + issues?: { [key: string]: Array; }; +} + +/** + * Check if a given object implements the ErrorResponse interface. + */ +export function instanceOfErrorResponse(value: object): value is ErrorResponse { + if (!('error' in value) || value['error'] === undefined) return false; + return true; +} + +export function ErrorResponseFromJSON(json: any): ErrorResponse { + return ErrorResponseFromJSONTyped(json, false); +} + +export function ErrorResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ErrorResponse { + if (json == null) { + return json; + } + return { + + 'error': ErrorResponseErrorFromJSON(json['error']), + 'issues': json['issues'] == null ? undefined : json['issues'], + }; +} + +export function ErrorResponseToJSON(json: any): ErrorResponse { + return ErrorResponseToJSONTyped(json, false); +} + +export function ErrorResponseToJSONTyped(value?: ErrorResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'error': ErrorResponseErrorToJSON(value['error']), + 'issues': value['issues'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/ErrorResponseError.ts b/packages/rest-api-sdk/src/generated/models/ErrorResponseError.ts new file mode 100644 index 00000000..efd7b93e --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/ErrorResponseError.ts @@ -0,0 +1,92 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * The error + * @export + * @interface ErrorResponseError + */ +export interface ErrorResponseError { + /** + * Error code + * @type {string} + * @memberof ErrorResponseError + */ + code: ErrorResponseErrorCodeEnum; + /** + * Human readable error message + * @type {string} + * @memberof ErrorResponseError + */ + message: string; +} + + +/** + * @export + */ +export const ErrorResponseErrorCodeEnum = { + InvalidRequest: 'invalid_request', + NotFound: 'not_found', + NotPossible: 'not_possible', + NotAllowed: 'not_allowed', + NotAvailable: 'not_available', + UnknownError: 'unknown_error', + Unauthorized: 'unauthorized', + Unauthenticated: 'unauthenticated' +} as const; +export type ErrorResponseErrorCodeEnum = typeof ErrorResponseErrorCodeEnum[keyof typeof ErrorResponseErrorCodeEnum]; + + +/** + * Check if a given object implements the ErrorResponseError interface. + */ +export function instanceOfErrorResponseError(value: object): value is ErrorResponseError { + if (!('code' in value) || value['code'] === undefined) return false; + if (!('message' in value) || value['message'] === undefined) return false; + return true; +} + +export function ErrorResponseErrorFromJSON(json: any): ErrorResponseError { + return ErrorResponseErrorFromJSONTyped(json, false); +} + +export function ErrorResponseErrorFromJSONTyped(json: any, ignoreDiscriminator: boolean): ErrorResponseError { + if (json == null) { + return json; + } + return { + + 'code': json['code'], + 'message': json['message'], + }; +} + +export function ErrorResponseErrorToJSON(json: any): ErrorResponseError { + return ErrorResponseErrorToJSONTyped(json, false); +} + +export function ErrorResponseErrorToJSONTyped(value?: ErrorResponseError | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'code': value['code'], + 'message': value['message'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/FlagHeader.ts b/packages/rest-api-sdk/src/generated/models/FlagHeader.ts new file mode 100644 index 00000000..8c092b05 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/FlagHeader.ts @@ -0,0 +1,174 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { StageHeader } from './StageHeader'; +import { + StageHeaderFromJSON, + StageHeaderFromJSONTyped, + StageHeaderToJSON, + StageHeaderToJSONTyped, +} from './StageHeader'; +import type { ReflagUserHeader } from './ReflagUserHeader'; +import { + ReflagUserHeaderFromJSON, + ReflagUserHeaderFromJSONTyped, + ReflagUserHeaderToJSON, + ReflagUserHeaderToJSONTyped, +} from './ReflagUserHeader'; + +/** + * Basic flag information + * @export + * @interface FlagHeader + */ +export interface FlagHeader { + /** + * Flag ID + * @type {string} + * @memberof FlagHeader + */ + id: string; + /** + * Unique flag key + * @type {string} + * @memberof FlagHeader + */ + key: string; + /** + * Flag name + * @type {string} + * @memberof FlagHeader + */ + name: string; + /** + * Flag description + * @type {string} + * @memberof FlagHeader + */ + description?: string; + /** + * + * @type {StageHeader} + * @memberof FlagHeader + */ + stage?: StageHeader; + /** + * + * @type {ReflagUserHeader} + * @memberof FlagHeader + */ + owner?: ReflagUserHeader; + /** + * Whether the flag is archived + * @type {boolean} + * @memberof FlagHeader + */ + archived: boolean; + /** + * Whether the flag is stale + * @type {boolean} + * @memberof FlagHeader + */ + stale: boolean; + /** + * Whether the flag is permanent + * @type {boolean} + * @memberof FlagHeader + */ + permanent: boolean; + /** + * Timestamp when the flag was created + * @type {string} + * @memberof FlagHeader + */ + createdAt?: string; + /** + * Timestamp when the flag was last checked + * @type {string} + * @memberof FlagHeader + */ + lastCheckAt?: string; + /** + * Timestamp when the flag was last tracked + * @type {string} + * @memberof FlagHeader + */ + lastTrackAt?: string; +} + +/** + * Check if a given object implements the FlagHeader interface. + */ +export function instanceOfFlagHeader(value: object): value is FlagHeader { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('key' in value) || value['key'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('archived' in value) || value['archived'] === undefined) return false; + if (!('stale' in value) || value['stale'] === undefined) return false; + if (!('permanent' in value) || value['permanent'] === undefined) return false; + return true; +} + +export function FlagHeaderFromJSON(json: any): FlagHeader { + return FlagHeaderFromJSONTyped(json, false); +} + +export function FlagHeaderFromJSONTyped(json: any, ignoreDiscriminator: boolean): FlagHeader { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'key': json['key'], + 'name': json['name'], + 'description': json['description'] == null ? undefined : json['description'], + 'stage': json['stage'] == null ? undefined : StageHeaderFromJSON(json['stage']), + 'owner': json['owner'] == null ? undefined : ReflagUserHeaderFromJSON(json['owner']), + 'archived': json['archived'], + 'stale': json['stale'], + 'permanent': json['permanent'], + 'createdAt': json['createdAt'] == null ? undefined : json['createdAt'], + 'lastCheckAt': json['lastCheckAt'] == null ? undefined : json['lastCheckAt'], + 'lastTrackAt': json['lastTrackAt'] == null ? undefined : json['lastTrackAt'], + }; +} + +export function FlagHeaderToJSON(json: any): FlagHeader { + return FlagHeaderToJSONTyped(json, false); +} + +export function FlagHeaderToJSONTyped(value?: FlagHeader | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'key': value['key'], + 'name': value['name'], + 'description': value['description'], + 'stage': StageHeaderToJSON(value['stage']), + 'owner': ReflagUserHeaderToJSON(value['owner']), + 'archived': value['archived'], + 'stale': value['stale'], + 'permanent': value['permanent'], + 'createdAt': value['createdAt'], + 'lastCheckAt': value['lastCheckAt'], + 'lastTrackAt': value['lastTrackAt'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/FlagHeaderCollection.ts b/packages/rest-api-sdk/src/generated/models/FlagHeaderCollection.ts new file mode 100644 index 00000000..a3dbd7eb --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/FlagHeaderCollection.ts @@ -0,0 +1,146 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { FlagHeader } from './FlagHeader'; +import { + FlagHeaderFromJSON, + FlagHeaderFromJSONTyped, + FlagHeaderToJSON, + FlagHeaderToJSONTyped, +} from './FlagHeader'; +import type { SortOrder } from './SortOrder'; +import { + SortOrderFromJSON, + SortOrderFromJSONTyped, + SortOrderToJSON, + SortOrderToJSONTyped, +} from './SortOrder'; + +/** + * Collection response containing flags + * @export + * @interface FlagHeaderCollection + */ +export interface FlagHeaderCollection { + /** + * Page of the collection of flags + * @type {Array} + * @memberof FlagHeaderCollection + */ + data: Array; + /** + * Total number of flags in collection + * @type {number} + * @memberof FlagHeaderCollection + */ + totalCount: number; + /** + * Page size + * @type {number} + * @memberof FlagHeaderCollection + */ + pageSize: number; + /** + * Page index + * @type {number} + * @memberof FlagHeaderCollection + */ + pageIndex: number; + /** + * Sort by + * @type {string} + * @memberof FlagHeaderCollection + */ + sortBy: FlagHeaderCollectionSortByEnum; + /** + * Sort order + * @type {SortOrder} + * @memberof FlagHeaderCollection + */ + sortOrder: SortOrder; +} + + +/** + * @export + */ +export const FlagHeaderCollectionSortByEnum = { + Name: 'name', + Key: 'key', + Stage: 'stage', + AutoFeedbackSurveysEnabled: 'autoFeedbackSurveysEnabled', + CreatedAt: 'createdAt', + EnvironmentStatus: 'environmentStatus', + Owner: 'owner', + LastCheck: 'lastCheck', + LastTrack: 'lastTrack', + Stale: 'stale', + ArchivingChecks: 'archivingChecks' +} as const; +export type FlagHeaderCollectionSortByEnum = typeof FlagHeaderCollectionSortByEnum[keyof typeof FlagHeaderCollectionSortByEnum]; + + +/** + * Check if a given object implements the FlagHeaderCollection interface. + */ +export function instanceOfFlagHeaderCollection(value: object): value is FlagHeaderCollection { + if (!('data' in value) || value['data'] === undefined) return false; + if (!('totalCount' in value) || value['totalCount'] === undefined) return false; + if (!('pageSize' in value) || value['pageSize'] === undefined) return false; + if (!('pageIndex' in value) || value['pageIndex'] === undefined) return false; + if (!('sortBy' in value) || value['sortBy'] === undefined) return false; + if (!('sortOrder' in value) || value['sortOrder'] === undefined) return false; + return true; +} + +export function FlagHeaderCollectionFromJSON(json: any): FlagHeaderCollection { + return FlagHeaderCollectionFromJSONTyped(json, false); +} + +export function FlagHeaderCollectionFromJSONTyped(json: any, ignoreDiscriminator: boolean): FlagHeaderCollection { + if (json == null) { + return json; + } + return { + + 'data': ((json['data'] as Array).map(FlagHeaderFromJSON)), + 'totalCount': json['totalCount'], + 'pageSize': json['pageSize'], + 'pageIndex': json['pageIndex'], + 'sortBy': json['sortBy'], + 'sortOrder': SortOrderFromJSON(json['sortOrder']), + }; +} + +export function FlagHeaderCollectionToJSON(json: any): FlagHeaderCollection { + return FlagHeaderCollectionToJSONTyped(json, false); +} + +export function FlagHeaderCollectionToJSONTyped(value?: FlagHeaderCollection | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'data': ((value['data'] as Array).map(FlagHeaderToJSON)), + 'totalCount': value['totalCount'], + 'pageSize': value['pageSize'], + 'pageIndex': value['pageIndex'], + 'sortBy': value['sortBy'], + 'sortOrder': SortOrderToJSON(value['sortOrder']), + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/FlagKeyFormat.ts b/packages/rest-api-sdk/src/generated/models/FlagKeyFormat.ts new file mode 100644 index 00000000..b0d33716 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/FlagKeyFormat.ts @@ -0,0 +1,58 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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. + */ + + +/** + * The enforced key format when creating flags + * @export + */ +export const FlagKeyFormat = { + Custom: 'custom', + PascalCase: 'pascalCase', + CamelCase: 'camelCase', + SnakeCaseUpper: 'snakeCaseUpper', + SnakeCaseLower: 'snakeCaseLower', + KebabCaseUpper: 'kebabCaseUpper', + KebabCaseLower: 'kebabCaseLower' +} as const; +export type FlagKeyFormat = typeof FlagKeyFormat[keyof typeof FlagKeyFormat]; + + +export function instanceOfFlagKeyFormat(value: any): boolean { + for (const key in FlagKeyFormat) { + if (Object.prototype.hasOwnProperty.call(FlagKeyFormat, key)) { + if (FlagKeyFormat[key as keyof typeof FlagKeyFormat] === value) { + return true; + } + } + } + return false; +} + +export function FlagKeyFormatFromJSON(json: any): FlagKeyFormat { + return FlagKeyFormatFromJSONTyped(json, false); +} + +export function FlagKeyFormatFromJSONTyped(json: any, ignoreDiscriminator: boolean): FlagKeyFormat { + return json as FlagKeyFormat; +} + +export function FlagKeyFormatToJSON(value?: FlagKeyFormat | null): any { + return value as any; +} + +export function FlagKeyFormatToJSONTyped(value: any, ignoreDiscriminator: boolean): FlagKeyFormat { + return value as FlagKeyFormat; +} + diff --git a/packages/rest-api-sdk/src/generated/models/FlagTargeting.ts b/packages/rest-api-sdk/src/generated/models/FlagTargeting.ts new file mode 100644 index 00000000..970812a6 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/FlagTargeting.ts @@ -0,0 +1,101 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { FlagValueTargeting } from './FlagValueTargeting'; +import { + FlagValueTargetingFromJSON, + FlagValueTargetingFromJSONTyped, + FlagValueTargetingToJSON, + FlagValueTargetingToJSONTyped, +} from './FlagValueTargeting'; + +/** + * Flag targeting information and its audience + * @export + * @interface FlagTargeting + */ +export interface FlagTargeting { + /** + * Unique flag key + * @type {string} + * @memberof FlagTargeting + */ + flagKey: string; + /** + * Flag targeting version + * @type {number} + * @memberof FlagTargeting + */ + version: number; + /** + * Last time the targeting was updated + * @type {Date} + * @memberof FlagTargeting + */ + updatedAt: Date; + /** + * The flag targeting for each value + * @type {{ [key: string]: FlagValueTargeting; }} + * @memberof FlagTargeting + */ + specificTargets: { [key: string]: FlagValueTargeting; }; +} + +/** + * Check if a given object implements the FlagTargeting interface. + */ +export function instanceOfFlagTargeting(value: object): value is FlagTargeting { + if (!('flagKey' in value) || value['flagKey'] === undefined) return false; + if (!('version' in value) || value['version'] === undefined) return false; + if (!('updatedAt' in value) || value['updatedAt'] === undefined) return false; + if (!('specificTargets' in value) || value['specificTargets'] === undefined) return false; + return true; +} + +export function FlagTargetingFromJSON(json: any): FlagTargeting { + return FlagTargetingFromJSONTyped(json, false); +} + +export function FlagTargetingFromJSONTyped(json: any, ignoreDiscriminator: boolean): FlagTargeting { + if (json == null) { + return json; + } + return { + + 'flagKey': json['flagKey'], + 'version': json['version'], + 'updatedAt': (new Date(json['updatedAt'])), + 'specificTargets': (mapValues(json['specificTargets'], FlagValueTargetingFromJSON)), + }; +} + +export function FlagTargetingToJSON(json: any): FlagTargeting { + return FlagTargetingToJSONTyped(json, false); +} + +export function FlagTargetingToJSONTyped(value?: FlagTargeting | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'flagKey': value['flagKey'], + 'version': value['version'], + 'updatedAt': value['updatedAt'].toISOString(), + 'specificTargets': (mapValues(value['specificTargets'], FlagValueTargetingToJSON)), + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/FlagValue.ts b/packages/rest-api-sdk/src/generated/models/FlagValue.ts new file mode 100644 index 00000000..5495197b --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/FlagValue.ts @@ -0,0 +1,52 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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. + */ + + +/** + * The value of the flag served to the audience. + * @export + */ +export const FlagValue = { + True: 'true' +} as const; +export type FlagValue = typeof FlagValue[keyof typeof FlagValue]; + + +export function instanceOfFlagValue(value: any): boolean { + for (const key in FlagValue) { + if (Object.prototype.hasOwnProperty.call(FlagValue, key)) { + if (FlagValue[key as keyof typeof FlagValue] === value) { + return true; + } + } + } + return false; +} + +export function FlagValueFromJSON(json: any): FlagValue { + return FlagValueFromJSONTyped(json, false); +} + +export function FlagValueFromJSONTyped(json: any, ignoreDiscriminator: boolean): FlagValue { + return json as FlagValue; +} + +export function FlagValueToJSON(value?: FlagValue | null): any { + return value as any; +} + +export function FlagValueToJSONTyped(value: any, ignoreDiscriminator: boolean): FlagValue { + return value as FlagValue; +} + diff --git a/packages/rest-api-sdk/src/generated/models/FlagValueTargeting.ts b/packages/rest-api-sdk/src/generated/models/FlagValueTargeting.ts new file mode 100644 index 00000000..d16726bc --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/FlagValueTargeting.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * Flag targeting value and its audience + * @export + * @interface FlagValueTargeting + */ +export interface FlagValueTargeting { + /** + * Companies that were explicitly given the value + * @type {Array} + * @memberof FlagValueTargeting + */ + companyIds: Array; + /** + * Users that were explicitly given the value + * @type {Array} + * @memberof FlagValueTargeting + */ + userIds: Array; +} + +/** + * Check if a given object implements the FlagValueTargeting interface. + */ +export function instanceOfFlagValueTargeting(value: object): value is FlagValueTargeting { + if (!('companyIds' in value) || value['companyIds'] === undefined) return false; + if (!('userIds' in value) || value['userIds'] === undefined) return false; + return true; +} + +export function FlagValueTargetingFromJSON(json: any): FlagValueTargeting { + return FlagValueTargetingFromJSONTyped(json, false); +} + +export function FlagValueTargetingFromJSONTyped(json: any, ignoreDiscriminator: boolean): FlagValueTargeting { + if (json == null) { + return json; + } + return { + + 'companyIds': json['companyIds'], + 'userIds': json['userIds'], + }; +} + +export function FlagValueTargetingToJSON(json: any): FlagValueTargeting { + return FlagValueTargetingToJSONTyped(json, false); +} + +export function FlagValueTargetingToJSONTyped(value?: FlagValueTargeting | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'companyIds': value['companyIds'], + 'userIds': value['userIds'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/OrgHeader.ts b/packages/rest-api-sdk/src/generated/models/OrgHeader.ts new file mode 100644 index 00000000..e24841bb --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/OrgHeader.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * Organization's basic information + * @export + * @interface OrgHeader + */ +export interface OrgHeader { + /** + * Organization identifier + * @type {string} + * @memberof OrgHeader + */ + id: string; + /** + * Organization name + * @type {string} + * @memberof OrgHeader + */ + name: string; +} + +/** + * Check if a given object implements the OrgHeader interface. + */ +export function instanceOfOrgHeader(value: object): value is OrgHeader { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + return true; +} + +export function OrgHeaderFromJSON(json: any): OrgHeader { + return OrgHeaderFromJSONTyped(json, false); +} + +export function OrgHeaderFromJSONTyped(json: any, ignoreDiscriminator: boolean): OrgHeader { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'name': json['name'], + }; +} + +export function OrgHeaderToJSON(json: any): OrgHeader { + return OrgHeaderToJSONTyped(json, false); +} + +export function OrgHeaderToJSONTyped(value?: OrgHeader | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'name': value['name'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/ReflagUserHeader.ts b/packages/rest-api-sdk/src/generated/models/ReflagUserHeader.ts new file mode 100644 index 00000000..2a7da548 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/ReflagUserHeader.ts @@ -0,0 +1,92 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * Reflag user's basic information + * @export + * @interface ReflagUserHeader + */ +export interface ReflagUserHeader { + /** + * Reflag user identifier + * @type {string} + * @memberof ReflagUserHeader + */ + id: string; + /** + * User's name + * @type {string} + * @memberof ReflagUserHeader + */ + name: string; + /** + * User's email + * @type {string} + * @memberof ReflagUserHeader + */ + email: string; + /** + * User's avatar URL + * @type {string} + * @memberof ReflagUserHeader + */ + avatarUrl?: string; +} + +/** + * Check if a given object implements the ReflagUserHeader interface. + */ +export function instanceOfReflagUserHeader(value: object): value is ReflagUserHeader { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('email' in value) || value['email'] === undefined) return false; + return true; +} + +export function ReflagUserHeaderFromJSON(json: any): ReflagUserHeader { + return ReflagUserHeaderFromJSONTyped(json, false); +} + +export function ReflagUserHeaderFromJSONTyped(json: any, ignoreDiscriminator: boolean): ReflagUserHeader { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'name': json['name'], + 'email': json['email'], + 'avatarUrl': json['avatarUrl'] == null ? undefined : json['avatarUrl'], + }; +} + +export function ReflagUserHeaderToJSON(json: any): ReflagUserHeader { + return ReflagUserHeaderToJSONTyped(json, false); +} + +export function ReflagUserHeaderToJSONTyped(value?: ReflagUserHeader | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'name': value['name'], + 'email': value['email'], + 'avatarUrl': value['avatarUrl'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/SegmentHeader.ts b/packages/rest-api-sdk/src/generated/models/SegmentHeader.ts new file mode 100644 index 00000000..50529443 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/SegmentHeader.ts @@ -0,0 +1,94 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { SegmentType } from './SegmentType'; +import { + SegmentTypeFromJSON, + SegmentTypeFromJSONTyped, + SegmentTypeToJSON, + SegmentTypeToJSONTyped, +} from './SegmentType'; + +/** + * Segment's basic information + * @export + * @interface SegmentHeader + */ +export interface SegmentHeader { + /** + * Segment identifier + * @type {string} + * @memberof SegmentHeader + */ + id: string; + /** + * Segment name + * @type {string} + * @memberof SegmentHeader + */ + name: string; + /** + * + * @type {SegmentType} + * @memberof SegmentHeader + */ + type: SegmentType; +} + + + +/** + * Check if a given object implements the SegmentHeader interface. + */ +export function instanceOfSegmentHeader(value: object): value is SegmentHeader { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('type' in value) || value['type'] === undefined) return false; + return true; +} + +export function SegmentHeaderFromJSON(json: any): SegmentHeader { + return SegmentHeaderFromJSONTyped(json, false); +} + +export function SegmentHeaderFromJSONTyped(json: any, ignoreDiscriminator: boolean): SegmentHeader { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'name': json['name'], + 'type': SegmentTypeFromJSON(json['type']), + }; +} + +export function SegmentHeaderToJSON(json: any): SegmentHeader { + return SegmentHeaderToJSONTyped(json, false); +} + +export function SegmentHeaderToJSONTyped(value?: SegmentHeader | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'name': value['name'], + 'type': SegmentTypeToJSON(value['type']), + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/SegmentType.ts b/packages/rest-api-sdk/src/generated/models/SegmentType.ts new file mode 100644 index 00000000..da773ae5 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/SegmentType.ts @@ -0,0 +1,53 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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. + */ + + +/** + * Segment type + * @export + */ +export const SegmentType = { + All: 'all', + Custom: 'custom' +} as const; +export type SegmentType = typeof SegmentType[keyof typeof SegmentType]; + + +export function instanceOfSegmentType(value: any): boolean { + for (const key in SegmentType) { + if (Object.prototype.hasOwnProperty.call(SegmentType, key)) { + if (SegmentType[key as keyof typeof SegmentType] === value) { + return true; + } + } + } + return false; +} + +export function SegmentTypeFromJSON(json: any): SegmentType { + return SegmentTypeFromJSONTyped(json, false); +} + +export function SegmentTypeFromJSONTyped(json: any, ignoreDiscriminator: boolean): SegmentType { + return json as SegmentType; +} + +export function SegmentTypeToJSON(value?: SegmentType | null): any { + return value as any; +} + +export function SegmentTypeToJSONTyped(value: any, ignoreDiscriminator: boolean): SegmentType { + return value as SegmentType; +} + diff --git a/packages/rest-api-sdk/src/generated/models/SortOrder.ts b/packages/rest-api-sdk/src/generated/models/SortOrder.ts new file mode 100644 index 00000000..034e4f2f --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/SortOrder.ts @@ -0,0 +1,53 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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. + */ + + +/** + * Sort order applied to the sorting column + * @export + */ +export const SortOrder = { + Asc: 'asc', + Desc: 'desc' +} as const; +export type SortOrder = typeof SortOrder[keyof typeof SortOrder]; + + +export function instanceOfSortOrder(value: any): boolean { + for (const key in SortOrder) { + if (Object.prototype.hasOwnProperty.call(SortOrder, key)) { + if (SortOrder[key as keyof typeof SortOrder] === value) { + return true; + } + } + } + return false; +} + +export function SortOrderFromJSON(json: any): SortOrder { + return SortOrderFromJSONTyped(json, false); +} + +export function SortOrderFromJSONTyped(json: any, ignoreDiscriminator: boolean): SortOrder { + return json as SortOrder; +} + +export function SortOrderToJSON(value?: SortOrder | null): any { + return value as any; +} + +export function SortOrderToJSONTyped(value: any, ignoreDiscriminator: boolean): SortOrder { + return value as SortOrder; +} + diff --git a/packages/rest-api-sdk/src/generated/models/StageHeader.ts b/packages/rest-api-sdk/src/generated/models/StageHeader.ts new file mode 100644 index 00000000..13975a96 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/StageHeader.ts @@ -0,0 +1,93 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * Stage's basic information + * @export + * @interface StageHeader + */ +export interface StageHeader { + /** + * Stage identifier + * @type {string} + * @memberof StageHeader + */ + id: string; + /** + * Stage name + * @type {string} + * @memberof StageHeader + */ + name: string; + /** + * Stage color (HTML color name or hex code) + * @type {string} + * @memberof StageHeader + */ + color: string; + /** + * Stage order + * @type {number} + * @memberof StageHeader + */ + order: number; +} + +/** + * Check if a given object implements the StageHeader interface. + */ +export function instanceOfStageHeader(value: object): value is StageHeader { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('name' in value) || value['name'] === undefined) return false; + if (!('color' in value) || value['color'] === undefined) return false; + if (!('order' in value) || value['order'] === undefined) return false; + return true; +} + +export function StageHeaderFromJSON(json: any): StageHeader { + return StageHeaderFromJSONTyped(json, false); +} + +export function StageHeaderFromJSONTyped(json: any, ignoreDiscriminator: boolean): StageHeader { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'name': json['name'], + 'color': json['color'], + 'order': json['order'], + }; +} + +export function StageHeaderToJSON(json: any): StageHeader { + return StageHeaderToJSONTyped(json, false); +} + +export function StageHeaderToJSONTyped(value?: StageHeader | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'name': value['name'], + 'color': value['color'], + 'order': value['order'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/UpdateEntityFlagsBody.ts b/packages/rest-api-sdk/src/generated/models/UpdateEntityFlagsBody.ts new file mode 100644 index 00000000..f526cecd --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/UpdateEntityFlagsBody.ts @@ -0,0 +1,90 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +import type { EntityFlagUpdate } from './EntityFlagUpdate'; +import { + EntityFlagUpdateFromJSON, + EntityFlagUpdateFromJSONTyped, + EntityFlagUpdateToJSON, + EntityFlagUpdateToJSONTyped, +} from './EntityFlagUpdate'; + +/** + * Request body for updating flags for an entity + * @export + * @interface UpdateEntityFlagsBody + */ +export interface UpdateEntityFlagsBody { + /** + * List of flag updates to apply + * @type {Array} + * @memberof UpdateEntityFlagsBody + */ + updates: Array; + /** + * Description of the change for audit history + * @type {string} + * @memberof UpdateEntityFlagsBody + */ + changeDescription?: string; + /** + * Whether to send notifications about the change (default: true) + * @type {boolean} + * @memberof UpdateEntityFlagsBody + */ + notifications?: boolean; +} + +/** + * Check if a given object implements the UpdateEntityFlagsBody interface. + */ +export function instanceOfUpdateEntityFlagsBody(value: object): value is UpdateEntityFlagsBody { + if (!('updates' in value) || value['updates'] === undefined) return false; + return true; +} + +export function UpdateEntityFlagsBodyFromJSON(json: any): UpdateEntityFlagsBody { + return UpdateEntityFlagsBodyFromJSONTyped(json, false); +} + +export function UpdateEntityFlagsBodyFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateEntityFlagsBody { + if (json == null) { + return json; + } + return { + + 'updates': ((json['updates'] as Array).map(EntityFlagUpdateFromJSON)), + 'changeDescription': json['changeDescription'] == null ? undefined : json['changeDescription'], + 'notifications': json['notifications'] == null ? undefined : json['notifications'], + }; +} + +export function UpdateEntityFlagsBodyToJSON(json: any): UpdateEntityFlagsBody { + return UpdateEntityFlagsBodyToJSONTyped(json, false); +} + +export function UpdateEntityFlagsBodyToJSONTyped(value?: UpdateEntityFlagsBody | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'updates': ((value['updates'] as Array).map(EntityFlagUpdateToJSON)), + 'changeDescription': value['changeDescription'], + 'notifications': value['notifications'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/UpdateFlagRequest.ts b/packages/rest-api-sdk/src/generated/models/UpdateFlagRequest.ts new file mode 100644 index 00000000..b08e9fdf --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/UpdateFlagRequest.ts @@ -0,0 +1,113 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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 { mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateFlagRequest + */ +export interface UpdateFlagRequest { + /** + * Name of the flag + * @type {string} + * @memberof UpdateFlagRequest + */ + name?: string; + /** + * + * @type {string} + * @memberof UpdateFlagRequest + */ + description?: string | null; + /** + * + * @type {string} + * @memberof UpdateFlagRequest + */ + ownerUserId?: string | null; + /** + * + * @type {boolean} + * @memberof UpdateFlagRequest + */ + permanent?: boolean; + /** + * Whether the flag is secret + * @type {boolean} + * @memberof UpdateFlagRequest + */ + secret?: boolean; + /** + * + * @type {boolean} + * @memberof UpdateFlagRequest + */ + isArchived?: boolean; + /** + * Stage ID of the flag + * @type {string} + * @memberof UpdateFlagRequest + */ + stageId?: string; +} + +/** + * Check if a given object implements the UpdateFlagRequest interface. + */ +export function instanceOfUpdateFlagRequest(value: object): value is UpdateFlagRequest { + return true; +} + +export function UpdateFlagRequestFromJSON(json: any): UpdateFlagRequest { + return UpdateFlagRequestFromJSONTyped(json, false); +} + +export function UpdateFlagRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateFlagRequest { + if (json == null) { + return json; + } + return { + + 'name': json['name'] == null ? undefined : json['name'], + 'description': json['description'] == null ? undefined : json['description'], + 'ownerUserId': json['ownerUserId'] == null ? undefined : json['ownerUserId'], + 'permanent': json['permanent'] == null ? undefined : json['permanent'], + 'secret': json['secret'] == null ? undefined : json['secret'], + 'isArchived': json['isArchived'] == null ? undefined : json['isArchived'], + 'stageId': json['stageId'] == null ? undefined : json['stageId'], + }; +} + +export function UpdateFlagRequestToJSON(json: any): UpdateFlagRequest { + return UpdateFlagRequestToJSONTyped(json, false); +} + +export function UpdateFlagRequestToJSONTyped(value?: UpdateFlagRequest | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'name': value['name'], + 'description': value['description'], + 'ownerUserId': value['ownerUserId'], + 'permanent': value['permanent'], + 'secret': value['secret'], + 'isArchived': value['isArchived'], + 'stageId': value['stageId'], + }; +} + diff --git a/packages/rest-api-sdk/src/generated/models/index.ts b/packages/rest-api-sdk/src/generated/models/index.ts new file mode 100644 index 00000000..1c4b59e4 --- /dev/null +++ b/packages/rest-api-sdk/src/generated/models/index.ts @@ -0,0 +1,32 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './App'; +export * from './AppHeader'; +export * from './AppHeaderCollection'; +export * from './CreateFlag200Response'; +export * from './CreateFlag200ResponseFlag'; +export * from './CreateFlagRequest'; +export * from './EntityFlag'; +export * from './EntityFlagUpdate'; +export * from './EntityFlagsResponse'; +export * from './Environment'; +export * from './EnvironmentHeader'; +export * from './EnvironmentHeaderCollection'; +export * from './EnvironmentHeaderSortByColumn'; +export * from './EnvironmentSdkAccess'; +export * from './ErrorResponse'; +export * from './ErrorResponseError'; +export * from './FlagHeader'; +export * from './FlagHeaderCollection'; +export * from './FlagKeyFormat'; +export * from './FlagTargeting'; +export * from './FlagValue'; +export * from './FlagValueTargeting'; +export * from './OrgHeader'; +export * from './ReflagUserHeader'; +export * from './SegmentHeader'; +export * from './SegmentType'; +export * from './SortOrder'; +export * from './StageHeader'; +export * from './UpdateEntityFlagsBody'; +export * from './UpdateFlagRequest'; diff --git a/packages/rest-api-sdk/src/generated/runtime.ts b/packages/rest-api-sdk/src/generated/runtime.ts new file mode 100644 index 00000000..b87a849d --- /dev/null +++ b/packages/rest-api-sdk/src/generated/runtime.ts @@ -0,0 +1,432 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Reflag API + * Feature flag management API + * + * The version of the OpenAPI document: 3.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. + */ + + +export const BASE_PATH = "https://app.reflag.com/api".replace(/\/+$/, ""); + +export interface ConfigurationParameters { + basePath?: string; // override base path + fetchApi?: FetchAPI; // override for fetch implementation + middleware?: Middleware[]; // middleware to apply before/after fetch requests + queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings + username?: string; // parameter for basic security + password?: string; // parameter for basic security + apiKey?: string | Promise | ((name: string) => string | Promise); // parameter for apiKey security + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string | Promise); // parameter for oauth2 security + headers?: HTTPHeaders; //header params we want to use on every request + credentials?: RequestCredentials; //value for the credentials param we want to use on each request +} + +export class Configuration { + constructor(private configuration: ConfigurationParameters = {}) {} + + set config(configuration: Configuration) { + this.configuration = configuration; + } + + get basePath(): string { + return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH; + } + + get fetchApi(): FetchAPI | undefined { + return this.configuration.fetchApi; + } + + get middleware(): Middleware[] { + return this.configuration.middleware || []; + } + + get queryParamsStringify(): (params: HTTPQuery) => string { + return this.configuration.queryParamsStringify || querystring; + } + + get username(): string | undefined { + return this.configuration.username; + } + + get password(): string | undefined { + return this.configuration.password; + } + + get apiKey(): ((name: string) => string | Promise) | undefined { + const apiKey = this.configuration.apiKey; + if (apiKey) { + return typeof apiKey === 'function' ? apiKey : () => apiKey; + } + return undefined; + } + + get accessToken(): ((name?: string, scopes?: string[]) => string | Promise) | undefined { + const accessToken = this.configuration.accessToken; + if (accessToken) { + return typeof accessToken === 'function' ? accessToken : async () => accessToken; + } + return undefined; + } + + get headers(): HTTPHeaders | undefined { + return this.configuration.headers; + } + + get credentials(): RequestCredentials | undefined { + return this.configuration.credentials; + } +} + +export const DefaultConfig = new Configuration(); + +/** + * This is the base class for all generated API classes. + */ +export class BaseAPI { + + private static readonly jsonRegex = new RegExp('^(:?application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$', 'i'); + private middleware: Middleware[]; + + constructor(protected configuration = DefaultConfig) { + this.middleware = configuration.middleware; + } + + withMiddleware(this: T, ...middlewares: Middleware[]) { + const next = this.clone(); + next.middleware = next.middleware.concat(...middlewares); + return next; + } + + withPreMiddleware(this: T, ...preMiddlewares: Array) { + const middlewares = preMiddlewares.map((pre) => ({ pre })); + return this.withMiddleware(...middlewares); + } + + withPostMiddleware(this: T, ...postMiddlewares: Array) { + const middlewares = postMiddlewares.map((post) => ({ post })); + return this.withMiddleware(...middlewares); + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + protected isJsonMime(mime: string | null | undefined): boolean { + if (!mime) { + return false; + } + return BaseAPI.jsonRegex.test(mime); + } + + protected async request(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction): Promise { + const { url, init } = await this.createFetchParams(context, initOverrides); + const response = await this.fetchApi(url, init); + if (response && (response.status >= 200 && response.status < 300)) { + return response; + } + throw new ResponseError(response, 'Response returned an error code'); + } + + private async createFetchParams(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction) { + let url = this.configuration.basePath + context.path; + if (context.query !== undefined && Object.keys(context.query).length !== 0) { + // only add the querystring to the URL if there are query parameters. + // this is done to avoid urls ending with a "?" character which buggy webservers + // do not handle correctly sometimes. + url += '?' + this.configuration.queryParamsStringify(context.query); + } + + const headers = Object.assign({}, this.configuration.headers, context.headers); + Object.keys(headers).forEach(key => headers[key] === undefined ? delete headers[key] : {}); + + const initOverrideFn = + typeof initOverrides === "function" + ? initOverrides + : async () => initOverrides; + + const initParams = { + method: context.method, + headers, + body: context.body, + credentials: this.configuration.credentials, + }; + + const overriddenInit: RequestInit = { + ...initParams, + ...(await initOverrideFn({ + init: initParams, + context, + })) + }; + + let body: any; + if (isFormData(overriddenInit.body) + || (overriddenInit.body instanceof URLSearchParams) + || isBlob(overriddenInit.body)) { + body = overriddenInit.body; + } else if (this.isJsonMime(headers['Content-Type'])) { + body = JSON.stringify(overriddenInit.body); + } else { + body = overriddenInit.body; + } + + const init: RequestInit = { + ...overriddenInit, + body + }; + + return { url, init }; + } + + private fetchApi = async (url: string, init: RequestInit) => { + let fetchParams = { url, init }; + for (const middleware of this.middleware) { + if (middleware.pre) { + fetchParams = await middleware.pre({ + fetch: this.fetchApi, + ...fetchParams, + }) || fetchParams; + } + } + let response: Response | undefined = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response === undefined) { + if (e instanceof Error) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } else { + throw e; + } + } + } + for (const middleware of this.middleware) { + if (middleware.post) { + response = await middleware.post({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + response: response.clone(), + }) || response; + } + } + return response; + } + + /** + * Create a shallow clone of `this` by constructing a new instance + * and then shallow cloning data members. + */ + private clone(this: T): T { + const constructor = this.constructor as any; + const next = new constructor(this.configuration); + next.middleware = this.middleware.slice(); + return next; + } +}; + +function isBlob(value: any): value is Blob { + return typeof Blob !== 'undefined' && value instanceof Blob; +} + +function isFormData(value: any): value is FormData { + return typeof FormData !== "undefined" && value instanceof FormData; +} + +export class ResponseError extends Error { + override name: "ResponseError" = "ResponseError"; + constructor(public response: Response, msg?: string) { + super(msg); + } +} + +export class FetchError extends Error { + override name: "FetchError" = "FetchError"; + constructor(public cause: Error, msg?: string) { + super(msg); + } +} + +export class RequiredError extends Error { + override name: "RequiredError" = "RequiredError"; + constructor(public field: string, msg?: string) { + super(msg); + } +} + +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +export type FetchAPI = WindowOrWorkerGlobalScope['fetch']; + +export type Json = any; +export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD'; +export type HTTPHeaders = { [key: string]: string }; +export type HTTPQuery = { [key: string]: string | number | null | boolean | Array | Set | HTTPQuery }; +export type HTTPBody = Json | FormData | URLSearchParams; +export type HTTPRequestInit = { headers?: HTTPHeaders; method: HTTPMethod; credentials?: RequestCredentials; body?: HTTPBody }; +export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; + +export type InitOverrideFunction = (requestContext: { init: HTTPRequestInit, context: RequestOpts }) => Promise + +export interface FetchParams { + url: string; + init: RequestInit; +} + +export interface RequestOpts { + path: string; + method: HTTPMethod; + headers: HTTPHeaders; + query?: HTTPQuery; + body?: HTTPBody; +} + +export function querystring(params: HTTPQuery, prefix: string = ''): string { + return Object.keys(params) + .map(key => querystringSingleKey(key, params[key], prefix)) + .filter(part => part.length > 0) + .join('&'); +} + +function querystringSingleKey(key: string, value: string | number | null | undefined | boolean | Array | Set | HTTPQuery, keyPrefix: string = ''): string { + const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key); + if (value instanceof Array) { + const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue))) + .join(`&${encodeURIComponent(fullKey)}=`); + return `${encodeURIComponent(fullKey)}=${multiValue}`; + } + if (value instanceof Set) { + const valueAsArray = Array.from(value); + return querystringSingleKey(key, valueAsArray, keyPrefix); + } + if (value instanceof Date) { + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`; + } + if (value instanceof Object) { + return querystring(value as HTTPQuery, fullKey); + } + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; +} + +export function exists(json: any, key: string) { + const value = json[key]; + return value !== null && value !== undefined; +} + +export function mapValues(data: any, fn: (item: any) => any) { + const result: { [key: string]: any } = {}; + for (const key of Object.keys(data)) { + result[key] = fn(data[key]); + } + return result; +} + +export function canConsumeForm(consumes: Consume[]): boolean { + for (const consume of consumes) { + if ('multipart/form-data' === consume.contentType) { + return true; + } + } + return false; +} + +export interface Consume { + contentType: string; +} + +export interface RequestContext { + fetch: FetchAPI; + url: string; + init: RequestInit; +} + +export interface ResponseContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + response: Response; +} + +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + +export interface Middleware { + pre?(context: RequestContext): Promise; + post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; +} + +export interface ApiResponse { + raw: Response; + value(): Promise; +} + +export interface ResponseTransformer { + (json: any): T; +} + +export class JSONApiResponse { + constructor(public raw: Response, private transformer: ResponseTransformer = (jsonValue: any) => jsonValue) {} + + async value(): Promise { + return this.transformer(await this.raw.json()); + } +} + +export class VoidApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return undefined; + } +} + +export class BlobApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.blob(); + }; +} + +export class TextApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.text(); + }; +} diff --git a/packages/rest-api-sdk/src/index.ts b/packages/rest-api-sdk/src/index.ts new file mode 100644 index 00000000..af774940 --- /dev/null +++ b/packages/rest-api-sdk/src/index.ts @@ -0,0 +1,3 @@ +export type { AppScopedApi } from "./api"; +export { Api, createAppClient, ReflagApiError } from "./api"; +export * from "./generated"; diff --git a/packages/rest-api-sdk/test/api.test.ts b/packages/rest-api-sdk/test/api.test.ts new file mode 100644 index 00000000..7d1f0031 --- /dev/null +++ b/packages/rest-api-sdk/test/api.test.ts @@ -0,0 +1,93 @@ +import { describe, expect, it, vi } from "vitest"; + +import { Api, ReflagApiError } from "../src/api"; + +describe("Api error normalization", () => { + it("maps JSON API errors to ReflagApiError", async () => { + const fetchApi = vi.fn( + async (_input: RequestInfo | URL, _init?: RequestInit) => + new Response( + JSON.stringify({ + error: { + message: "Bad request payload", + code: "INVALID_REQUEST", + }, + }), + { + status: 400, + headers: { "Content-Type": "application/json" }, + }, + ), + ); + + const api = new Api({ + basePath: "https://example.test", + accessToken: "test-token", + fetchApi, + }); + + const error = await api.listApps().catch((e) => e); + expect(error).toBeInstanceOf(ReflagApiError); + expect(error).toMatchObject({ + status: 400, + message: "Bad request payload", + code: "INVALID_REQUEST", + }); + expect(error.details).toEqual({ + error: { + message: "Bad request payload", + code: "INVALID_REQUEST", + }, + }); + }); + + it("maps text errors to ReflagApiError with text details", async () => { + const fetchApi = vi.fn( + async (_input: RequestInfo | URL, _init?: RequestInit) => + new Response("Service unavailable", { + status: 503, + headers: { "Content-Type": "text/plain" }, + }), + ); + + const api = new Api({ + basePath: "https://example.test", + accessToken: "test-token", + fetchApi, + }); + + const error = await api.listApps().catch((e) => e); + expect(error).toBeInstanceOf(ReflagApiError); + expect(error).toMatchObject({ + status: 503, + message: "Request failed with 503: Service unavailable", + code: undefined, + details: "Service unavailable", + }); + }); + + it("handles invalid JSON error bodies safely", async () => { + const fetchApi = vi.fn( + async (_input: RequestInfo | URL, _init?: RequestInit) => + new Response("{not-json", { + status: 500, + headers: { "Content-Type": "application/json" }, + }), + ); + + const api = new Api({ + basePath: "https://example.test", + accessToken: "test-token", + fetchApi, + }); + + const error = await api.listApps().catch((e) => e); + expect(error).toBeInstanceOf(ReflagApiError); + expect(error).toMatchObject({ + status: 500, + message: "Request failed with 500", + code: undefined, + details: undefined, + }); + }); +}); diff --git a/packages/rest-api-sdk/test/createAppClient.test.ts b/packages/rest-api-sdk/test/createAppClient.test.ts new file mode 100644 index 00000000..bad23f57 --- /dev/null +++ b/packages/rest-api-sdk/test/createAppClient.test.ts @@ -0,0 +1,106 @@ +import { describe, expect, it, vi } from "vitest"; + +import { createAppClient } from "../src/api"; +import type { Middleware } from "../src/generated/runtime"; + +const listFlagsResponse = { + data: [], + totalCount: 0, + pageSize: 0, + pageIndex: 0, + sortBy: "name", + sortOrder: "asc", +}; + +type ScopedListFlagsClient = { + listFlags(args: Record): Promise; +}; + +describe("createAppClient", () => { + it("preserves app scoping after withPreMiddleware", async () => { + const fetchApi = vi.fn( + async (_input: RequestInfo | URL, _init?: RequestInit) => + new Response(JSON.stringify(listFlagsResponse), { + status: 200, + headers: { "Content-Type": "application/json" }, + }), + ); + const client = createAppClient("app-123", { + basePath: "https://example.test", + fetchApi, + }); + + const withPre = client.withPreMiddleware(async ({ url, init }) => ({ + url, + init, + })); + + await expect( + (withPre as unknown as ScopedListFlagsClient).listFlags({}), + ).resolves.toEqual(listFlagsResponse); + expect(fetchApi).toHaveBeenCalledTimes(1); + expect(String(fetchApi.mock.calls[0]?.[0])).toBe( + "https://example.test/apps/app-123/flags", + ); + }); + + it("preserves app scoping after withMiddleware", async () => { + const fetchApi = vi.fn( + async (_input: RequestInfo | URL, _init?: RequestInit) => + new Response(JSON.stringify(listFlagsResponse), { + status: 200, + headers: { "Content-Type": "application/json" }, + }), + ); + const client = createAppClient("app-123", { + basePath: "https://example.test", + fetchApi, + }); + const middleware: Middleware = { + pre: vi.fn(async ({ url, init }) => ({ url, init })), + }; + + const withMiddleware = client.withMiddleware(middleware); + + await expect( + (withMiddleware as unknown as ScopedListFlagsClient).listFlags({}), + ).resolves.toEqual(listFlagsResponse); + expect(middleware.pre).toHaveBeenCalledTimes(1); + expect(fetchApi).toHaveBeenCalledTimes(1); + expect(String(fetchApi.mock.calls[0]?.[0])).toBe( + "https://example.test/apps/app-123/flags", + ); + }); + + it("preserves class-based middleware hooks after withMiddleware", async () => { + const fetchApi = vi.fn( + async (_input: RequestInfo | URL, _init?: RequestInit) => + new Response(JSON.stringify(listFlagsResponse), { + status: 200, + headers: { "Content-Type": "application/json" }, + }), + ); + const client = createAppClient("app-123", { + basePath: "https://example.test", + fetchApi, + }); + + class PrototypePreMiddleware implements Middleware { + preCalls = 0; + + async pre({ url, init }: { url: string; init: RequestInit }) { + this.preCalls += 1; + return { url, init }; + } + } + + const middleware = new PrototypePreMiddleware(); + const withMiddleware = client.withMiddleware(middleware); + + await expect( + (withMiddleware as unknown as ScopedListFlagsClient).listFlags({}), + ).resolves.toEqual(listFlagsResponse); + expect(middleware.preCalls).toBe(1); + expect(fetchApi).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/rest-api-sdk/tsconfig.build.json b/packages/rest-api-sdk/tsconfig.build.json new file mode 100644 index 00000000..daa1b256 --- /dev/null +++ b/packages/rest-api-sdk/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noUnusedLocals": false, + "noUnusedParameters": false + }, + "include": ["src"] +} diff --git a/packages/rest-api-sdk/tsconfig.eslint.json b/packages/rest-api-sdk/tsconfig.eslint.json new file mode 100644 index 00000000..8f51c5d7 --- /dev/null +++ b/packages/rest-api-sdk/tsconfig.eslint.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["./src", "./test", "./*.ts"] +} diff --git a/packages/rest-api-sdk/tsconfig.json b/packages/rest-api-sdk/tsconfig.json new file mode 100644 index 00000000..af496590 --- /dev/null +++ b/packages/rest-api-sdk/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@reflag/tsconfig/library", + "compilerOptions": { + "lib": ["ES2020", "DOM"], + "outDir": "./dist/", + "declarationDir": "./dist/types", + "declarationMap": true, + "noUncheckedIndexedAccess": true + }, + "include": ["src"], + "typeRoots": ["./node_modules/@types"] +} diff --git a/yarn.lock b/yarn.lock index f19683f8..d52de854 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1735,6 +1735,13 @@ __metadata: languageName: node linkType: hard +"@borewit/text-codec@npm:^0.2.1": + version: 0.2.1 + resolution: "@borewit/text-codec@npm:0.2.1" + checksum: 10c0/aabd9c86497197aacc9ddb413857f112a98a9fd4be9ed56a24971a47bbec7c0d5d449efcad830f9895009c1a5914e5c448f972a0c968e97c4ebf99297dea7a6b + languageName: node + linkType: hard + "@bundled-es-modules/cookie@npm:^2.0.0": version: 2.0.0 resolution: "@bundled-es-modules/cookie@npm:2.0.0" @@ -2195,6 +2202,15 @@ __metadata: languageName: node linkType: hard +"@emnapi/runtime@npm:^1.7.0": + version: 1.8.1 + resolution: "@emnapi/runtime@npm:1.8.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/f4929d75e37aafb24da77d2f58816761fe3f826aad2e37fa6d4421dac9060cbd5098eea1ac3c9ecc4526b89deb58153852fa432f87021dc57863f2ff726d713f + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/aix-ppc64@npm:0.21.5" @@ -2567,6 +2583,13 @@ __metadata: languageName: node linkType: hard +"@eslint-community/regexpp@npm:^4.6.1": + version: 4.12.2 + resolution: "@eslint-community/regexpp@npm:4.12.2" + checksum: 10c0/fddcbc66851b308478d04e302a4d771d6917a0b3740dc351513c0da9ca2eab8a1adf99f5e0aa7ab8b13fa0df005c81adeee7e63a92f3effd7d367a163b721c2d + languageName: node + linkType: hard + "@eslint/config-array@npm:^0.19.2": version: 0.19.2 resolution: "@eslint/config-array@npm:0.19.2" @@ -2616,6 +2639,23 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/eslintrc@npm:2.1.4" + dependencies: + ajv: "npm:^6.12.4" + debug: "npm:^4.3.2" + espree: "npm:^9.6.0" + globals: "npm:^13.19.0" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^4.1.0" + minimatch: "npm:^3.1.2" + strip-json-comments: "npm:^3.1.1" + checksum: 10c0/32f67052b81768ae876c84569ffd562491ec5a5091b0c1e1ca1e0f3c24fb42f804952fdd0a137873bc64303ba368a71ba079a6f691cee25beee9722d94cc8573 + languageName: node + linkType: hard + "@eslint/eslintrc@npm:^3.3.0": version: 3.3.0 resolution: "@eslint/eslintrc@npm:3.3.0" @@ -2650,6 +2690,13 @@ __metadata: languageName: node linkType: hard +"@eslint/js@npm:8.57.1": + version: 8.57.1 + resolution: "@eslint/js@npm:8.57.1" + checksum: 10c0/b489c474a3b5b54381c62e82b3f7f65f4b8a5eaaed126546520bf2fede5532a8ed53212919fed1e9048dcf7f37167c8561d58d0ba4492a4244004e7793805223 + languageName: node + linkType: hard + "@eslint/js@npm:9.21.0, @eslint/js@npm:^9.21.0": version: 9.21.0 resolution: "@eslint/js@npm:9.21.0" @@ -3166,6 +3213,17 @@ __metadata: languageName: node linkType: hard +"@humanwhocodes/config-array@npm:^0.13.0": + version: 0.13.0 + resolution: "@humanwhocodes/config-array@npm:0.13.0" + dependencies: + "@humanwhocodes/object-schema": "npm:^2.0.3" + debug: "npm:^4.3.1" + minimatch: "npm:^3.0.5" + checksum: 10c0/205c99e756b759f92e1f44a3dc6292b37db199beacba8f26c2165d4051fe73a4ae52fdcfd08ffa93e7e5cb63da7c88648f0e84e197d154bbbbe137b2e0dd332e + languageName: node + linkType: hard + "@humanwhocodes/module-importer@npm:^1.0.1": version: 1.0.1 resolution: "@humanwhocodes/module-importer@npm:1.0.1" @@ -3173,6 +3231,13 @@ __metadata: languageName: node linkType: hard +"@humanwhocodes/object-schema@npm:^2.0.3": + version: 2.0.3 + resolution: "@humanwhocodes/object-schema@npm:2.0.3" + checksum: 10c0/80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c + languageName: node + linkType: hard + "@humanwhocodes/retry@npm:^0.3.0": version: 0.3.1 resolution: "@humanwhocodes/retry@npm:0.3.1" @@ -3194,6 +3259,233 @@ __metadata: languageName: node linkType: hard +"@img/colour@npm:^1.0.0": + version: 1.1.0 + resolution: "@img/colour@npm:1.1.0" + checksum: 10c0/2ebea2c0bbaee73b99badcefa04e1e71d83f36e5369337d3121dca841f4569533c4e2faddda6d62dd247f0d5cca143711f9446c59bcce81e427ba433a7a94a17 + languageName: node + linkType: hard + +"@img/sharp-darwin-arm64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-darwin-arm64@npm:0.34.5" + dependencies: + "@img/sharp-libvips-darwin-arm64": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-darwin-arm64": + optional: true + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-darwin-x64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-darwin-x64@npm:0.34.5" + dependencies: + "@img/sharp-libvips-darwin-x64": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-darwin-x64": + optional: true + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@img/sharp-libvips-darwin-arm64@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-darwin-arm64@npm:1.2.4" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-libvips-darwin-x64@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-darwin-x64@npm:1.2.4" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-arm64@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-linux-arm64@npm:1.2.4" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-arm@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-linux-arm@npm:1.2.4" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-ppc64@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-linux-ppc64@npm:1.2.4" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-riscv64@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-linux-riscv64@npm:1.2.4" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-s390x@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-linux-s390x@npm:1.2.4" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-x64@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-linux-x64@npm:1.2.4" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linuxmusl-arm64@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.2.4" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-libvips-linuxmusl-x64@npm:1.2.4": + version: 1.2.4 + resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.2.4" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-linux-arm64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-linux-arm64@npm:0.34.5" + dependencies: + "@img/sharp-libvips-linux-arm64": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-linux-arm64": + optional: true + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-arm@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-linux-arm@npm:0.34.5" + dependencies: + "@img/sharp-libvips-linux-arm": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-linux-arm": + optional: true + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-ppc64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-linux-ppc64@npm:0.34.5" + dependencies: + "@img/sharp-libvips-linux-ppc64": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-linux-ppc64": + optional: true + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-riscv64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-linux-riscv64@npm:0.34.5" + dependencies: + "@img/sharp-libvips-linux-riscv64": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-linux-riscv64": + optional: true + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-s390x@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-linux-s390x@npm:0.34.5" + dependencies: + "@img/sharp-libvips-linux-s390x": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-linux-s390x": + optional: true + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-x64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-linux-x64@npm:0.34.5" + dependencies: + "@img/sharp-libvips-linux-x64": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-linux-x64": + optional: true + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linuxmusl-arm64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-linuxmusl-arm64@npm:0.34.5" + dependencies: + "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-linuxmusl-arm64": + optional: true + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-linuxmusl-x64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-linuxmusl-x64@npm:0.34.5" + dependencies: + "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.4" + dependenciesMeta: + "@img/sharp-libvips-linuxmusl-x64": + optional: true + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-wasm32@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-wasm32@npm:0.34.5" + dependencies: + "@emnapi/runtime": "npm:^1.7.0" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@img/sharp-win32-arm64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-win32-arm64@npm:0.34.5" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-win32-ia32@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-win32-ia32@npm:0.34.5" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@img/sharp-win32-x64@npm:0.34.5": + version: 0.34.5 + resolution: "@img/sharp-win32-x64@npm:0.34.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@inquirer/ansi@npm:^1.0.1": version: 1.0.1 resolution: "@inquirer/ansi@npm:1.0.1" @@ -3265,6 +3557,28 @@ __metadata: languageName: node linkType: hard +"@inquirer/core@npm:^6.0.0": + version: 6.0.0 + resolution: "@inquirer/core@npm:6.0.0" + dependencies: + "@inquirer/type": "npm:^1.1.6" + "@types/mute-stream": "npm:^0.0.4" + "@types/node": "npm:^20.10.7" + "@types/wrap-ansi": "npm:^3.0.0" + ansi-escapes: "npm:^4.3.2" + chalk: "npm:^4.1.2" + cli-spinners: "npm:^2.9.2" + cli-width: "npm:^4.1.0" + figures: "npm:^3.2.0" + mute-stream: "npm:^1.0.0" + run-async: "npm:^3.0.0" + signal-exit: "npm:^4.1.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^6.2.0" + checksum: 10c0/0663330936c9baea58d8a10e93de6c3446ab84ed909c41d7b3f6762842473b8f88e10d776326d89a278abfb3c4083240d0f5876293908eb1005d0026aa2cfb7d + languageName: node + linkType: hard + "@inquirer/core@npm:^9.0.5": version: 9.0.5 resolution: "@inquirer/core@npm:9.0.5" @@ -3449,6 +3763,19 @@ __metadata: languageName: node linkType: hard +"@inquirer/select@npm:1.3.3": + version: 1.3.3 + resolution: "@inquirer/select@npm:1.3.3" + dependencies: + "@inquirer/core": "npm:^6.0.0" + "@inquirer/type": "npm:^1.1.6" + ansi-escapes: "npm:^4.3.2" + chalk: "npm:^4.1.2" + figures: "npm:^3.2.0" + checksum: 10c0/695de7dc85bf1b4ae4d13bbacb39e73cf4ff12f04da5cff4f0cc046db6bb32ff6051d30753a94299370908051133535e0db7e011e3b61e9806908eb1a7ef6b39 + languageName: node + linkType: hard + "@inquirer/select@npm:^4.4.0": version: 4.4.0 resolution: "@inquirer/select@npm:4.4.0" @@ -3467,6 +3794,15 @@ __metadata: languageName: node linkType: hard +"@inquirer/type@npm:^1.1.6": + version: 1.5.5 + resolution: "@inquirer/type@npm:1.5.5" + dependencies: + mute-stream: "npm:^1.0.0" + checksum: 10c0/4c41736c09ba9426b5a9e44993bdd54e8f532e791518802e33866f233a2a6126a25c1c82c19d1abbf1df627e57b1b957dd3f8318ea96073d8bfc32193943bcb3 + languageName: node + linkType: hard + "@inquirer/type@npm:^1.5.1": version: 1.5.1 resolution: "@inquirer/type@npm:1.5.1" @@ -3834,6 +4170,13 @@ __metadata: languageName: node linkType: hard +"@lukeed/csprng@npm:^1.0.0": + version: 1.1.0 + resolution: "@lukeed/csprng@npm:1.1.0" + checksum: 10c0/5d6dcf478af732972083ab2889c294b57f1028fa13c2c240d7a4aaa079c2c75df7ef0dcbdda5419147fc6704b4adf96b2de92f1a9a72ac21c6350c4014fffe6c + languageName: node + linkType: hard + "@mdn/browser-compat-data@npm:^5.3.13, @mdn/browser-compat-data@npm:^5.6.19": version: 5.7.6 resolution: "@mdn/browser-compat-data@npm:5.7.6" @@ -4028,6 +4371,68 @@ __metadata: languageName: node linkType: hard +"@nestjs/axios@npm:4.0.1": + version: 4.0.1 + resolution: "@nestjs/axios@npm:4.0.1" + peerDependencies: + "@nestjs/common": ^10.0.0 || ^11.0.0 + axios: ^1.3.1 + rxjs: ^7.0.0 + checksum: 10c0/6290f6ceaab2ea1000ee705dfd81da8cd776eb9fb388287a74a4faecf0afd8a8cdef7f6cc3afe2a9b10e47067df027280ca1ddb75b7885ff365e2faed37b10c7 + languageName: node + linkType: hard + +"@nestjs/common@npm:11.1.14": + version: 11.1.14 + resolution: "@nestjs/common@npm:11.1.14" + dependencies: + file-type: "npm:21.3.0" + iterare: "npm:1.2.1" + load-esm: "npm:1.0.3" + tslib: "npm:2.8.1" + uid: "npm:2.0.2" + peerDependencies: + class-transformer: ">=0.4.1" + class-validator: ">=0.13.2" + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + checksum: 10c0/bba35fabdc350dfd362009e15a2cb6b660a53325ee6c1863f04667df0201b51b334226ace2985505969727aaf5b494396dd33f682ce75d0f3b1cab1d206a11e9 + languageName: node + linkType: hard + +"@nestjs/core@npm:11.1.14": + version: 11.1.14 + resolution: "@nestjs/core@npm:11.1.14" + dependencies: + "@nuxt/opencollective": "npm:0.4.1" + fast-safe-stringify: "npm:2.1.1" + iterare: "npm:1.2.1" + path-to-regexp: "npm:8.3.0" + tslib: "npm:2.8.1" + uid: "npm:2.0.2" + peerDependencies: + "@nestjs/common": ^11.0.0 + "@nestjs/microservices": ^11.0.0 + "@nestjs/platform-express": ^11.0.0 + "@nestjs/websockets": ^11.0.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + "@nestjs/microservices": + optional: true + "@nestjs/platform-express": + optional: true + "@nestjs/websockets": + optional: true + checksum: 10c0/842c8048fb83bc6df70975d91ec357bacb6d2cc42791e709d122fda16c6343d279cf9f4ec88c5427b02de5c3f40f3271b9c62367c662c39cdad838b5962669e9 + languageName: node + linkType: hard + "@next/env@npm:14.2.26": version: 14.2.26 resolution: "@next/env@npm:14.2.26" @@ -4035,6 +4440,27 @@ __metadata: languageName: node linkType: hard +"@next/env@npm:14.2.5": + version: 14.2.5 + resolution: "@next/env@npm:14.2.5" + checksum: 10c0/63d8b88ac450b3c37940a9e2119a63a1074aca89908574ade6157a8aa295275dcb3ac5f69e00883fc55d0f12963b73b74e87ba32a5768a489f9609c6be57b699 + languageName: node + linkType: hard + +"@next/env@npm:15.5.10": + version: 15.5.10 + resolution: "@next/env@npm:15.5.10" + checksum: 10c0/fb26c299ff388a3a0b2d14379616e3e59fe7960002e5aa67be4d195a377b9803fb93dd90067a5eb7d889d6f437aff091171701eec0e8d201666160269dda4e95 + languageName: node + linkType: hard + +"@next/env@npm:16.1.5": + version: 16.1.5 + resolution: "@next/env@npm:16.1.5" + checksum: 10c0/9d6442bee75386593d5da6e952146cf3c4338202e68a0ba9464d70c24ab7abb0c7e4ecd0ab661ca211e544fe7d6bd075270379bee3e97c5da3b6d082f95a04cd + languageName: node + linkType: hard + "@next/eslint-plugin-next@npm:14.2.5": version: 14.2.5 resolution: "@next/eslint-plugin-next@npm:14.2.5" @@ -4051,6 +4477,27 @@ __metadata: languageName: node linkType: hard +"@next/swc-darwin-arm64@npm:14.2.5": + version: 14.2.5 + resolution: "@next/swc-darwin-arm64@npm:14.2.5" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@next/swc-darwin-arm64@npm:15.5.7": + version: 15.5.7 + resolution: "@next/swc-darwin-arm64@npm:15.5.7" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@next/swc-darwin-arm64@npm:16.1.5": + version: 16.1.5 + resolution: "@next/swc-darwin-arm64@npm:16.1.5" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@next/swc-darwin-x64@npm:14.2.26": version: 14.2.26 resolution: "@next/swc-darwin-x64@npm:14.2.26" @@ -4058,6 +4505,27 @@ __metadata: languageName: node linkType: hard +"@next/swc-darwin-x64@npm:14.2.5": + version: 14.2.5 + resolution: "@next/swc-darwin-x64@npm:14.2.5" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@next/swc-darwin-x64@npm:15.5.7": + version: 15.5.7 + resolution: "@next/swc-darwin-x64@npm:15.5.7" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@next/swc-darwin-x64@npm:16.1.5": + version: 16.1.5 + resolution: "@next/swc-darwin-x64@npm:16.1.5" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@next/swc-linux-arm64-gnu@npm:14.2.26": version: 14.2.26 resolution: "@next/swc-linux-arm64-gnu@npm:14.2.26" @@ -4065,6 +4533,27 @@ __metadata: languageName: node linkType: hard +"@next/swc-linux-arm64-gnu@npm:14.2.5": + version: 14.2.5 + resolution: "@next/swc-linux-arm64-gnu@npm:14.2.5" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@next/swc-linux-arm64-gnu@npm:15.5.7": + version: 15.5.7 + resolution: "@next/swc-linux-arm64-gnu@npm:15.5.7" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@next/swc-linux-arm64-gnu@npm:16.1.5": + version: 16.1.5 + resolution: "@next/swc-linux-arm64-gnu@npm:16.1.5" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@next/swc-linux-arm64-musl@npm:14.2.26": version: 14.2.26 resolution: "@next/swc-linux-arm64-musl@npm:14.2.26" @@ -4072,6 +4561,27 @@ __metadata: languageName: node linkType: hard +"@next/swc-linux-arm64-musl@npm:14.2.5": + version: 14.2.5 + resolution: "@next/swc-linux-arm64-musl@npm:14.2.5" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@next/swc-linux-arm64-musl@npm:15.5.7": + version: 15.5.7 + resolution: "@next/swc-linux-arm64-musl@npm:15.5.7" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@next/swc-linux-arm64-musl@npm:16.1.5": + version: 16.1.5 + resolution: "@next/swc-linux-arm64-musl@npm:16.1.5" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@next/swc-linux-x64-gnu@npm:14.2.26": version: 14.2.26 resolution: "@next/swc-linux-x64-gnu@npm:14.2.26" @@ -4079,6 +4589,27 @@ __metadata: languageName: node linkType: hard +"@next/swc-linux-x64-gnu@npm:14.2.5": + version: 14.2.5 + resolution: "@next/swc-linux-x64-gnu@npm:14.2.5" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@next/swc-linux-x64-gnu@npm:15.5.7": + version: 15.5.7 + resolution: "@next/swc-linux-x64-gnu@npm:15.5.7" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@next/swc-linux-x64-gnu@npm:16.1.5": + version: 16.1.5 + resolution: "@next/swc-linux-x64-gnu@npm:16.1.5" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@next/swc-linux-x64-musl@npm:14.2.26": version: 14.2.26 resolution: "@next/swc-linux-x64-musl@npm:14.2.26" @@ -4086,6 +4617,27 @@ __metadata: languageName: node linkType: hard +"@next/swc-linux-x64-musl@npm:14.2.5": + version: 14.2.5 + resolution: "@next/swc-linux-x64-musl@npm:14.2.5" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@next/swc-linux-x64-musl@npm:15.5.7": + version: 15.5.7 + resolution: "@next/swc-linux-x64-musl@npm:15.5.7" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@next/swc-linux-x64-musl@npm:16.1.5": + version: 16.1.5 + resolution: "@next/swc-linux-x64-musl@npm:16.1.5" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@next/swc-win32-arm64-msvc@npm:14.2.26": version: 14.2.26 resolution: "@next/swc-win32-arm64-msvc@npm:14.2.26" @@ -4093,6 +4645,27 @@ __metadata: languageName: node linkType: hard +"@next/swc-win32-arm64-msvc@npm:14.2.5": + version: 14.2.5 + resolution: "@next/swc-win32-arm64-msvc@npm:14.2.5" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@next/swc-win32-arm64-msvc@npm:15.5.7": + version: 15.5.7 + resolution: "@next/swc-win32-arm64-msvc@npm:15.5.7" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@next/swc-win32-arm64-msvc@npm:16.1.5": + version: 16.1.5 + resolution: "@next/swc-win32-arm64-msvc@npm:16.1.5" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@next/swc-win32-ia32-msvc@npm:14.2.26": version: 14.2.26 resolution: "@next/swc-win32-ia32-msvc@npm:14.2.26" @@ -4100,6 +4673,13 @@ __metadata: languageName: node linkType: hard +"@next/swc-win32-ia32-msvc@npm:14.2.5": + version: 14.2.5 + resolution: "@next/swc-win32-ia32-msvc@npm:14.2.5" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@next/swc-win32-x64-msvc@npm:14.2.26": version: 14.2.26 resolution: "@next/swc-win32-x64-msvc@npm:14.2.26" @@ -4107,6 +4687,27 @@ __metadata: languageName: node linkType: hard +"@next/swc-win32-x64-msvc@npm:14.2.5": + version: 14.2.5 + resolution: "@next/swc-win32-x64-msvc@npm:14.2.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@next/swc-win32-x64-msvc@npm:15.5.7": + version: 15.5.7 + resolution: "@next/swc-win32-x64-msvc@npm:15.5.7" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@next/swc-win32-x64-msvc@npm:16.1.5": + version: 16.1.5 + resolution: "@next/swc-win32-x64-msvc@npm:16.1.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1": version: 5.1.1-v1 resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1" @@ -4133,7 +4734,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3": +"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -4285,6 +4886,30 @@ __metadata: languageName: node linkType: hard +"@nuxt/opencollective@npm:0.4.1": + version: 0.4.1 + resolution: "@nuxt/opencollective@npm:0.4.1" + dependencies: + consola: "npm:^3.2.3" + bin: + opencollective: bin/opencollective.js + checksum: 10c0/ef2835d8635d2928152eff8b5a1ec42c145e2ab00cb02ff4bb61f0a6f5528afc9b169c06c32308c783779fe26855ebc67419743046caa80e582e814cff73187d + languageName: node + linkType: hard + +"@nuxtjs/opencollective@npm:0.3.2": + version: 0.3.2 + resolution: "@nuxtjs/opencollective@npm:0.3.2" + dependencies: + chalk: "npm:^4.1.0" + consola: "npm:^2.15.0" + node-fetch: "npm:^2.6.1" + bin: + opencollective: bin/opencollective.js + checksum: 10c0/540268687af3289ff107585484d42201b404cdbb98b3a512487c12a6b180a8f0e1df0d701df47d3d9e0d5c0f6eb3252d80535562aedca9edf52cf7fd17ae4601 + languageName: node + linkType: hard + "@nx/devkit@npm:19.0.4, @nx/devkit@npm:>=17.1.2 < 20": version: 19.0.4 resolution: "@nx/devkit@npm:19.0.4" @@ -4557,6 +5182,33 @@ __metadata: languageName: node linkType: hard +"@openapitools/openapi-generator-cli@npm:^2.13.5": + version: 2.30.0 + resolution: "@openapitools/openapi-generator-cli@npm:2.30.0" + dependencies: + "@inquirer/select": "npm:1.3.3" + "@nestjs/axios": "npm:4.0.1" + "@nestjs/common": "npm:11.1.14" + "@nestjs/core": "npm:11.1.14" + "@nuxtjs/opencollective": "npm:0.3.2" + axios: "npm:1.13.5" + chalk: "npm:4.1.2" + commander: "npm:8.3.0" + compare-versions: "npm:6.1.1" + concurrently: "npm:9.2.1" + console.table: "npm:0.10.0" + fs-extra: "npm:11.3.3" + glob: "npm:13.0.6" + proxy-agent: "npm:6.5.0" + reflect-metadata: "npm:0.2.2" + rxjs: "npm:7.8.2" + tslib: "npm:2.8.1" + bin: + openapi-generator-cli: main.js + checksum: 10c0/dc0830dfafee27a4243eb3cce58ee179fea44adbb05889ab5d95a7123679a34b47c90c776dabae42ce7932d3919ea1f9d8da2773bbbd0a742cb60332e11293ea + languageName: node + linkType: hard + "@openfeature/core@npm:1.3.0": version: 1.3.0 resolution: "@openfeature/core@npm:1.3.0" @@ -5149,7 +5801,7 @@ __metadata: languageName: node linkType: hard -"@reflag/node-sdk@workspace:packages/node-sdk": +"@reflag/node-sdk@workspace:^, @reflag/node-sdk@workspace:packages/node-sdk": version: 0.0.0-use.local resolution: "@reflag/node-sdk@workspace:packages/node-sdk" dependencies: @@ -5273,6 +5925,22 @@ __metadata: languageName: unknown linkType: soft +"@reflag/rest-api-sdk@workspace:*, @reflag/rest-api-sdk@workspace:packages/rest-api-sdk": + version: 0.0.0-use.local + resolution: "@reflag/rest-api-sdk@workspace:packages/rest-api-sdk" + dependencies: + "@openapitools/openapi-generator-cli": "npm:^2.13.5" + "@reflag/eslint-config": "npm:~0.0.2" + "@reflag/tsconfig": "npm:~0.0.2" + "@types/node": "npm:^22.12.0" + "@vitest/coverage-v8": "npm:~1.6.0" + eslint: "npm:^9.21.0" + prettier: "npm:^3.5.2" + typescript: "npm:^5.7.3" + vitest: "npm:~1.6.0" + languageName: unknown + linkType: soft + "@reflag/tsconfig@npm:0.0.2, @reflag/tsconfig@npm:^0.0.2, @reflag/tsconfig@npm:~0.0.2, @reflag/tsconfig@workspace:packages/tsconfig": version: 0.0.0-use.local resolution: "@reflag/tsconfig@workspace:packages/tsconfig" @@ -5869,6 +6537,15 @@ __metadata: languageName: node linkType: hard +"@swc/helpers@npm:0.5.15": + version: 0.5.15 + resolution: "@swc/helpers@npm:0.5.15" + dependencies: + tslib: "npm:^2.8.0" + checksum: 10c0/33002f74f6f885f04c132960835fdfc474186983ea567606db62e86acd0680ca82f34647e8e610f4e1e422d1c16fce729dde22cd3b797ab1fd9061a825dabca4 + languageName: node + linkType: hard + "@swc/helpers@npm:0.5.5": version: 0.5.5 resolution: "@swc/helpers@npm:0.5.5" @@ -5913,6 +6590,23 @@ __metadata: languageName: node linkType: hard +"@tokenizer/inflate@npm:^0.4.1": + version: 0.4.1 + resolution: "@tokenizer/inflate@npm:0.4.1" + dependencies: + debug: "npm:^4.4.3" + token-types: "npm:^6.1.1" + checksum: 10c0/9817516efe21d1ce3bdfb80a1f94efc8981064ce3873448ba79f4d81d96c0694c484c289bd042d346ae5536cf77f5aa9a367d39c3df700eb610761b7c306b4de + languageName: node + linkType: hard + +"@tokenizer/token@npm:^0.3.0": + version: 0.3.0 + resolution: "@tokenizer/token@npm:0.3.0" + checksum: 10c0/7ab9a822d4b5ff3f5bca7f7d14d46bdd8432528e028db4a52be7fbf90c7f495cc1af1324691dda2813c6af8dc4b8eb29de3107d4508165f9aa5b53e7d501f155 + languageName: node + linkType: hard + "@tootallnate/once@npm:2": version: 2.0.0 resolution: "@tootallnate/once@npm:2.0.0" @@ -5920,6 +6614,13 @@ __metadata: languageName: node linkType: hard +"@tootallnate/quickjs-emscripten@npm:^0.23.0": + version: 0.23.0 + resolution: "@tootallnate/quickjs-emscripten@npm:0.23.0" + checksum: 10c0/2a939b781826fb5fd3edd0f2ec3b321d259d760464cf20611c9877205aaca3ccc0b7304dea68416baa0d568e82cd86b17d29548d1e5139fa3155a4a86a2b4b49 + languageName: node + linkType: hard + "@tsconfig/node10@npm:^1.0.7": version: 1.0.8 resolution: "@tsconfig/node10@npm:1.0.8" @@ -6248,6 +6949,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20.10.7": + version: 20.19.35 + resolution: "@types/node@npm:20.19.35" + dependencies: + undici-types: "npm:~6.21.0" + checksum: 10c0/e27d3e1eac4105b627fdba2d86577e603c66fc7b4ad61418d41f3898d84b2f5ff3e0c6b6d3948b34976ea91056e6359740b387edcc65ca516c3f2b5a0c0f9c6a + languageName: node + linkType: hard + "@types/node@npm:^20.14.11": version: 20.14.11 resolution: "@types/node@npm:20.14.11" @@ -6622,7 +7332,7 @@ __metadata: languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.3.0": +"@ungap/structured-clone@npm:^1.2.0, @ungap/structured-clone@npm:^1.3.0": version: 1.3.0 resolution: "@ungap/structured-clone@npm:1.3.0" checksum: 10c0/0fc3097c2540ada1fc340ee56d58d96b5b536a2a0dab6e3ec17d4bfc8c4c86db345f61a375a8185f9da96f01c69678f836a2b57eeaa9e4b8eeafd26428e57b0a @@ -8264,6 +8974,15 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:^0.13.4": + version: 0.13.4 + resolution: "ast-types@npm:0.13.4" + dependencies: + tslib: "npm:^2.0.1" + checksum: 10c0/3a1a409764faa1471601a0ad01b3aa699292991aa9c8a30c7717002cabdf5d98008e7b53ae61f6e058f757fc6ba965e147967a93c13e62692c907d79cfb245f8 + languageName: node + linkType: hard + "astral-regex@npm:^1.0.0": version: 1.0.0 resolution: "astral-regex@npm:1.0.0" @@ -8342,6 +9061,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:1.13.5": + version: 1.13.5 + resolution: "axios@npm:1.13.5" + dependencies: + follow-redirects: "npm:^1.15.11" + form-data: "npm:^4.0.5" + proxy-from-env: "npm:^1.1.0" + checksum: 10c0/abf468c34f2d145f3dc7dbc0f1be67e520630624307bda69a41bbe8d386bd672d87b4405c4ee77f9ff54b235ab02f96a9968fb00e75b13ce64706e352a3068fd + languageName: node + linkType: hard + "axios@npm:^1.6.0": version: 1.8.4 resolution: "axios@npm:1.8.4" @@ -8557,6 +9287,13 @@ __metadata: languageName: node linkType: hard +"balanced-match@npm:^4.0.2": + version: 4.0.4 + resolution: "balanced-match@npm:4.0.4" + checksum: 10c0/07e86102a3eb2ee2a6a1a89164f29d0dbaebd28f2ca3f5ca786f36b8b23d9e417eb3be45a4acf754f837be5ac0a2317de90d3fcb7f4f4dc95720a1f36b26a17b + languageName: node + linkType: hard + "base64-js@npm:^1.2.3, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -8564,6 +9301,15 @@ __metadata: languageName: node linkType: hard +"baseline-browser-mapping@npm:^2.8.3": + version: 2.10.0 + resolution: "baseline-browser-mapping@npm:2.10.0" + bin: + baseline-browser-mapping: dist/cli.cjs + checksum: 10c0/da9c3ec0fcd7f325226a47d2142794d41706b6e0a405718a2c15410bbdb72aacadd65738bedef558c6f1b106ed19458cb25b06f63b66df2c284799905dbbd003 + languageName: node + linkType: hard + "baseline-browser-mapping@npm:^2.9.0": version: 2.9.19 resolution: "baseline-browser-mapping@npm:2.9.19" @@ -8582,6 +9328,13 @@ __metadata: languageName: node linkType: hard +"basic-ftp@npm:^5.0.2": + version: 5.2.0 + resolution: "basic-ftp@npm:5.2.0" + checksum: 10c0/a0f85c01deae0723021f9bf4a7be29378186fa8bba41e74ea11832fe74c187ce90c3599c3cc5ec936581cfd150020e79f4a9ed0ee9fb20b2308e69b045f3a059 + languageName: node + linkType: hard + "before-after-hook@npm:^2.2.0": version: 2.2.3 resolution: "before-after-hook@npm:2.2.3" @@ -8716,6 +9469,15 @@ __metadata: languageName: node linkType: hard +"brace-expansion@npm:^5.0.2": + version: 5.0.4 + resolution: "brace-expansion@npm:5.0.4" + dependencies: + balanced-match: "npm:^4.0.2" + checksum: 10c0/359cbcfa80b2eb914ca1f3440e92313fbfe7919ee6b274c35db55bec555aded69dac5ee78f102cec90c35f98c20fa43d10936d0cd9978158823c249257e1643a + languageName: node + linkType: hard + "braces@npm:^3.0.3, braces@npm:~3.0.2": version: 3.0.3 resolution: "braces@npm:3.0.3" @@ -9130,6 +9892,16 @@ __metadata: languageName: node linkType: hard +"chalk@npm:4.1.2, chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880 + languageName: node + linkType: hard + "chalk@npm:^2.0.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -9141,16 +9913,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": - version: 4.1.2 - resolution: "chalk@npm:4.1.2" - dependencies: - ansi-styles: "npm:^4.1.0" - supports-color: "npm:^7.1.0" - checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880 - languageName: node - linkType: hard - "chalk@npm:^5.3.0": version: 5.3.0 resolution: "chalk@npm:5.3.0" @@ -9485,6 +10247,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 10c0/8b043bb8322ea1c39664a1598a95e0495bfe4ca2fad0d84a92d7d1d8d213e2a155b441d2470c8e08de7c4a28cf2bc6e169211c49e1b21d9f7edc6ae4d9356060 + languageName: node + linkType: hard + "commander@npm:^10.0.0, commander@npm:^10.0.1": version: 10.0.1 resolution: "commander@npm:10.0.1" @@ -9550,7 +10319,7 @@ __metadata: languageName: node linkType: hard -"compare-versions@npm:^6.1.1": +"compare-versions@npm:6.1.1, compare-versions@npm:^6.1.1": version: 6.1.1 resolution: "compare-versions@npm:6.1.1" checksum: 10c0/415205c7627f9e4f358f571266422980c9fe2d99086be0c9a48008ef7c771f32b0fbe8e97a441ffedc3910872f917a0675fe0fe3c3b6d331cda6d8690be06338 @@ -9607,6 +10376,23 @@ __metadata: languageName: node linkType: hard +"concurrently@npm:9.2.1": + version: 9.2.1 + resolution: "concurrently@npm:9.2.1" + dependencies: + chalk: "npm:4.1.2" + rxjs: "npm:7.8.2" + shell-quote: "npm:1.8.3" + supports-color: "npm:8.1.1" + tree-kill: "npm:1.2.2" + yargs: "npm:17.7.2" + bin: + conc: dist/bin/concurrently.js + concurrently: dist/bin/concurrently.js + checksum: 10c0/da37f239f82eb7ac24f5ddb56259861e5f1d6da2ade7602b6ea7ad3101b13b5ccec02a77b7001402d1028ff2fdc38eed55644b32853ad5abf30e057002a963aa + languageName: node + linkType: hard + "confbox@npm:^0.1.7": version: 0.1.7 resolution: "confbox@npm:0.1.7" @@ -9650,6 +10436,20 @@ __metadata: languageName: node linkType: hard +"consola@npm:^2.15.0": + version: 2.15.3 + resolution: "consola@npm:2.15.3" + checksum: 10c0/34a337e6b4a1349ee4d7b4c568484344418da8fdb829d7d71bfefcd724f608f273987633b6eef465e8de510929907a092e13cb7a28a5d3acb3be446fcc79fd5e + languageName: node + linkType: hard + +"consola@npm:^3.2.3": + version: 3.4.2 + resolution: "consola@npm:3.4.2" + checksum: 10c0/7cebe57ecf646ba74b300bcce23bff43034ed6fbec9f7e39c27cee1dc00df8a21cd336b466ad32e304ea70fba04ec9e890c200270de9a526ce021ba8a7e4c11a + languageName: node + linkType: hard + "console-control-strings@npm:^1.1.0": version: 1.1.0 resolution: "console-control-strings@npm:1.1.0" @@ -9657,6 +10457,15 @@ __metadata: languageName: node linkType: hard +"console.table@npm:0.10.0": + version: 0.10.0 + resolution: "console.table@npm:0.10.0" + dependencies: + easy-table: "npm:1.1.0" + checksum: 10c0/b1893a06b422c7e82dca03dec000beabebc26415df558a05e1b9778407a76e4caa1db286df40f72e3780ac5c5b5ef5f4b8a3bef2d22020abb86f6408dc357875 + languageName: node + linkType: hard + "content-disposition@npm:0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" @@ -9867,7 +10676,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -9950,6 +10759,17 @@ __metadata: languageName: node linkType: hard +"customer-admin-panel@workspace:packages/rest-api-sdk/examples/customer-admin-panel": + version: 0.0.0-use.local + resolution: "customer-admin-panel@workspace:packages/rest-api-sdk/examples/customer-admin-panel" + dependencies: + "@reflag/rest-api-sdk": "workspace:*" + next: "npm:14.2.5" + react: "npm:18.3.1" + react-dom: "npm:18.3.1" + languageName: unknown + linkType: soft + "damerau-levenshtein@npm:^1.0.8": version: 1.0.8 resolution: "damerau-levenshtein@npm:1.0.8" @@ -9964,6 +10784,13 @@ __metadata: languageName: node linkType: hard +"data-uri-to-buffer@npm:^6.0.2": + version: 6.0.2 + resolution: "data-uri-to-buffer@npm:6.0.2" + checksum: 10c0/f76922bf895b3d7d443059ff278c9cc5efc89d70b8b80cd9de0aa79b3adc6d7a17948eefb8692e30398c43635f70ece1673d6085cc9eba2878dbc6c6da5292ac + languageName: node + linkType: hard + "data-urls@npm:^5.0.0": version: 5.0.0 resolution: "data-urls@npm:5.0.0" @@ -10316,6 +11143,17 @@ __metadata: languageName: node linkType: hard +"degenerator@npm:^5.0.0": + version: 5.0.1 + resolution: "degenerator@npm:5.0.1" + dependencies: + ast-types: "npm:^0.13.4" + escodegen: "npm:^2.1.0" + esprima: "npm:^4.0.1" + checksum: 10c0/e48d8a651edeb512a648711a09afec269aac6de97d442a4bb9cf121a66877e0eec11b9727100a10252335c0666ae1c84a8bc1e3a3f47788742c975064d2c7b1c + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -10365,7 +11203,7 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.3": +"detect-libc@npm:^2.0.3, detect-libc@npm:^2.1.2": version: 2.1.2 resolution: "detect-libc@npm:2.1.2" checksum: 10c0/acc675c29a5649fa1fb6e255f993b8ee829e510b6b56b0910666949c80c364738833417d0edb5f90e4e46be17228b0f2b66a010513984e18b15deeeac49369c4 @@ -10418,6 +11256,15 @@ __metadata: languageName: node linkType: hard +"doctrine@npm:^3.0.0": + version: 3.0.0 + resolution: "doctrine@npm:3.0.0" + dependencies: + esutils: "npm:^2.0.2" + checksum: 10c0/c96bdccabe9d62ab6fea9399fdff04a66e6563c1d6fb3a3a063e8d53c3bb136ba63e84250bbf63d00086a769ad53aef92d2bd483f03f837fc97b71cbee6b2520 + languageName: node + linkType: hard + "dom-accessibility-api@npm:^0.5.9": version: 0.5.16 resolution: "dom-accessibility-api@npm:0.5.16" @@ -10496,6 +11343,18 @@ __metadata: languageName: node linkType: hard +"easy-table@npm:1.1.0": + version: 1.1.0 + resolution: "easy-table@npm:1.1.0" + dependencies: + wcwidth: "npm:>=1.0.1" + dependenciesMeta: + wcwidth: + optional: true + checksum: 10c0/0b7b03723e450c8286bd375bbe7d23247456dbb8f79df055adcfd745bfb91f7604c4e78204ff75d65d5229bec8867cbefca51c57938004f487ff800b587540bb + languageName: node + linkType: hard + "editorconfig@npm:^1.0.4": version: 1.0.4 resolution: "editorconfig@npm:1.0.4" @@ -11282,6 +12141,24 @@ __metadata: languageName: node linkType: hard +"escodegen@npm:^2.1.0": + version: 2.1.0 + resolution: "escodegen@npm:2.1.0" + dependencies: + esprima: "npm:^4.0.1" + estraverse: "npm:^5.2.0" + esutils: "npm:^2.0.2" + source-map: "npm:~0.6.1" + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 10c0/e1450a1f75f67d35c061bf0d60888b15f62ab63aef9df1901cffc81cffbbb9e8b3de237c5502cf8613a017c1df3a3003881307c78835a1ab54d8c8d2206e01d3 + languageName: node + linkType: hard + "eslint-config-next@npm:14.2.5": version: 14.2.5 resolution: "eslint-config-next@npm:14.2.5" @@ -11671,7 +12548,7 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.1.1": +"eslint-scope@npm:^7.1.1, eslint-scope@npm:^7.2.2": version: 7.2.2 resolution: "eslint-scope@npm:7.2.2" dependencies: @@ -11729,6 +12606,54 @@ __metadata: languageName: node linkType: hard +"eslint@npm:^8": + version: 8.57.1 + resolution: "eslint@npm:8.57.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.2.0" + "@eslint-community/regexpp": "npm:^4.6.1" + "@eslint/eslintrc": "npm:^2.1.4" + "@eslint/js": "npm:8.57.1" + "@humanwhocodes/config-array": "npm:^0.13.0" + "@humanwhocodes/module-importer": "npm:^1.0.1" + "@nodelib/fs.walk": "npm:^1.2.8" + "@ungap/structured-clone": "npm:^1.2.0" + ajv: "npm:^6.12.4" + chalk: "npm:^4.0.0" + cross-spawn: "npm:^7.0.2" + debug: "npm:^4.3.2" + doctrine: "npm:^3.0.0" + escape-string-regexp: "npm:^4.0.0" + eslint-scope: "npm:^7.2.2" + eslint-visitor-keys: "npm:^3.4.3" + espree: "npm:^9.6.1" + esquery: "npm:^1.4.2" + esutils: "npm:^2.0.2" + fast-deep-equal: "npm:^3.1.3" + file-entry-cache: "npm:^6.0.1" + find-up: "npm:^5.0.0" + glob-parent: "npm:^6.0.2" + globals: "npm:^13.19.0" + graphemer: "npm:^1.4.0" + ignore: "npm:^5.2.0" + imurmurhash: "npm:^0.1.4" + is-glob: "npm:^4.0.0" + is-path-inside: "npm:^3.0.3" + js-yaml: "npm:^4.1.0" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + levn: "npm:^0.4.1" + lodash.merge: "npm:^4.6.2" + minimatch: "npm:^3.1.2" + natural-compare: "npm:^1.4.0" + optionator: "npm:^0.9.3" + strip-ansi: "npm:^6.0.1" + text-table: "npm:^0.2.0" + bin: + eslint: bin/eslint.js + checksum: 10c0/1fd31533086c1b72f86770a4d9d7058ee8b4643fd1cfd10c7aac1ecb8725698e88352a87805cf4b2ce890aa35947df4b4da9655fb7fdfa60dbb448a43f6ebcf1 + languageName: node + linkType: hard + "eslint@npm:^9": version: 9.39.2 resolution: "eslint@npm:9.39.2" @@ -11849,7 +12774,7 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.3.1": +"espree@npm:^9.3.1, espree@npm:^9.6.0, espree@npm:^9.6.1": version: 9.6.1 resolution: "espree@npm:9.6.1" dependencies: @@ -11879,6 +12804,15 @@ __metadata: languageName: node linkType: hard +"esquery@npm:^1.4.2": + version: 1.7.0 + resolution: "esquery@npm:1.7.0" + dependencies: + estraverse: "npm:^5.1.0" + checksum: 10c0/77d5173db450b66f3bc685d11af4c90cffeedb340f34a39af96d43509a335ce39c894fd79233df32d38f5e4e219fa0f7076f6ec90bae8320170ba082c0db4793 + languageName: node + linkType: hard + "esrecurse@npm:^4.3.0": version: 4.3.0 resolution: "esrecurse@npm:4.3.0" @@ -12282,6 +13216,13 @@ __metadata: languageName: node linkType: hard +"fast-safe-stringify@npm:2.1.1": + version: 2.1.1 + resolution: "fast-safe-stringify@npm:2.1.1" + checksum: 10c0/d90ec1c963394919828872f21edaa3ad6f1dddd288d2bd4e977027afff09f5db40f94e39536d4646f7e01761d704d72d51dce5af1b93717f3489ef808f5f4e4d + languageName: node + linkType: hard + "fast-uri@npm:^3.0.1": version: 3.0.1 resolution: "fast-uri@npm:3.0.1" @@ -12361,7 +13302,7 @@ __metadata: languageName: node linkType: hard -"figures@npm:3.2.0, figures@npm:^3.0.0": +"figures@npm:3.2.0, figures@npm:^3.0.0, figures@npm:^3.2.0": version: 3.2.0 resolution: "figures@npm:3.2.0" dependencies: @@ -12370,6 +13311,15 @@ __metadata: languageName: node linkType: hard +"file-entry-cache@npm:^6.0.1": + version: 6.0.1 + resolution: "file-entry-cache@npm:6.0.1" + dependencies: + flat-cache: "npm:^3.0.4" + checksum: 10c0/58473e8a82794d01b38e5e435f6feaf648e3f36fdb3a56e98f417f4efae71ad1c0d4ebd8a9a7c50c3ad085820a93fc7494ad721e0e4ebc1da3573f4e1c3c7cdd + languageName: node + linkType: hard + "file-entry-cache@npm:^8.0.0": version: 8.0.0 resolution: "file-entry-cache@npm:8.0.0" @@ -12379,6 +13329,18 @@ __metadata: languageName: node linkType: hard +"file-type@npm:21.3.0": + version: 21.3.0 + resolution: "file-type@npm:21.3.0" + dependencies: + "@tokenizer/inflate": "npm:^0.4.1" + strtok3: "npm:^10.3.4" + token-types: "npm:^6.1.1" + uint8array-extras: "npm:^1.4.0" + checksum: 10c0/1b1fa909e6063044a6da1d2ea348ee4d747ed9286382d3f0d4d6532c11fb2ea9f2e7e67b2bc7d745d1bc937e05dee1aa8cb912c64250933bcb393a3744f4e284 + languageName: node + linkType: hard + "filelist@npm:^1.0.4": version: 1.0.4 resolution: "filelist@npm:1.0.4" @@ -12467,6 +13429,17 @@ __metadata: languageName: node linkType: hard +"flat-cache@npm:^3.0.4": + version: 3.2.0 + resolution: "flat-cache@npm:3.2.0" + dependencies: + flatted: "npm:^3.2.9" + keyv: "npm:^4.5.3" + rimraf: "npm:^3.0.2" + checksum: 10c0/b76f611bd5f5d68f7ae632e3ae503e678d205cf97a17c6ab5b12f6ca61188b5f1f7464503efae6dc18683ed8f0b41460beb48ac4b9ac63fe6201296a91ba2f75 + languageName: node + linkType: hard + "flat-cache@npm:^4.0.0": version: 4.0.1 resolution: "flat-cache@npm:4.0.1" @@ -12517,6 +13490,16 @@ __metadata: languageName: node linkType: hard +"follow-redirects@npm:^1.15.11": + version: 1.15.11 + resolution: "follow-redirects@npm:1.15.11" + peerDependenciesMeta: + debug: + optional: true + checksum: 10c0/d301f430542520a54058d4aeeb453233c564aaccac835d29d15e050beb33f339ad67d9bddbce01739c5dc46a6716dbe3d9d0d5134b1ca203effa11a7ef092343 + languageName: node + linkType: hard + "follow-redirects@npm:^1.15.6": version: 1.15.6 resolution: "follow-redirects@npm:1.15.6" @@ -12566,6 +13549,19 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^4.0.5": + version: 4.0.5 + resolution: "form-data@npm:4.0.5" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + es-set-tostringtag: "npm:^2.1.0" + hasown: "npm:^2.0.2" + mime-types: "npm:^2.1.12" + checksum: 10c0/dd6b767ee0bbd6d84039db12a0fa5a2028160ffbfaba1800695713b46ae974a5f6e08b3356c3195137f8530dcd9dfcb5d5ae1eeff53d0db1e5aad863b619ce3b + languageName: node + linkType: hard + "forwarded@npm:0.2.0": version: 0.2.0 resolution: "forwarded@npm:0.2.0" @@ -12601,6 +13597,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:11.3.3": + version: 11.3.3 + resolution: "fs-extra@npm:11.3.3" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/984924ff4104e3e9f351b658a864bf3b354b2c90429f57aec0acd12d92c4e6b762cbacacdffb4e745b280adce882e1f980c485d9f02c453f769ab4e7fc646ce3 + languageName: node + linkType: hard + "fs-extra@npm:^11.1.0, fs-extra@npm:^11.1.1": version: 11.2.0 resolution: "fs-extra@npm:11.2.0" @@ -12963,6 +13970,17 @@ __metadata: languageName: node linkType: hard +"get-uri@npm:^6.0.1": + version: 6.0.5 + resolution: "get-uri@npm:6.0.5" + dependencies: + basic-ftp: "npm:^5.0.2" + data-uri-to-buffer: "npm:^6.0.2" + debug: "npm:^4.3.4" + checksum: 10c0/c7ff5d5d55de53d23ecce7c5108cc3ed0db1174db43c9aa15506d640283d36ee0956fd8ba1fc50b06a718466cc85794ae9d8860193f91318afe846e3e7010f3a + languageName: node + linkType: hard + "getenv@npm:^2.0.0": version: 2.0.0 resolution: "getenv@npm:2.0.0" @@ -13073,6 +14091,17 @@ __metadata: languageName: node linkType: hard +"glob@npm:13.0.6": + version: 13.0.6 + resolution: "glob@npm:13.0.6" + dependencies: + minimatch: "npm:^10.2.2" + minipass: "npm:^7.1.3" + path-scurry: "npm:^2.0.2" + checksum: 10c0/269c236f11a9b50357fe7a8c6aadac667e01deb5242b19c84975628f05f4438d8ee1354bb62c5d6c10f37fd59911b54d7799730633a2786660d8c69f1d18120a + languageName: node + linkType: hard + "glob@npm:^10.2.2, glob@npm:^10.3.10": version: 10.3.14 resolution: "glob@npm:10.3.14" @@ -13191,7 +14220,7 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.24.0": +"globals@npm:^13.19.0, globals@npm:^13.24.0": version: 13.24.0 resolution: "globals@npm:13.24.0" dependencies: @@ -13621,7 +14650,7 @@ __metadata: languageName: node linkType: hard -"http-proxy-agent@npm:^7.0.2": +"http-proxy-agent@npm:^7.0.1, http-proxy-agent@npm:^7.0.2": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" dependencies: @@ -13685,7 +14714,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.5": +"https-proxy-agent@npm:^7.0.5, https-proxy-agent@npm:^7.0.6": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" dependencies: @@ -13745,7 +14774,7 @@ __metadata: languageName: node linkType: hard -"ieee754@npm:^1.1.13": +"ieee754@npm:^1.1.13, ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb @@ -13956,6 +14985,13 @@ __metadata: languageName: node linkType: hard +"ip-address@npm:^10.0.1": + version: 10.1.0 + resolution: "ip-address@npm:10.1.0" + checksum: 10c0/0103516cfa93f6433b3bd7333fa876eb21263912329bfa47010af5e16934eeeff86f3d2ae700a3744a137839ddfad62b900c7a445607884a49b5d1e32a3d7566 + languageName: node + linkType: hard + "ip-address@npm:^9.0.5": version: 9.0.5 resolution: "ip-address@npm:9.0.5" @@ -14339,6 +15375,13 @@ __metadata: languageName: node linkType: hard +"is-path-inside@npm:^3.0.3": + version: 3.0.3 + resolution: "is-path-inside@npm:3.0.3" + checksum: 10c0/cf7d4ac35fb96bab6a1d2c3598fe5ebb29aafb52c0aaa482b5a3ed9d8ba3edc11631e3ec2637660c44b3ce0e61a08d54946e8af30dec0b60a7c27296c68ffd05 + languageName: node + linkType: hard + "is-plain-obj@npm:^1.0.0, is-plain-obj@npm:^1.1.0": version: 1.1.0 resolution: "is-plain-obj@npm:1.1.0" @@ -14733,6 +15776,13 @@ __metadata: languageName: node linkType: hard +"iterare@npm:1.2.1": + version: 1.2.1 + resolution: "iterare@npm:1.2.1" + checksum: 10c0/02667d486e3e83ead028ba8484d927498c2ceab7e8c6a69dd881fd02abc4114f00b13abb36b592252fbb578b6e6f99ca1dfc2835408b9158c9a112a9964f453f + languageName: node + linkType: hard + "iterator.prototype@npm:^1.1.2": version: 1.1.2 resolution: "iterator.prototype@npm:1.1.2" @@ -15262,7 +16312,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.4": +"keyv@npm:^4.5.3, keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -15621,6 +16671,13 @@ __metadata: languageName: node linkType: hard +"load-esm@npm:1.0.3": + version: 1.0.3 + resolution: "load-esm@npm:1.0.3" + checksum: 10c0/285a3666a29c11f7b466bb70ee3582af32893d03ed91b68be939c656a15afd27f3683f5f8d56b52834ce2911ecf1c84e515e6048248fb5268a89b724a8ddbf65 + languageName: node + linkType: hard + "load-json-file@npm:6.2.0": version: 6.2.0 resolution: "load-json-file@npm:6.2.0" @@ -15876,7 +16933,7 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^7.5.1, lru-cache@npm:^7.7.1": +"lru-cache@npm:^7.14.1, lru-cache@npm:^7.5.1, lru-cache@npm:^7.7.1": version: 7.18.3 resolution: "lru-cache@npm:7.18.3" checksum: 10c0/b3a452b491433db885beed95041eb104c157ef7794b9c9b4d647be503be91769d11206bb573849a16b4cc0d03cbd15ffd22df7960997788b74c1d399ac7a4fed @@ -16508,6 +17565,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^10.2.2": + version: 10.2.4 + resolution: "minimatch@npm:10.2.4" + dependencies: + brace-expansion: "npm:^5.0.2" + checksum: 10c0/35f3dfb7b99b51efd46afd378486889f590e7efb10e0f6a10ba6800428cf65c9a8dedb74427d0570b318d749b543dc4e85f06d46d2858bc8cac7e1eb49a95945 + languageName: node + linkType: hard + "minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -16517,6 +17583,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^3.0.5": + version: 3.1.5 + resolution: "minimatch@npm:3.1.5" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10c0/2ecbdc0d33f07bddb0315a8b5afbcb761307a8778b48f0b312418ccbced99f104a2d17d8aca7573433c70e8ccd1c56823a441897a45e384ea76ef401a26ace70 + languageName: node + linkType: hard + "minimatch@npm:^5.0.1": version: 5.1.6 resolution: "minimatch@npm:5.1.6" @@ -16687,6 +17762,13 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^7.1.3": + version: 7.1.3 + resolution: "minipass@npm:7.1.3" + checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb + languageName: node + linkType: hard + "minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": version: 2.1.2 resolution: "minizlib@npm:2.1.2" @@ -16954,6 +18036,13 @@ __metadata: languageName: node linkType: hard +"netmask@npm:^2.0.2": + version: 2.0.2 + resolution: "netmask@npm:2.0.2" + checksum: 10c0/cafd28388e698e1138ace947929f842944d0f1c0b87d3fa2601a61b38dc89397d33c0ce2c8e7b99e968584b91d15f6810b91bef3f3826adf71b1833b61d4bf4f + languageName: node + linkType: hard + "next@npm:14.2.26": version: 14.2.26 resolution: "next@npm:14.2.26" @@ -17008,10 +18097,226 @@ __metadata: optional: true bin: next: dist/bin/next - checksum: 10c0/d5792ad9aff56b42648456f9cced2f269100c4d4200590c2f4e419f3ad2c5795b57f7caf273bc336323f866dbb31268197b46a07016ca7e55637d68b53176b29 + checksum: 10c0/d5792ad9aff56b42648456f9cced2f269100c4d4200590c2f4e419f3ad2c5795b57f7caf273bc336323f866dbb31268197b46a07016ca7e55637d68b53176b29 + languageName: node + linkType: hard + +"next@npm:14.2.5": + version: 14.2.5 + resolution: "next@npm:14.2.5" + dependencies: + "@next/env": "npm:14.2.5" + "@next/swc-darwin-arm64": "npm:14.2.5" + "@next/swc-darwin-x64": "npm:14.2.5" + "@next/swc-linux-arm64-gnu": "npm:14.2.5" + "@next/swc-linux-arm64-musl": "npm:14.2.5" + "@next/swc-linux-x64-gnu": "npm:14.2.5" + "@next/swc-linux-x64-musl": "npm:14.2.5" + "@next/swc-win32-arm64-msvc": "npm:14.2.5" + "@next/swc-win32-ia32-msvc": "npm:14.2.5" + "@next/swc-win32-x64-msvc": "npm:14.2.5" + "@swc/helpers": "npm:0.5.5" + busboy: "npm:1.6.0" + caniuse-lite: "npm:^1.0.30001579" + graceful-fs: "npm:^4.2.11" + postcss: "npm:8.4.31" + styled-jsx: "npm:5.1.1" + peerDependencies: + "@opentelemetry/api": ^1.1.0 + "@playwright/test": ^1.41.2 + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + dependenciesMeta: + "@next/swc-darwin-arm64": + optional: true + "@next/swc-darwin-x64": + optional: true + "@next/swc-linux-arm64-gnu": + optional: true + "@next/swc-linux-arm64-musl": + optional: true + "@next/swc-linux-x64-gnu": + optional: true + "@next/swc-linux-x64-musl": + optional: true + "@next/swc-win32-arm64-msvc": + optional: true + "@next/swc-win32-ia32-msvc": + optional: true + "@next/swc-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@opentelemetry/api": + optional: true + "@playwright/test": + optional: true + sass: + optional: true + bin: + next: dist/bin/next + checksum: 10c0/8df7d8ccc1a5bab03fa50dd6656c8a6f3750e81ef0b087dc329fea9346847c3094a933a890a8e87151dc32f0bc55020b8f6386d4565856d83bcc10895d29ec08 + languageName: node + linkType: hard + +"next@npm:15.5.10": + version: 15.5.10 + resolution: "next@npm:15.5.10" + dependencies: + "@next/env": "npm:15.5.10" + "@next/swc-darwin-arm64": "npm:15.5.7" + "@next/swc-darwin-x64": "npm:15.5.7" + "@next/swc-linux-arm64-gnu": "npm:15.5.7" + "@next/swc-linux-arm64-musl": "npm:15.5.7" + "@next/swc-linux-x64-gnu": "npm:15.5.7" + "@next/swc-linux-x64-musl": "npm:15.5.7" + "@next/swc-win32-arm64-msvc": "npm:15.5.7" + "@next/swc-win32-x64-msvc": "npm:15.5.7" + "@swc/helpers": "npm:0.5.15" + caniuse-lite: "npm:^1.0.30001579" + postcss: "npm:8.4.31" + sharp: "npm:^0.34.3" + styled-jsx: "npm:5.1.6" + peerDependencies: + "@opentelemetry/api": ^1.1.0 + "@playwright/test": ^1.51.1 + babel-plugin-react-compiler: "*" + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + dependenciesMeta: + "@next/swc-darwin-arm64": + optional: true + "@next/swc-darwin-x64": + optional: true + "@next/swc-linux-arm64-gnu": + optional: true + "@next/swc-linux-arm64-musl": + optional: true + "@next/swc-linux-x64-gnu": + optional: true + "@next/swc-linux-x64-musl": + optional: true + "@next/swc-win32-arm64-msvc": + optional: true + "@next/swc-win32-x64-msvc": + optional: true + sharp: + optional: true + peerDependenciesMeta: + "@opentelemetry/api": + optional: true + "@playwright/test": + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + bin: + next: dist/bin/next + checksum: 10c0/ebf358cfc13e856ac2d60f6b1eb166560c541796d3422d6719712c0e8038626407f6075cb0d2805d9d6392404a5b0e63e501515982d78d7e934b721ea9753b17 + languageName: node + linkType: hard + +"next@npm:16.1.5": + version: 16.1.5 + resolution: "next@npm:16.1.5" + dependencies: + "@next/env": "npm:16.1.5" + "@next/swc-darwin-arm64": "npm:16.1.5" + "@next/swc-darwin-x64": "npm:16.1.5" + "@next/swc-linux-arm64-gnu": "npm:16.1.5" + "@next/swc-linux-arm64-musl": "npm:16.1.5" + "@next/swc-linux-x64-gnu": "npm:16.1.5" + "@next/swc-linux-x64-musl": "npm:16.1.5" + "@next/swc-win32-arm64-msvc": "npm:16.1.5" + "@next/swc-win32-x64-msvc": "npm:16.1.5" + "@swc/helpers": "npm:0.5.15" + baseline-browser-mapping: "npm:^2.8.3" + caniuse-lite: "npm:^1.0.30001579" + postcss: "npm:8.4.31" + sharp: "npm:^0.34.4" + styled-jsx: "npm:5.1.6" + peerDependencies: + "@opentelemetry/api": ^1.1.0 + "@playwright/test": ^1.51.1 + babel-plugin-react-compiler: "*" + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + dependenciesMeta: + "@next/swc-darwin-arm64": + optional: true + "@next/swc-darwin-x64": + optional: true + "@next/swc-linux-arm64-gnu": + optional: true + "@next/swc-linux-arm64-musl": + optional: true + "@next/swc-linux-x64-gnu": + optional: true + "@next/swc-linux-x64-musl": + optional: true + "@next/swc-win32-arm64-msvc": + optional: true + "@next/swc-win32-x64-msvc": + optional: true + sharp: + optional: true + peerDependenciesMeta: + "@opentelemetry/api": + optional: true + "@playwright/test": + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + bin: + next: dist/bin/next + checksum: 10c0/ff9f7dd0cae79f7ba2a64ac0d29ca77c94921dfc37b36899f4f997b948242f72585f4bb75829aaf8704d46c6f7d1a9796b8ff30688a3467c04c738b3a4247a9f languageName: node linkType: hard +"nextjs-bootstrap-demo@workspace:packages/react-sdk/dev/nextjs-bootstrap-demo": + version: 0.0.0-use.local + resolution: "nextjs-bootstrap-demo@workspace:packages/react-sdk/dev/nextjs-bootstrap-demo" + dependencies: + "@reflag/node-sdk": "workspace:^" + "@reflag/react-sdk": "workspace:^" + "@types/node": "npm:^22.12.0" + "@types/react": "npm:^18" + "@types/react-dom": "npm:^18" + eslint: "npm:^8" + eslint-config-next: "npm:14.2.5" + next: "npm:16.1.5" + postcss: "npm:^8" + react: "npm:^18" + react-dom: "npm:^18" + tailwindcss: "npm:^3.4.1" + typescript: "npm:^5.7.3" + languageName: unknown + linkType: soft + +"nextjs-flag-demo@workspace:packages/react-sdk/dev/nextjs-flag-demo": + version: 0.0.0-use.local + resolution: "nextjs-flag-demo@workspace:packages/react-sdk/dev/nextjs-flag-demo" + dependencies: + "@reflag/react-sdk": "workspace:^" + "@types/node": "npm:^22.12.0" + "@types/react": "npm:^18" + "@types/react-dom": "npm:^18" + eslint: "npm:^8" + eslint-config-next: "npm:14.2.5" + next: "npm:15.5.10" + postcss: "npm:^8" + react: "npm:^18" + react-dom: "npm:^18" + tailwindcss: "npm:^3.4.1" + typescript: "npm:^5.7.3" + languageName: unknown + linkType: soft + "nextjs-openfeature-example@workspace:packages/openfeature-browser-provider/example": version: 0.0.0-use.local resolution: "nextjs-openfeature-example@workspace:packages/openfeature-browser-provider/example" @@ -17066,7 +18371,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.7": +"node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.7": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: @@ -18101,6 +19406,32 @@ __metadata: languageName: node linkType: hard +"pac-proxy-agent@npm:^7.1.0": + version: 7.2.0 + resolution: "pac-proxy-agent@npm:7.2.0" + dependencies: + "@tootallnate/quickjs-emscripten": "npm:^0.23.0" + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + get-uri: "npm:^6.0.1" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.6" + pac-resolver: "npm:^7.0.1" + socks-proxy-agent: "npm:^8.0.5" + checksum: 10c0/0265c17c9401c2ea735697931a6553a0c6d8b20c4d7d4e3b3a0506080ba69a8d5ad656e2a6be875411212e2b6ed7a4d9526dd3997e08581fdfb1cbcad454c296 + languageName: node + linkType: hard + +"pac-resolver@npm:^7.0.1": + version: 7.0.1 + resolution: "pac-resolver@npm:7.0.1" + dependencies: + degenerator: "npm:^5.0.0" + netmask: "npm:^2.0.2" + checksum: 10c0/5f3edd1dd10fded31e7d1f95776442c3ee51aa098c28b74ede4927d9677ebe7cebb2636750c24e945f5b84445e41ae39093d3a1014a994e5ceb9f0b1b88ebff5 + languageName: node + linkType: hard + "package-json-from-dist@npm:^1.0.0": version: 1.0.0 resolution: "package-json-from-dist@npm:1.0.0" @@ -18296,6 +19627,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^2.0.2": + version: 2.0.2 + resolution: "path-scurry@npm:2.0.2" + dependencies: + lru-cache: "npm:^11.0.0" + minipass: "npm:^7.1.2" + checksum: 10c0/b35ad37cf6557a87fd057121ce2be7695380c9138d93e87ae928609da259ea0a170fac6f3ef1eb3ece8a068e8b7f2f3adf5bb2374cf4d4a57fe484954fcc9482 + languageName: node + linkType: hard + "path-to-regexp@npm:0.1.12": version: 0.1.12 resolution: "path-to-regexp@npm:0.1.12" @@ -18303,6 +19644,13 @@ __metadata: languageName: node linkType: hard +"path-to-regexp@npm:8.3.0": + version: 8.3.0 + resolution: "path-to-regexp@npm:8.3.0" + checksum: 10c0/ee1544a73a3f294a97a4c663b0ce71bbf1621d732d80c9c9ed201b3e911a86cb628ebad691b9d40f40a3742fe22011e5a059d8eed2cf63ec2cb94f6fb4efe67c + languageName: node + linkType: hard + "path-to-regexp@npm:^6.2.0": version: 6.3.0 resolution: "path-to-regexp@npm:6.3.0" @@ -19241,6 +20589,22 @@ __metadata: languageName: node linkType: hard +"proxy-agent@npm:6.5.0": + version: 6.5.0 + resolution: "proxy-agent@npm:6.5.0" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + http-proxy-agent: "npm:^7.0.1" + https-proxy-agent: "npm:^7.0.6" + lru-cache: "npm:^7.14.1" + pac-proxy-agent: "npm:^7.1.0" + proxy-from-env: "npm:^1.1.0" + socks-proxy-agent: "npm:^8.0.5" + checksum: 10c0/7fd4e6f36bf17098a686d4aee3b8394abfc0b0537c2174ce96b0a4223198b9fafb16576c90108a3fcfc2af0168bd7747152bfa1f58e8fee91d3780e79aab7fd8 + languageName: node + linkType: hard + "proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -19737,6 +21101,13 @@ __metadata: languageName: unknown linkType: soft +"reflect-metadata@npm:0.2.2": + version: 0.2.2 + resolution: "reflect-metadata@npm:0.2.2" + checksum: 10c0/1cd93a15ea291e420204955544637c264c216e7aac527470e393d54b4bb075f10a17e60d8168ec96600c7e0b9fcc0cb0bb6e91c3fbf5b0d8c9056f04e6ac1ec2 + languageName: node + linkType: hard + "reflect.getprototypeof@npm:^1.0.4": version: 1.0.6 resolution: "reflect.getprototypeof@npm:1.0.6" @@ -20320,6 +21691,13 @@ __metadata: languageName: node linkType: hard +"run-async@npm:^3.0.0": + version: 3.0.0 + resolution: "run-async@npm:3.0.0" + checksum: 10c0/b18b562ae37c3020083dcaae29642e4cc360c824fbfb6b7d50d809a9d5227bb986152d09310255842c8dce40526e82ca768f02f00806c91ba92a8dfa6159cb85 + languageName: node + linkType: hard + "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -20329,6 +21707,15 @@ __metadata: languageName: node linkType: hard +"rxjs@npm:7.8.2": + version: 7.8.2 + resolution: "rxjs@npm:7.8.2" + dependencies: + tslib: "npm:^2.1.0" + checksum: 10c0/1fcd33d2066ada98ba8f21fcbbcaee9f0b271de1d38dc7f4e256bfbc6ffcdde68c8bfb69093de7eeb46f24b1fb820620bf0223706cff26b4ab99a7ff7b2e2c45 + languageName: node + linkType: hard + "rxjs@npm:^7.5.5": version: 7.8.1 resolution: "rxjs@npm:7.8.1" @@ -20547,7 +21934,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.5.2": +"semver@npm:^7.5.2, semver@npm:^7.7.3": version: 7.7.4 resolution: "semver@npm:7.7.4" bin: @@ -20730,6 +22117,90 @@ __metadata: languageName: node linkType: hard +"sharp@npm:^0.34.3, sharp@npm:^0.34.4": + version: 0.34.5 + resolution: "sharp@npm:0.34.5" + dependencies: + "@img/colour": "npm:^1.0.0" + "@img/sharp-darwin-arm64": "npm:0.34.5" + "@img/sharp-darwin-x64": "npm:0.34.5" + "@img/sharp-libvips-darwin-arm64": "npm:1.2.4" + "@img/sharp-libvips-darwin-x64": "npm:1.2.4" + "@img/sharp-libvips-linux-arm": "npm:1.2.4" + "@img/sharp-libvips-linux-arm64": "npm:1.2.4" + "@img/sharp-libvips-linux-ppc64": "npm:1.2.4" + "@img/sharp-libvips-linux-riscv64": "npm:1.2.4" + "@img/sharp-libvips-linux-s390x": "npm:1.2.4" + "@img/sharp-libvips-linux-x64": "npm:1.2.4" + "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.4" + "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.4" + "@img/sharp-linux-arm": "npm:0.34.5" + "@img/sharp-linux-arm64": "npm:0.34.5" + "@img/sharp-linux-ppc64": "npm:0.34.5" + "@img/sharp-linux-riscv64": "npm:0.34.5" + "@img/sharp-linux-s390x": "npm:0.34.5" + "@img/sharp-linux-x64": "npm:0.34.5" + "@img/sharp-linuxmusl-arm64": "npm:0.34.5" + "@img/sharp-linuxmusl-x64": "npm:0.34.5" + "@img/sharp-wasm32": "npm:0.34.5" + "@img/sharp-win32-arm64": "npm:0.34.5" + "@img/sharp-win32-ia32": "npm:0.34.5" + "@img/sharp-win32-x64": "npm:0.34.5" + detect-libc: "npm:^2.1.2" + semver: "npm:^7.7.3" + dependenciesMeta: + "@img/sharp-darwin-arm64": + optional: true + "@img/sharp-darwin-x64": + optional: true + "@img/sharp-libvips-darwin-arm64": + optional: true + "@img/sharp-libvips-darwin-x64": + optional: true + "@img/sharp-libvips-linux-arm": + optional: true + "@img/sharp-libvips-linux-arm64": + optional: true + "@img/sharp-libvips-linux-ppc64": + optional: true + "@img/sharp-libvips-linux-riscv64": + optional: true + "@img/sharp-libvips-linux-s390x": + optional: true + "@img/sharp-libvips-linux-x64": + optional: true + "@img/sharp-libvips-linuxmusl-arm64": + optional: true + "@img/sharp-libvips-linuxmusl-x64": + optional: true + "@img/sharp-linux-arm": + optional: true + "@img/sharp-linux-arm64": + optional: true + "@img/sharp-linux-ppc64": + optional: true + "@img/sharp-linux-riscv64": + optional: true + "@img/sharp-linux-s390x": + optional: true + "@img/sharp-linux-x64": + optional: true + "@img/sharp-linuxmusl-arm64": + optional: true + "@img/sharp-linuxmusl-x64": + optional: true + "@img/sharp-wasm32": + optional: true + "@img/sharp-win32-arm64": + optional: true + "@img/sharp-win32-ia32": + optional: true + "@img/sharp-win32-x64": + optional: true + checksum: 10c0/fd79e29df0597a7d5704b8461c51f944ead91a5243691697be6e8243b966402beda53ddc6f0a53b96ea3cb8221f0b244aa588114d3ebf8734fb4aefd41ab802f + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -20746,7 +22217,7 @@ __metadata: languageName: node linkType: hard -"shell-quote@npm:^1.6.1, shell-quote@npm:^1.8.3": +"shell-quote@npm:1.8.3, shell-quote@npm:^1.6.1, shell-quote@npm:^1.8.3": version: 1.8.3 resolution: "shell-quote@npm:1.8.3" checksum: 10c0/bee87c34e1e986cfb4c30846b8e6327d18874f10b535699866f368ade11ea4ee45433d97bf5eada22c4320c27df79c3a6a7eb1bf3ecfc47f2c997d9e5e2672fd @@ -20980,6 +22451,17 @@ __metadata: languageName: node linkType: hard +"socks-proxy-agent@npm:^8.0.5": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + socks: "npm:^2.8.3" + checksum: 10c0/5d2c6cecba6821389aabf18728325730504bf9bb1d9e342e7987a5d13badd7a98838cc9a55b8ed3cb866ad37cc23e1086f09c4d72d93105ce9dfe76330e9d2a6 + languageName: node + linkType: hard + "socks@npm:^2.6.2, socks@npm:^2.7.1": version: 2.8.3 resolution: "socks@npm:2.8.3" @@ -20990,6 +22472,16 @@ __metadata: languageName: node linkType: hard +"socks@npm:^2.8.3": + version: 2.8.7 + resolution: "socks@npm:2.8.7" + dependencies: + ip-address: "npm:^10.0.1" + smart-buffer: "npm:^4.2.0" + checksum: 10c0/2805a43a1c4bcf9ebf6e018268d87b32b32b06fbbc1f9282573583acc155860dc361500f89c73bfbb157caa1b4ac78059eac0ef15d1811eb0ca75e0bdadbc9d2 + languageName: node + linkType: hard + "sort-keys@npm:^2.0.0": version: 2.0.0 resolution: "sort-keys@npm:2.0.0" @@ -21559,6 +23051,15 @@ __metadata: languageName: node linkType: hard +"strtok3@npm:^10.3.4": + version: 10.3.4 + resolution: "strtok3@npm:10.3.4" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + checksum: 10c0/277ab69e417f4545e364ffaf9d560c991f531045dbace32d77b5c822cccd76a608b782785a2c60595274288d4d32dced184a5c21dc20348791da697127dc69a8 + languageName: node + linkType: hard + "structured-headers@npm:^0.4.1": version: 0.4.1 resolution: "structured-headers@npm:0.4.1" @@ -21582,6 +23083,22 @@ __metadata: languageName: node linkType: hard +"styled-jsx@npm:5.1.6": + version: 5.1.6 + resolution: "styled-jsx@npm:5.1.6" + dependencies: + client-only: "npm:0.0.1" + peerDependencies: + react: ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + peerDependenciesMeta: + "@babel/core": + optional: true + babel-plugin-macros: + optional: true + checksum: 10c0/ace50e7ea5ae5ae6a3b65a50994c51fca6ae7df9c7ecfd0104c36be0b4b3a9c5c1a2374d16e2a11e256d0b20be6d47256d768ecb4f91ab390f60752a075780f5 + languageName: node + linkType: hard + "sucrase@npm:^3.32.0": version: 3.35.0 resolution: "sucrase@npm:3.35.0" @@ -21618,6 +23135,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:8.1.1, supports-color@npm:^8.0.0, supports-color@npm:~8.1.1": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -21636,15 +23162,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0, supports-color@npm:~8.1.1": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: "npm:^4.0.0" - checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 - languageName: node - linkType: hard - "supports-hyperlinks@npm:^2.0.0": version: 2.3.0 resolution: "supports-hyperlinks@npm:2.3.0" @@ -21845,6 +23362,13 @@ __metadata: languageName: node linkType: hard +"text-table@npm:^0.2.0": + version: 0.2.0 + resolution: "text-table@npm:0.2.0" + checksum: 10c0/02805740c12851ea5982686810702e2f14369a5f4c5c40a836821e3eefc65ffeec3131ba324692a37608294b0fd8c1e55a2dd571ffed4909822787668ddbee5c + languageName: node + linkType: hard + "thenify-all@npm:^1.0.0": version: 1.6.0 resolution: "thenify-all@npm:1.6.0" @@ -22026,6 +23550,17 @@ __metadata: languageName: node linkType: hard +"token-types@npm:^6.1.1": + version: 6.1.2 + resolution: "token-types@npm:6.1.2" + dependencies: + "@borewit/text-codec": "npm:^0.2.1" + "@tokenizer/token": "npm:^0.3.0" + ieee754: "npm:^1.2.1" + checksum: 10c0/8786e28e3cb65b9e890bc3c38def98e6dfe4565538237f8c0e47dbe549ed8f5f00de8dc464717868308abb4729f1958f78f69e1c4c3deebbb685729113a6fee8 + languageName: node + linkType: hard + "tough-cookie@npm:^4.1.4": version: 4.1.4 resolution: "tough-cookie@npm:4.1.4" @@ -22054,6 +23589,15 @@ __metadata: languageName: node linkType: hard +"tree-kill@npm:1.2.2": + version: 1.2.2 + resolution: "tree-kill@npm:1.2.2" + bin: + tree-kill: cli.js + checksum: 10c0/7b1b7c7f17608a8f8d20a162e7957ac1ef6cd1636db1aba92f4e072dc31818c2ff0efac1e3d91064ede67ed5dc57c565420531a8134090a12ac10cf792ab14d2 + languageName: node + linkType: hard + "trim-newlines@npm:^3.0.0": version: 3.0.1 resolution: "trim-newlines@npm:3.0.1" @@ -22147,6 +23691,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:2.8.1, tslib@npm:^2.0.1, tslib@npm:^2.8.0": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 + languageName: node + linkType: hard + "tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0": version: 2.6.2 resolution: "tslib@npm:2.6.2" @@ -22620,6 +24171,22 @@ __metadata: languageName: node linkType: hard +"uid@npm:2.0.2": + version: 2.0.2 + resolution: "uid@npm:2.0.2" + dependencies: + "@lukeed/csprng": "npm:^1.0.0" + checksum: 10c0/e9d02d0562c74e74b5a2519e586db9d7f8204978e476cddd191ee1a9efb85efafdbab2dbf3fc3dde0f5da01fd9da161f37d604dabf513447fd2c03d008f1324c + languageName: node + linkType: hard + +"uint8array-extras@npm:^1.4.0": + version: 1.5.0 + resolution: "uint8array-extras@npm:1.5.0" + checksum: 10c0/0e74641ac7dadb02eadefc1ccdadba6010e007757bda824960de3c72bbe2b04e6d3af75648441f412148c4103261d54fcb60be45a2863beb76643a55fddba3bd + languageName: node + linkType: hard + "unbox-primitive@npm:^1.0.2": version: 1.0.2 resolution: "unbox-primitive@npm:1.0.2" @@ -22665,6 +24232,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10c0/c01ed51829b10aa72fc3ce64b747f8e74ae9b60eafa19a7b46ef624403508a54c526ffab06a14a26b3120d055e1104d7abe7c9017e83ced038ea5cf52f8d5e04 + languageName: node + linkType: hard + "undici@npm:^6.18.2": version: 6.23.0 resolution: "undici@npm:6.23.0" @@ -23463,7 +25037,7 @@ __metadata: languageName: node linkType: hard -"wcwidth@npm:^1.0.0, wcwidth@npm:^1.0.1": +"wcwidth@npm:>=1.0.1, wcwidth@npm:^1.0.0, wcwidth@npm:^1.0.1": version: 1.0.1 resolution: "wcwidth@npm:1.0.1" dependencies: