priceos 1.0.13 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # PriceOS SDK (`priceos`)
2
+
3
+ Use PriceOS in your backend and React app to evaluate feature access and track usage.
4
+
5
+ - Docs: [docs.priceos.com](https://docs.priceos.com)
6
+ - Package: [npmjs.com/package/priceos](https://www.npmjs.com/package/priceos)
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm i priceos
12
+ ```
13
+
14
+ Set your API key in your backend environment:
15
+
16
+ ```bash
17
+ PRICEOS_API_KEY=pos_ab234cdef...
18
+ ```
19
+
20
+ `PRICEOS_API_KEY` must never be exposed client-side.
21
+
22
+ ## Quickstart (Node.js)
23
+
24
+ Create features in PriceOS first:
25
+ - [Creating Features](https://docs.priceos.com/creating-features)
26
+ - [Defining Feature Access](https://docs.priceos.com/defining-feature-access)
27
+
28
+ Generate typed feature keys (recommended):
29
+
30
+ ```bash
31
+ npx priceos generate-types --out ./src/priceos.types.d.ts
32
+ ```
33
+
34
+ Use the SDK:
35
+
36
+ ```ts
37
+ import { PriceOS } from "priceos";
38
+ import type { MyFeatures } from "./priceos.types";
39
+
40
+ const priceos = new PriceOS<MyFeatures>(process.env.PRICEOS_API_KEY!);
41
+
42
+ const premiumSupport = await priceos.features.getAccess("customer_123", "premium_support");
43
+
44
+ if (premiumSupport.hasAccess) {
45
+ // allow action
46
+ }
47
+
48
+ await priceos.usage.track({
49
+ customerId: "customer_123",
50
+ featureKey: "team_seats",
51
+ amount: 1,
52
+ });
53
+ ```
54
+
55
+ ## Next.js backend handlers (`priceos/next`)
56
+
57
+ Use built-in handlers for:
58
+ - `GET /api/priceos/v1/customer`
59
+ - `GET /api/priceos/v1/feature-access`
60
+ - `POST /api/priceos/v1/usage`
61
+
62
+ App Router:
63
+
64
+ ```ts
65
+ // app/api/priceos/[...path]/route.ts
66
+ import { priceosHandler } from "priceos/next";
67
+
68
+ export const { GET, POST } = priceosHandler({
69
+ getCustomerId: async (request: Request) => {
70
+ // resolve your current user/customer ID
71
+ return "customer_123";
72
+ },
73
+ });
74
+ ```
75
+
76
+ Pages Router:
77
+
78
+ ```ts
79
+ // pages/api/priceos/[...path].ts
80
+ import { priceosPagesHandler, type PriceOSPagesRequest } from "priceos/next";
81
+
82
+ export default priceosPagesHandler({
83
+ getCustomerId: async (_req: PriceOSPagesRequest) => {
84
+ return "customer_123";
85
+ },
86
+ });
87
+ ```
88
+
89
+ ## React hooks (`priceos/react`)
90
+
91
+ Wrap your app:
92
+
93
+ ```tsx
94
+ import { PriceOSProvider } from "priceos/react";
95
+
96
+ export function AppProviders({ children }: { children: React.ReactNode }) {
97
+ return <PriceOSProvider>{children}</PriceOSProvider>;
98
+ }
99
+ ```
100
+
101
+ Read feature access:
102
+
103
+ ```tsx
104
+ import { useFeatureAccess } from "priceos/react";
105
+ import type { MyFeatures } from "./priceos.types";
106
+
107
+ const { featureAccess, isLoading, error } = useFeatureAccess<MyFeatures>();
108
+ ```
109
+
110
+ Track usage:
111
+
112
+ ```tsx
113
+ import { useTrackUsage } from "priceos/react";
114
+ import type { MyFeatures } from "./priceos.types";
115
+
116
+ const { trackUsage } = useTrackUsage<MyFeatures>();
117
+ await trackUsage({ featureKey: "team_seats", amount: 1 });
118
+ ```
119
+
120
+ ## API surface
121
+
122
+ `PriceOS` client groups:
123
+ - `customers`: `get`, `link`, `create`, `update`, `delete`
124
+ - `features`: `getAccess(customerId, featureKey?)`
125
+ - `usage`: `track`, `set`, `getEvent`, `getEventByKey`, `updateEvent`, `voidEvent`, `deleteEvent`, `deleteEvents`, `trackBatch`, `listEvents`
126
+ - `bonuses`: `create`, `list`, `update`, `delete`
127
+
128
+ Error handling:
129
+ - Throws `PriceOSError` with `message`, optional `status`, and optional `details`.
130
+
131
+ ## CLI
132
+
133
+ Generate local feature types:
134
+
135
+ ```bash
136
+ npx priceos generate-types
137
+ ```
138
+
139
+ Options:
140
+ - `--api-key <key>`: use explicit API key (otherwise checks `.env.local`, `.env`, then `process.env`)
141
+ - `--out <path>`: output file path (default `priceos.d.ts`)
142
+ - `--out-dir <path>`: output directory (ignored when `--out` is set)
143
+ - `-h, --help`: CLI help
144
+
145
+ ## Docs
146
+
147
+ - [Quickstart](https://docs.priceos.com/quickstart)
148
+ - [backend](https://docs.priceos.com/nodejs-api)
149
+ - [React integration](https://docs.priceos.com/react-nextjs)
150
+ - [Generating types](https://docs.priceos.com/react/generating-types)
151
+ - [React `useFeatureAccess`](https://docs.priceos.com/react/use-feature-access)
152
+ - [React `useCustomer`](https://docs.priceos.com/react/use-customer)
153
+ - [React `useTrackUsage`](https://docs.priceos.com/react/use-track-usage)
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ // src/browser-unsupported.ts
4
+ throw new Error(
5
+ 'The "priceos" root SDK is server-only and cannot run in browser bundles. Use server routes or import "priceos/react" for frontend hooks.'
6
+ );
7
+ //# sourceMappingURL=browser-unsupported.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/browser-unsupported.ts"],"sourcesContent":["throw new Error(\n 'The \"priceos\" root SDK is server-only and cannot run in browser bundles. Use server routes or import \"priceos/react\" for frontend hooks.'\n);\n"],"mappings":";;;AAAA,MAAM,IAAI;AAAA,EACR;AACF;","names":[]}
File without changes
@@ -0,0 +1,5 @@
1
+ // src/browser-unsupported.ts
2
+ throw new Error(
3
+ 'The "priceos" root SDK is server-only and cannot run in browser bundles. Use server routes or import "priceos/react" for frontend hooks.'
4
+ );
5
+ //# sourceMappingURL=browser-unsupported.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/browser-unsupported.ts"],"sourcesContent":["throw new Error(\n 'The \"priceos\" root SDK is server-only and cannot run in browser bundles. Use server routes or import \"priceos/react\" for frontend hooks.'\n);\n"],"mappings":";AAAA,MAAM,IAAI;AAAA,EACR;AACF;","names":[]}
@@ -189,6 +189,8 @@ var PriceOS = class {
189
189
  log;
190
190
  customers;
191
191
  features;
192
+ pricing;
193
+ checkout;
192
194
  bonuses;
193
195
  usage;
194
196
  constructor(apiKey, opts = {}) {
@@ -245,12 +247,41 @@ var PriceOS = class {
245
247
  return data;
246
248
  }
247
249
  };
250
+ const getFeatureAccessForCustomer = async (customerId) => {
251
+ const { data, error, response } = await this.client.GET("/v1/feature-access", {
252
+ params: { query: { customerId }, header: this.header }
253
+ });
254
+ if (error) throwRequestError(this.log, error, response, "GET /v1/feature-access");
255
+ return data;
256
+ };
257
+ async function getFeatureAccess(customerId, featureKey) {
258
+ const featureAccess = await getFeatureAccessForCustomer(customerId);
259
+ if (featureKey === void 0) return featureAccess;
260
+ return featureAccess[featureKey];
261
+ }
248
262
  this.features = {
249
- getAccess: async (customerId) => {
250
- const { data, error, response } = await this.client.GET("/v1/feature-access", {
251
- params: { query: { customerId }, header: this.header }
263
+ getAccess: getFeatureAccess
264
+ };
265
+ this.pricing = {
266
+ getTable: async (input = {}) => {
267
+ const query = {
268
+ ...typeof input.customerId === "string" ? { customerId: input.customerId } : {},
269
+ ...typeof input.pricingTableKey === "string" ? { pricingTableKey: input.pricingTableKey } : {}
270
+ };
271
+ const { data, error, response } = await this.client.GET("/v1/pricing-table", {
272
+ params: { query, header: this.header }
273
+ });
274
+ if (error) throwRequestError(this.log, error, response, "GET /v1/pricing-table");
275
+ return data;
276
+ }
277
+ };
278
+ this.checkout = {
279
+ create: async (input) => {
280
+ const { data, error, response } = await this.client.POST("/v1/checkout", {
281
+ params: { header: this.header },
282
+ body: input
252
283
  });
253
- if (error) throwRequestError(this.log, error, response, "GET /v1/feature-access");
284
+ if (error) throwRequestError(this.log, error, response, "POST /v1/checkout");
254
285
  return data;
255
286
  }
256
287
  };
@@ -375,4 +406,4 @@ export {
375
406
  PriceOSError,
376
407
  PriceOS
377
408
  };
378
- //# sourceMappingURL=chunk-BZLBBQWU.js.map
409
+ //# sourceMappingURL=chunk-4OWSKJ7F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["import createClient from \"openapi-fetch\";\nimport type { Client } from \"openapi-fetch\";\nimport type { paths } from \"./gen/openapi\";\nimport {\n CreateBonusBody,\n CreateBonusResponse,\n CreateCustomerRequest,\n CreateCustomerResponse,\n DeleteBonusResponse,\n ListBonusesRequest,\n ListBonusesResponse,\n DeleteUsageEventsBody,\n DeleteUsageEventsResponse,\n DeleteUsageEventResponse,\n DeleteCustomerResponse,\n GetUsageEventResponse,\n GetUsageEventByKeyResponse,\n GetCustomerResponse,\n GetFeatureAccessResponse,\n LinkCustomerBody,\n LinkCustomerResponse,\n LimitFeatureKeyFromAccessMap,\n TrackedLimitFeatureKeyFromAccessMap,\n ListUsageEventsBody,\n ListUsageEventsResponse,\n SetUsageBody,\n SetUsageResponse,\n UpdateUsageEventRequest,\n UpdateUsageEventResponse,\n VoidUsageEventRequest,\n VoidUsageEventResponse,\n UpdateBonusRequest,\n UpdateBonusResponse,\n TrackUsageBody,\n TrackUsageBatchBody,\n TrackUsageBatchResponse,\n TrackUsageResponse,\n UpdateCustomerBody,\n UpdateCustomerResponse,\n GetPricingTableRequest,\n GetPricingTableResponse,\n CreateCheckoutRequest,\n CreateCheckoutResponse,\n} from \"./types\";\n\nexport type PriceOSLogLevel = \"none\" | \"error\" | \"warning\" | \"info\" | \"debug\";\n\n// --- Public options ---\nexport type PriceOSClientOptions = {\n logLevel?: PriceOSLogLevel;\n};\n\nconst RATE_LIMIT_STATUS = 429;\nconst MAX_RETRIES = 4;\nconst BASE_DELAY_MS = 250;\nconst BACKOFF_MULTIPLIER = 2;\nconst JITTER_MS = 250;\nconst RETRY_DELAY_CAP_MS = 5_000;\nconst REQUEST_TIMEOUT_MS = 20_000;\n\nconst LOG_LEVELS: Record<PriceOSLogLevel, number> = {\n none: 0,\n error: 1,\n warning: 2,\n info: 3,\n debug: 4,\n};\n\ntype Logger = {\n error: (message: string, details?: Record<string, unknown>) => void;\n warning: (message: string, details?: Record<string, unknown>) => void;\n info: (message: string, details?: Record<string, unknown>) => void;\n debug: (message: string, details?: Record<string, unknown>) => void;\n};\n\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst getRetryDelayMs = (retryCount: number): number => {\n const backoff = BASE_DELAY_MS * Math.pow(BACKOFF_MULTIPLIER, retryCount - 1);\n const jitter = Math.random() * JITTER_MS;\n return Math.min(RETRY_DELAY_CAP_MS, backoff + jitter);\n};\n\nconst createLogger = (logLevel: PriceOSLogLevel): Logger => {\n const shouldLog = (level: PriceOSLogLevel): boolean =>\n logLevel !== \"none\" && LOG_LEVELS[level] <= LOG_LEVELS[logLevel];\n\n const write = (\n level: PriceOSLogLevel,\n message: string,\n details?: Record<string, unknown>\n ): void => {\n if (!shouldLog(level)) return;\n const prefix = `[PriceOS] ${level.toUpperCase()}: ${message}`;\n const payload = details && Object.keys(details).length > 0 ? details : undefined;\n\n switch (level) {\n case \"error\":\n payload ? console.error(prefix, payload) : console.error(prefix);\n return;\n case \"warning\":\n payload ? console.warn(prefix, payload) : console.warn(prefix);\n return;\n case \"info\":\n payload ? console.info(prefix, payload) : console.info(prefix);\n return;\n case \"debug\":\n payload ? console.debug(prefix, payload) : console.debug(prefix);\n return;\n }\n };\n\n return {\n error: (message, details) => write(\"error\", message, details),\n warning: (message, details) => write(\"warning\", message, details),\n info: (message, details) => write(\"info\", message, details),\n debug: (message, details) => write(\"debug\", message, details),\n };\n};\n\nconst getUpstreamSignal = (input: RequestInfo | URL, init?: RequestInit): AbortSignal | undefined => {\n if (init?.signal) return init.signal;\n if (typeof Request !== \"undefined\" && input instanceof Request) return input.signal;\n return undefined;\n};\n\nconst stripSignal = (init?: RequestInit): RequestInit | undefined => {\n if (!init) return undefined;\n const { signal: _signal, ...rest } = init;\n return rest;\n};\n\nconst getRequestDetails = (\n input: RequestInfo | URL,\n init?: RequestInit\n): { method: string; url: string } => {\n const method =\n init?.method ??\n (typeof Request !== \"undefined\" && input instanceof Request ? input.method : \"GET\");\n const url =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n return { method, url };\n};\n\nconst prepareRetryRequest = async (\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n log: Logger,\n method: string,\n url: string\n): Promise<{ requestInput: RequestInfo | URL; baseInit?: RequestInit; canRetry: boolean }> => {\n if (!(typeof Request !== \"undefined\" && input instanceof Request)) {\n return { requestInput: input, baseInit: stripSignal(init), canRetry: true };\n }\n\n if (input.bodyUsed) {\n log.warning(\"Request body already used; retries disabled\", { method, url });\n return { requestInput: input, baseInit: stripSignal(init), canRetry: false };\n }\n\n let body: BodyInit | undefined = undefined;\n if (method !== \"GET\" && method !== \"HEAD\") {\n try {\n body = await input.clone().arrayBuffer();\n } catch (error) {\n log.warning(\"Unable to clone request body; retries disabled\", { method, url, error });\n return { requestInput: input, baseInit: stripSignal(init), canRetry: false };\n }\n }\n\n const headers = new Headers(input.headers);\n const baseInit = { ...stripSignal(init), method, headers, body };\n return { requestInput: input.url, baseInit, canRetry: true };\n};\n\nconst getErrorMessage = (error: unknown): string => {\n const maybeError = error as { error?: unknown } | null;\n if (maybeError && typeof maybeError.error === \"string\") return maybeError.error;\n return \"Request failed\";\n};\n\nconst throwRequestError = (\n log: Logger,\n error: unknown,\n response: Response | undefined,\n context: string\n): never => {\n log.error(\"Request failed\", { context, status: response?.status, error });\n throw new PriceOSError(getErrorMessage(error), { status: response?.status, details: error });\n};\n\nconst createRetryingFetch = (baseFetch: typeof fetch, log: Logger): typeof fetch => {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const { method, url } = getRequestDetails(input, init);\n const upstreamSignal = getUpstreamSignal(input, init);\n const { requestInput, baseInit, canRetry } = await prepareRetryRequest(\n input,\n init,\n log,\n method,\n url\n );\n let attempt = 0;\n while (true) {\n log.debug(\"Request attempt\", { method, url, attempt: attempt + 1, maxRetries: MAX_RETRIES });\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n let removeAbortListener: (() => void) | null = null;\n\n if (upstreamSignal) {\n if (upstreamSignal.aborted) {\n controller.abort();\n } else {\n const onAbort = () => controller.abort();\n upstreamSignal.addEventListener(\"abort\", onAbort);\n removeAbortListener = () => upstreamSignal.removeEventListener(\"abort\", onAbort);\n }\n }\n\n try {\n const requestInit = { ...(baseInit ?? {}), signal: controller.signal };\n const response = await baseFetch(requestInput, requestInit);\n if (response.status !== RATE_LIMIT_STATUS) return response;\n\n const retryAfter = response.headers.get(\"retry-after\") ?? undefined;\n log.warning(\"Rate limit hit (429)\", {\n method,\n url,\n attempt: attempt + 1,\n maxRetries: MAX_RETRIES,\n retryAfter,\n });\n\n if (!canRetry) {\n log.warning(\"Skipping retry because request body is not replayable\", { method, url });\n return response;\n }\n\n if (attempt >= MAX_RETRIES) {\n log.error(\"Rate limit retries exhausted\", { method, url, attempts: attempt + 1 });\n return response;\n }\n\n const delayMs = getRetryDelayMs(attempt + 1);\n log.info(\"Waiting to retry after rate limit\", {\n method,\n url,\n delayMs,\n nextAttempt: attempt + 2,\n maxRetries: MAX_RETRIES,\n });\n await sleep(delayMs);\n attempt += 1;\n } catch (error) {\n if (controller.signal.aborted) {\n const abortedByCaller = upstreamSignal?.aborted ?? false;\n if (abortedByCaller) {\n log.warning(\"Request aborted by caller\", { method, url, attempt: attempt + 1 });\n } else {\n log.error(\"Request timed out\", {\n method,\n url,\n attempt: attempt + 1,\n timeoutMs: REQUEST_TIMEOUT_MS,\n });\n }\n } else {\n log.error(\"Request failed\", { method, url, attempt: attempt + 1, error });\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n removeAbortListener?.();\n }\n }\n };\n};\n\nexport type PriceOSCustomersClient<TFeatureAccessMap = GetFeatureAccessResponse> = {\n get(customerId: string): Promise<GetCustomerResponse<TFeatureAccessMap> | null>;\n link(input: LinkCustomerBody): Promise<LinkCustomerResponse<TFeatureAccessMap> | null>;\n create(input: CreateCustomerRequest): Promise<CreateCustomerResponse<TFeatureAccessMap>>;\n update(input: UpdateCustomerBody): Promise<UpdateCustomerResponse<TFeatureAccessMap>>;\n delete(customerId: string): Promise<DeleteCustomerResponse>;\n};\n\ntype FeatureAccessRecord<TFeatureAccessMap> =\n TFeatureAccessMap extends Record<string, unknown> ? TFeatureAccessMap : Record<string, never>;\n\ntype FeatureAccessKey<TFeatureAccessMap> = keyof FeatureAccessRecord<TFeatureAccessMap> & string;\n\nexport type PriceOSFeaturesClient<TFeatureAccessMap = GetFeatureAccessResponse> = {\n getAccess(customerId: string): Promise<TFeatureAccessMap>;\n getAccess<TFeatureKey extends FeatureAccessKey<TFeatureAccessMap>>(\n customerId: string,\n featureKey: TFeatureKey\n ): Promise<FeatureAccessRecord<TFeatureAccessMap>[TFeatureKey]>;\n};\n\nexport type PriceOSPricingClient = {\n getTable(input?: GetPricingTableRequest): Promise<GetPricingTableResponse>;\n};\n\nexport type PriceOSCheckoutClient = {\n create(input: CreateCheckoutRequest): Promise<CreateCheckoutResponse>;\n};\n\nexport type PriceOSBonusesClient<TFeatureAccessMap = GetFeatureAccessResponse> = {\n create(\n input: CreateBonusBody<TrackedLimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<CreateBonusResponse>;\n list(\n input: ListBonusesRequest<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<ListBonusesResponse>;\n update(input: UpdateBonusRequest): Promise<UpdateBonusResponse>;\n delete(bonusId: string): Promise<DeleteBonusResponse>;\n};\n\nexport type PriceOSUsageClient<TFeatureAccessMap = GetFeatureAccessResponse> = {\n track(\n input: TrackUsageBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<TrackUsageResponse>;\n set(\n input: SetUsageBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<SetUsageResponse>;\n getEvent(eventId: string): Promise<GetUsageEventResponse>;\n getEventByKey(eventKey: string): Promise<GetUsageEventByKeyResponse>;\n updateEvent(input: UpdateUsageEventRequest): Promise<UpdateUsageEventResponse>;\n voidEvent(input: VoidUsageEventRequest): Promise<VoidUsageEventResponse>;\n deleteEvent(eventId: string): Promise<DeleteUsageEventResponse>;\n deleteEvents(\n input: DeleteUsageEventsBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<DeleteUsageEventsResponse>;\n trackBatch(\n input: TrackUsageBatchBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<TrackUsageBatchResponse>;\n listEvents(\n input: ListUsageEventsBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<ListUsageEventsResponse>;\n};\n\n// --- Public SDK surface type ---\nexport type PriceOSHttpClient<TFeatureAccessMap = GetFeatureAccessResponse> = {\n customers: PriceOSCustomersClient<TFeatureAccessMap>;\n features: PriceOSFeaturesClient<TFeatureAccessMap>;\n pricing: PriceOSPricingClient;\n checkout: PriceOSCheckoutClient;\n bonuses: PriceOSBonusesClient<TFeatureAccessMap>;\n usage: PriceOSUsageClient<TFeatureAccessMap>;\n};\n\nexport class PriceOSError extends Error {\n status?: number;\n details?: unknown;\n\n constructor(message: string, opts?: { status?: number; details?: unknown }) {\n super(message);\n this.name = \"PriceOSError\";\n this.status = opts?.status;\n this.details = opts?.details;\n }\n}\n\nexport class PriceOS<TFeatureAccessMap = GetFeatureAccessResponse>\n implements PriceOSHttpClient<TFeatureAccessMap>\n{\n private client: Client<paths>;\n private header: { \"x-api-key\": string };\n private log: Logger;\n customers: PriceOSCustomersClient<TFeatureAccessMap>;\n features: PriceOSFeaturesClient<TFeatureAccessMap>;\n pricing: PriceOSPricingClient;\n checkout: PriceOSCheckoutClient;\n bonuses: PriceOSBonusesClient<TFeatureAccessMap>;\n usage: PriceOSUsageClient<TFeatureAccessMap>;\n\n constructor(apiKey: string, opts: PriceOSClientOptions = {}) {\n const logLevel = opts.logLevel ?? \"none\";\n this.log = createLogger(logLevel);\n const baseUrl = \"https://api.priceos.com\";\n this.header = { \"x-api-key\": apiKey };\n const fetchWithRetry = createRetryingFetch(fetch, this.log);\n this.client = createClient<paths>({\n baseUrl,\n fetch: fetchWithRetry,\n headers: {\n \"x-api-key\": apiKey,\n },\n });\n\n this.customers = {\n get: async (customerId: string): Promise<GetCustomerResponse<TFeatureAccessMap> | null> => {\n const { data, error, response } = await this.client.GET(\"/v1/customers/{customerId}\", {\n params: { path: { customerId }, header: this.header },\n });\n if (error) throwRequestError(this.log, error, response, \"GET /v1/customers/{customerId}\");\n return (data ?? null) as GetCustomerResponse<TFeatureAccessMap> | null;\n },\n link: async (\n input: LinkCustomerBody\n ): Promise<LinkCustomerResponse<TFeatureAccessMap> | null> => {\n const { data, error, response } = await this.client.POST(\"/v1/customers/link\", {\n params: { header: this.header },\n body: input,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/customers/link\");\n return (data ?? null) as LinkCustomerResponse<TFeatureAccessMap> | null;\n },\n create: async (input: CreateCustomerRequest): Promise<CreateCustomerResponse<TFeatureAccessMap>> => {\n const { data, error, response } = await this.client.POST(\"/v1/customers\", {\n params: { header: this.header },\n body: input,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/customers\");\n return data! as CreateCustomerResponse<TFeatureAccessMap>;\n },\n update: async (input: UpdateCustomerBody): Promise<UpdateCustomerResponse<TFeatureAccessMap>> => {\n const { customerId, ...body } = input;\n const { data, error, response } = await this.client.PUT(\"/v1/customers/{customerId}\", {\n params: { path: { customerId }, header: this.header },\n body,\n });\n if (error) throwRequestError(this.log, error, response, \"PUT /v1/customers/{customerId}\");\n return data! as UpdateCustomerResponse<TFeatureAccessMap>;\n },\n delete: async (customerId: string): Promise<DeleteCustomerResponse> => {\n const { data, error, response } = await this.client.DELETE(\"/v1/customers/{customerId}\", {\n params: { path: { customerId }, header: this.header },\n });\n if (error) throwRequestError(this.log, error, response, \"DELETE /v1/customers/{customerId}\");\n return data! as DeleteCustomerResponse;\n },\n };\n\n const getFeatureAccessForCustomer = async (customerId: string): Promise<TFeatureAccessMap> => {\n const { data, error, response } = await this.client.GET(\"/v1/feature-access\", {\n params: { query: { customerId }, header: this.header },\n });\n if (error) throwRequestError(this.log, error, response, \"GET /v1/feature-access\");\n return data! as TFeatureAccessMap;\n };\n\n function getFeatureAccess(customerId: string): Promise<TFeatureAccessMap>;\n function getFeatureAccess<TFeatureKey extends FeatureAccessKey<TFeatureAccessMap>>(\n customerId: string,\n featureKey: TFeatureKey\n ): Promise<FeatureAccessRecord<TFeatureAccessMap>[TFeatureKey]>;\n async function getFeatureAccess<TFeatureKey extends FeatureAccessKey<TFeatureAccessMap>>(\n customerId: string,\n featureKey?: TFeatureKey\n ): Promise<TFeatureAccessMap | FeatureAccessRecord<TFeatureAccessMap>[TFeatureKey]> {\n const featureAccess = await getFeatureAccessForCustomer(customerId);\n if (featureKey === undefined) return featureAccess;\n return (featureAccess as FeatureAccessRecord<TFeatureAccessMap>)[featureKey];\n }\n\n this.features = {\n getAccess: getFeatureAccess,\n };\n\n this.pricing = {\n getTable: async (input: GetPricingTableRequest = {}): Promise<GetPricingTableResponse> => {\n const query = {\n ...(typeof input.customerId === \"string\" ? { customerId: input.customerId } : {}),\n ...(typeof input.pricingTableKey === \"string\" ? { pricingTableKey: input.pricingTableKey } : {}),\n };\n const { data, error, response } = await this.client.GET(\"/v1/pricing-table\", {\n params: { query, header: this.header },\n });\n if (error) throwRequestError(this.log, error, response, \"GET /v1/pricing-table\");\n return data! as GetPricingTableResponse;\n },\n };\n\n this.checkout = {\n create: async (input: CreateCheckoutRequest): Promise<CreateCheckoutResponse> => {\n const { data, error, response } = await this.client.POST(\"/v1/checkout\", {\n params: { header: this.header },\n body: input,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/checkout\");\n return data! as CreateCheckoutResponse;\n },\n };\n\n this.bonuses = {\n create: async (\n input: CreateBonusBody<TrackedLimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<CreateBonusResponse> => {\n const { data, error, response } = await this.client.POST(\"/v1/bonuses\", {\n params: { header: this.header },\n body: input,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/bonuses\");\n return data!;\n },\n list: async (\n input: ListBonusesRequest<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<ListBonusesResponse> => {\n const { data, error, response } = await this.client.GET(\"/v1/bonuses\", {\n params: { header: this.header, query: input },\n });\n if (error) throwRequestError(this.log, error, response, \"GET /v1/bonuses\");\n return data!;\n },\n update: async (input: UpdateBonusRequest): Promise<UpdateBonusResponse> => {\n const { bonusId, ...body } = input;\n const { data, error, response } = await this.client.PUT(\"/v1/bonuses/{bonusId}\", {\n params: { header: this.header, path: { bonusId } },\n body,\n });\n if (error) throwRequestError(this.log, error, response, \"PUT /v1/bonuses/{bonusId}\");\n return data!;\n },\n delete: async (bonusId: string): Promise<DeleteBonusResponse> => {\n const { data, error, response } = await this.client.DELETE(\"/v1/bonuses/{bonusId}\", {\n params: { header: this.header, path: { bonusId } },\n });\n if (error) throwRequestError(this.log, error, response, \"DELETE /v1/bonuses/{bonusId}\");\n return data!;\n },\n };\n\n this.usage = {\n track: async (\n input: TrackUsageBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<TrackUsageResponse> => {\n const { data, error, response } = await this.client.POST(\"/v1/usage\", {\n params: { header: this.header },\n body: input,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/usage\");\n return data!;\n },\n set: async (\n input: SetUsageBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<SetUsageResponse> => {\n const { data, error, response } = await this.client.POST(\"/v1/usage/set\", {\n params: { header: this.header },\n body: input,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/usage/set\");\n return data!;\n },\n getEvent: async (eventId: string): Promise<GetUsageEventResponse> => {\n const { data, error, response } = await this.client.GET(\"/v1/usage/{id}\", {\n params: { header: this.header, path: { id: eventId } },\n });\n if (error) throwRequestError(this.log, error, response, \"GET /v1/usage/{id}\");\n return data!;\n },\n getEventByKey: async (eventKey: string): Promise<GetUsageEventByKeyResponse> => {\n const { data, error, response } = await this.client.GET(\"/v1/usage/event-key/{eventKey}\", {\n params: { header: this.header, path: { eventKey } },\n });\n if (error) throwRequestError(this.log, error, response, \"GET /v1/usage/event-key/{eventKey}\");\n return data!;\n },\n updateEvent: async (input: UpdateUsageEventRequest): Promise<UpdateUsageEventResponse> => {\n const { id, ...body } = input;\n const { data, error, response } = await this.client.PUT(\"/v1/usage/{id}\", {\n params: { header: this.header, path: { id } },\n body,\n });\n if (error) throwRequestError(this.log, error, response, \"PUT /v1/usage/{id}\");\n return data!;\n },\n voidEvent: async (input: VoidUsageEventRequest): Promise<VoidUsageEventResponse> => {\n const { id, ...body } = input;\n const { data, error, response } = await this.client.POST(\"/v1/usage/{id}/void\", {\n params: { header: this.header, path: { id } },\n body,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/usage/{id}/void\");\n return data!;\n },\n deleteEvent: async (eventId: string): Promise<DeleteUsageEventResponse> => {\n const { data, error, response } = await this.client.DELETE(\"/v1/usage/{id}\", {\n params: { header: this.header, path: { id: eventId } },\n });\n if (error) throwRequestError(this.log, error, response, \"DELETE /v1/usage/{id}\");\n return data!;\n },\n deleteEvents: async (\n input: DeleteUsageEventsBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<DeleteUsageEventsResponse> => {\n const { data, error, response } = await this.client.POST(\"/v1/usage/delete\", {\n params: { header: this.header },\n body: input,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/usage/delete\");\n return data!;\n },\n trackBatch: async (\n input: TrackUsageBatchBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<TrackUsageBatchResponse> => {\n const { data, error, response } = await this.client.POST(\"/v1/usage/batch\", {\n params: { header: this.header },\n body: input,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/usage/batch\");\n return data!;\n },\n listEvents: async (\n input: ListUsageEventsBody<LimitFeatureKeyFromAccessMap<TFeatureAccessMap>>\n ): Promise<ListUsageEventsResponse> => {\n const { data, error, response } = await this.client.POST(\"/v1/usage/events\", {\n params: { header: this.header },\n body: input,\n });\n if (error) throwRequestError(this.log, error, response, \"POST /v1/usage/events\");\n return data!;\n },\n };\n }\n}\n"],"mappings":"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","names":[]}
package/dist/cli.cjs CHANGED
@@ -153,6 +153,7 @@ export type LimitFeatureUsage = {
153
153
  used: number;
154
154
  remaining: number | null;
155
155
  bonusRemaining: number;
156
+ hasReachedLimit: boolean;
156
157
  bonusUsed: number;
157
158
  nextReset: number | null;
158
159
  lastReset: number | null;
@@ -172,7 +173,7 @@ export type UntrackedLimitFeatureAccess = {
172
173
  };
173
174
  export type LimitFeatureAccess = TrackedLimitFeatureAccess | UntrackedLimitFeatureAccess;
174
175
  export type FeatureAccessEntry = BooleanFeatureAccess | LimitFeatureAccess;
175
- export type FeatureAccessMap = {
176
+ export type MyFeatures = {
176
177
  ${mapLines.join("\n")}
177
178
  };
178
179
  `;
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\ntype Feature = {\n featureKey: string;\n type?: \"boolean\" | \"limit\" | null;\n tracksUsage?: boolean | null;\n};\n\nfunction argValue(args: string[], name: string) {\n const idx = args.indexOf(name);\n if (idx === -1) return undefined;\n return args[idx + 1];\n}\n\nfunction hasFlag(args: string[], name: string) {\n return args.includes(name);\n}\n\nasync function readEnvFile(filePath: string) {\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n const entries: Record<string, string> = {};\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx === -1) continue;\n const rawKey = trimmed.slice(0, eqIdx).trim();\n const key = rawKey.startsWith(\"export \") ? rawKey.slice(\"export \".length).trim() : rawKey;\n let value = trimmed.slice(eqIdx + 1).trim();\n if (\n (value.startsWith(\"\\\"\") && value.endsWith(\"\\\"\")) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (key) {\n entries[key] = value;\n }\n }\n return entries;\n } catch {\n return {};\n }\n}\n\nfunction printHelp() {\n console.log(`\npriceos generate-types\n\nGenerates TypeScript feature access types for your PriceOS workspace.\n\nOptions:\n --api-key <key> PriceOS API key (defaults to .env.local, .env, or env PRICEOS_API_KEY) [required]\n --out <path> Output .d.ts file (default: priceos.d.ts in current directory)\n --out-dir <path> Output directory for priceos.d.ts (ignored if --out is set)\n -h, --help Show help\n\nExamples:\n priceos generate-types --api-key sk_test_... --out ./priceos.d.ts\n priceos generate-types --api-key sk_test_... --out-dir ./src\n`.trim());\n}\n\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || hasFlag(args, \"--help\") || hasFlag(args, \"-h\")) {\n printHelp();\n process.exit(args.length === 0 ? 1 : 0);\n }\n\n const cmd = args[0];\n if (cmd !== \"generate-types\") {\n console.error(`Unknown command: ${cmd}`);\n printHelp();\n process.exit(1);\n }\n\n const envLocal = await readEnvFile(path.resolve(process.cwd(), \".env.local\"));\n const envDefault = await readEnvFile(path.resolve(process.cwd(), \".env\"));\n const apiKey =\n argValue(args, \"--api-key\") ??\n envLocal.PRICEOS_API_KEY ??\n envDefault.PRICEOS_API_KEY ??\n process.env.PRICEOS_API_KEY;\n\n if (!apiKey) {\n console.error(\"Missing API key. Provide --api-key <key> or set PRICEOS_API_KEY in .env.local/.env.\");\n process.exit(1);\n }\n\n const outRel = argValue(args, \"--out\");\n const outDir = argValue(args, \"--out-dir\");\n const outFile = outRel ?? \"priceos.d.ts\";\n const outPath = outDir && !outRel\n ? path.resolve(process.cwd(), outDir, outFile)\n : path.resolve(process.cwd(), outFile);\n const outDisplay = outDir && !outRel ? path.join(outDir, outFile) : outFile;\n\n const url = \"https://api.priceos.com/v1/features\";\n const res = await fetch(url, {\n headers: { \"x-api-key\": apiKey },\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n console.error(`Failed to fetch features: ${res.status} ${res.statusText}\\n${text}`);\n process.exit(1);\n }\n\n const features = (await res.json()) as Feature[];\n const typeByKey = new Map<string, \"boolean\" | \"limit\" | \"unknown\">();\n const trackingByKey = new Map<string, \"tracked\" | \"untracked\" | \"unknown\">();\n\n for (const feature of features ?? []) {\n if (!feature?.featureKey) continue;\n const key = feature.featureKey;\n const nextType = feature.type === \"boolean\" || feature.type === \"limit\" ? feature.type : \"unknown\";\n const currentType = typeByKey.get(key);\n if (!currentType) {\n typeByKey.set(key, nextType);\n } else if (currentType !== nextType) {\n typeByKey.set(key, \"unknown\");\n }\n\n if (nextType !== \"limit\") continue;\n\n const nextTracking =\n feature.tracksUsage === true\n ? \"tracked\"\n : feature.tracksUsage === false\n ? \"untracked\"\n : \"unknown\";\n const currentTracking = trackingByKey.get(key);\n if (!currentTracking) {\n trackingByKey.set(key, nextTracking);\n continue;\n }\n if (currentTracking !== nextTracking) {\n trackingByKey.set(key, \"unknown\");\n }\n }\n\n const keys = [...typeByKey.keys()].sort();\n const union = keys.length ? keys.map((k) => JSON.stringify(k)).join(\" | \") : \"never\";\n const limitKeys = keys.filter((key) => typeByKey.get(key) === \"limit\");\n const limitUnion = limitKeys.length ? limitKeys.map((k) => JSON.stringify(k)).join(\" | \") : \"never\";\n const mapLines = keys.map((key) => {\n const featureType = typeByKey.get(key);\n const accessType =\n featureType === \"boolean\"\n ? \"BooleanFeatureAccess\"\n : featureType === \"limit\"\n ? trackingByKey.get(key) === \"tracked\"\n ? \"TrackedLimitFeatureAccess\"\n : trackingByKey.get(key) === \"untracked\"\n ? \"UntrackedLimitFeatureAccess\"\n : \"LimitFeatureAccess\"\n : \"FeatureAccessEntry\";\n return ` ${JSON.stringify(key)}: ${accessType};`;\n });\n\n const content = `// Auto-generated by PriceOS (priceos generate-types). Do not edit.\nexport type FeatureKey = ${union};\nexport type LimitFeatureKey = ${limitUnion};\nexport type BooleanFeatureAccess = {\n type: \"boolean\";\n hasAccess: boolean;\n};\nexport type LimitFeatureUsage = {\n used: number;\n remaining: number | null;\n bonusRemaining: number;\n bonusUsed: number;\n nextReset: number | null;\n lastReset: number | null;\n};\nexport type TrackedLimitFeatureAccess = {\n type: \"limit\";\n hasAccess: boolean;\n isUnlimited: boolean;\n limit: number | null;\n usage: LimitFeatureUsage;\n};\nexport type UntrackedLimitFeatureAccess = {\n type: \"limit\";\n hasAccess: boolean;\n isUnlimited: boolean;\n limit: number | null;\n};\nexport type LimitFeatureAccess = TrackedLimitFeatureAccess | UntrackedLimitFeatureAccess;\nexport type FeatureAccessEntry = BooleanFeatureAccess | LimitFeatureAccess;\nexport type FeatureAccessMap = {\n${mapLines.join(\"\\n\")}\n};\n`;\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, content, \"utf8\");\n\n console.log(`Generated ${outDisplay} (${keys.length} feature keys)`);\n}\n\nmain().catch((e) => {\n console.error(e);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\ntype Feature = {\n featureKey: string;\n type?: \"boolean\" | \"limit\" | null;\n tracksUsage?: boolean | null;\n};\n\nfunction argValue(args: string[], name: string) {\n const idx = args.indexOf(name);\n if (idx === -1) return undefined;\n return args[idx + 1];\n}\n\nfunction hasFlag(args: string[], name: string) {\n return args.includes(name);\n}\n\nasync function readEnvFile(filePath: string) {\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n const entries: Record<string, string> = {};\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx === -1) continue;\n const rawKey = trimmed.slice(0, eqIdx).trim();\n const key = rawKey.startsWith(\"export \") ? rawKey.slice(\"export \".length).trim() : rawKey;\n let value = trimmed.slice(eqIdx + 1).trim();\n if (\n (value.startsWith(\"\\\"\") && value.endsWith(\"\\\"\")) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (key) {\n entries[key] = value;\n }\n }\n return entries;\n } catch {\n return {};\n }\n}\n\nfunction printHelp() {\n console.log(`\npriceos generate-types\n\nGenerates TypeScript feature access types for your PriceOS workspace.\n\nOptions:\n --api-key <key> PriceOS API key (defaults to .env.local, .env, or env PRICEOS_API_KEY) [required]\n --out <path> Output .d.ts file (default: priceos.d.ts in current directory)\n --out-dir <path> Output directory for priceos.d.ts (ignored if --out is set)\n -h, --help Show help\n\nExamples:\n priceos generate-types --api-key sk_test_... --out ./priceos.d.ts\n priceos generate-types --api-key sk_test_... --out-dir ./src\n`.trim());\n}\n\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || hasFlag(args, \"--help\") || hasFlag(args, \"-h\")) {\n printHelp();\n process.exit(args.length === 0 ? 1 : 0);\n }\n\n const cmd = args[0];\n if (cmd !== \"generate-types\") {\n console.error(`Unknown command: ${cmd}`);\n printHelp();\n process.exit(1);\n }\n\n const envLocal = await readEnvFile(path.resolve(process.cwd(), \".env.local\"));\n const envDefault = await readEnvFile(path.resolve(process.cwd(), \".env\"));\n const apiKey =\n argValue(args, \"--api-key\") ??\n envLocal.PRICEOS_API_KEY ??\n envDefault.PRICEOS_API_KEY ??\n process.env.PRICEOS_API_KEY;\n\n if (!apiKey) {\n console.error(\"Missing API key. Provide --api-key <key> or set PRICEOS_API_KEY in .env.local/.env.\");\n process.exit(1);\n }\n\n const outRel = argValue(args, \"--out\");\n const outDir = argValue(args, \"--out-dir\");\n const outFile = outRel ?? \"priceos.d.ts\";\n const outPath = outDir && !outRel\n ? path.resolve(process.cwd(), outDir, outFile)\n : path.resolve(process.cwd(), outFile);\n const outDisplay = outDir && !outRel ? path.join(outDir, outFile) : outFile;\n\n const url = \"https://api.priceos.com/v1/features\";\n const res = await fetch(url, {\n headers: { \"x-api-key\": apiKey },\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n console.error(`Failed to fetch features: ${res.status} ${res.statusText}\\n${text}`);\n process.exit(1);\n }\n\n const features = (await res.json()) as Feature[];\n const typeByKey = new Map<string, \"boolean\" | \"limit\" | \"unknown\">();\n const trackingByKey = new Map<string, \"tracked\" | \"untracked\" | \"unknown\">();\n\n for (const feature of features ?? []) {\n if (!feature?.featureKey) continue;\n const key = feature.featureKey;\n const nextType = feature.type === \"boolean\" || feature.type === \"limit\" ? feature.type : \"unknown\";\n const currentType = typeByKey.get(key);\n if (!currentType) {\n typeByKey.set(key, nextType);\n } else if (currentType !== nextType) {\n typeByKey.set(key, \"unknown\");\n }\n\n if (nextType !== \"limit\") continue;\n\n const nextTracking =\n feature.tracksUsage === true\n ? \"tracked\"\n : feature.tracksUsage === false\n ? \"untracked\"\n : \"unknown\";\n const currentTracking = trackingByKey.get(key);\n if (!currentTracking) {\n trackingByKey.set(key, nextTracking);\n continue;\n }\n if (currentTracking !== nextTracking) {\n trackingByKey.set(key, \"unknown\");\n }\n }\n\n const keys = [...typeByKey.keys()].sort();\n const union = keys.length ? keys.map((k) => JSON.stringify(k)).join(\" | \") : \"never\";\n const limitKeys = keys.filter((key) => typeByKey.get(key) === \"limit\");\n const limitUnion = limitKeys.length ? limitKeys.map((k) => JSON.stringify(k)).join(\" | \") : \"never\";\n const mapLines = keys.map((key) => {\n const featureType = typeByKey.get(key);\n const accessType =\n featureType === \"boolean\"\n ? \"BooleanFeatureAccess\"\n : featureType === \"limit\"\n ? trackingByKey.get(key) === \"tracked\"\n ? \"TrackedLimitFeatureAccess\"\n : trackingByKey.get(key) === \"untracked\"\n ? \"UntrackedLimitFeatureAccess\"\n : \"LimitFeatureAccess\"\n : \"FeatureAccessEntry\";\n return ` ${JSON.stringify(key)}: ${accessType};`;\n });\n\n const content = `// Auto-generated by PriceOS (priceos generate-types). Do not edit.\nexport type FeatureKey = ${union};\nexport type LimitFeatureKey = ${limitUnion};\nexport type BooleanFeatureAccess = {\n type: \"boolean\";\n hasAccess: boolean;\n};\nexport type LimitFeatureUsage = {\n used: number;\n remaining: number | null;\n bonusRemaining: number;\n hasReachedLimit: boolean;\n bonusUsed: number;\n nextReset: number | null;\n lastReset: number | null;\n};\nexport type TrackedLimitFeatureAccess = {\n type: \"limit\";\n hasAccess: boolean;\n isUnlimited: boolean;\n limit: number | null;\n usage: LimitFeatureUsage;\n};\nexport type UntrackedLimitFeatureAccess = {\n type: \"limit\";\n hasAccess: boolean;\n isUnlimited: boolean;\n limit: number | null;\n};\nexport type LimitFeatureAccess = TrackedLimitFeatureAccess | UntrackedLimitFeatureAccess;\nexport type FeatureAccessEntry = BooleanFeatureAccess | LimitFeatureAccess;\nexport type MyFeatures = {\n${mapLines.join(\"\\n\")}\n};\n`;\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, content, \"utf8\");\n\n console.log(`Generated ${outDisplay} (${keys.length} feature keys)`);\n}\n\nmain().catch((e) => {\n console.error(e);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path"]}
package/dist/cli.js CHANGED
@@ -130,6 +130,7 @@ export type LimitFeatureUsage = {
130
130
  used: number;
131
131
  remaining: number | null;
132
132
  bonusRemaining: number;
133
+ hasReachedLimit: boolean;
133
134
  bonusUsed: number;
134
135
  nextReset: number | null;
135
136
  lastReset: number | null;
@@ -149,7 +150,7 @@ export type UntrackedLimitFeatureAccess = {
149
150
  };
150
151
  export type LimitFeatureAccess = TrackedLimitFeatureAccess | UntrackedLimitFeatureAccess;
151
152
  export type FeatureAccessEntry = BooleanFeatureAccess | LimitFeatureAccess;
152
- export type FeatureAccessMap = {
153
+ export type MyFeatures = {
153
154
  ${mapLines.join("\n")}
154
155
  };
155
156
  `;
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\ntype Feature = {\n featureKey: string;\n type?: \"boolean\" | \"limit\" | null;\n tracksUsage?: boolean | null;\n};\n\nfunction argValue(args: string[], name: string) {\n const idx = args.indexOf(name);\n if (idx === -1) return undefined;\n return args[idx + 1];\n}\n\nfunction hasFlag(args: string[], name: string) {\n return args.includes(name);\n}\n\nasync function readEnvFile(filePath: string) {\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n const entries: Record<string, string> = {};\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx === -1) continue;\n const rawKey = trimmed.slice(0, eqIdx).trim();\n const key = rawKey.startsWith(\"export \") ? rawKey.slice(\"export \".length).trim() : rawKey;\n let value = trimmed.slice(eqIdx + 1).trim();\n if (\n (value.startsWith(\"\\\"\") && value.endsWith(\"\\\"\")) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (key) {\n entries[key] = value;\n }\n }\n return entries;\n } catch {\n return {};\n }\n}\n\nfunction printHelp() {\n console.log(`\npriceos generate-types\n\nGenerates TypeScript feature access types for your PriceOS workspace.\n\nOptions:\n --api-key <key> PriceOS API key (defaults to .env.local, .env, or env PRICEOS_API_KEY) [required]\n --out <path> Output .d.ts file (default: priceos.d.ts in current directory)\n --out-dir <path> Output directory for priceos.d.ts (ignored if --out is set)\n -h, --help Show help\n\nExamples:\n priceos generate-types --api-key sk_test_... --out ./priceos.d.ts\n priceos generate-types --api-key sk_test_... --out-dir ./src\n`.trim());\n}\n\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || hasFlag(args, \"--help\") || hasFlag(args, \"-h\")) {\n printHelp();\n process.exit(args.length === 0 ? 1 : 0);\n }\n\n const cmd = args[0];\n if (cmd !== \"generate-types\") {\n console.error(`Unknown command: ${cmd}`);\n printHelp();\n process.exit(1);\n }\n\n const envLocal = await readEnvFile(path.resolve(process.cwd(), \".env.local\"));\n const envDefault = await readEnvFile(path.resolve(process.cwd(), \".env\"));\n const apiKey =\n argValue(args, \"--api-key\") ??\n envLocal.PRICEOS_API_KEY ??\n envDefault.PRICEOS_API_KEY ??\n process.env.PRICEOS_API_KEY;\n\n if (!apiKey) {\n console.error(\"Missing API key. Provide --api-key <key> or set PRICEOS_API_KEY in .env.local/.env.\");\n process.exit(1);\n }\n\n const outRel = argValue(args, \"--out\");\n const outDir = argValue(args, \"--out-dir\");\n const outFile = outRel ?? \"priceos.d.ts\";\n const outPath = outDir && !outRel\n ? path.resolve(process.cwd(), outDir, outFile)\n : path.resolve(process.cwd(), outFile);\n const outDisplay = outDir && !outRel ? path.join(outDir, outFile) : outFile;\n\n const url = \"https://api.priceos.com/v1/features\";\n const res = await fetch(url, {\n headers: { \"x-api-key\": apiKey },\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n console.error(`Failed to fetch features: ${res.status} ${res.statusText}\\n${text}`);\n process.exit(1);\n }\n\n const features = (await res.json()) as Feature[];\n const typeByKey = new Map<string, \"boolean\" | \"limit\" | \"unknown\">();\n const trackingByKey = new Map<string, \"tracked\" | \"untracked\" | \"unknown\">();\n\n for (const feature of features ?? []) {\n if (!feature?.featureKey) continue;\n const key = feature.featureKey;\n const nextType = feature.type === \"boolean\" || feature.type === \"limit\" ? feature.type : \"unknown\";\n const currentType = typeByKey.get(key);\n if (!currentType) {\n typeByKey.set(key, nextType);\n } else if (currentType !== nextType) {\n typeByKey.set(key, \"unknown\");\n }\n\n if (nextType !== \"limit\") continue;\n\n const nextTracking =\n feature.tracksUsage === true\n ? \"tracked\"\n : feature.tracksUsage === false\n ? \"untracked\"\n : \"unknown\";\n const currentTracking = trackingByKey.get(key);\n if (!currentTracking) {\n trackingByKey.set(key, nextTracking);\n continue;\n }\n if (currentTracking !== nextTracking) {\n trackingByKey.set(key, \"unknown\");\n }\n }\n\n const keys = [...typeByKey.keys()].sort();\n const union = keys.length ? keys.map((k) => JSON.stringify(k)).join(\" | \") : \"never\";\n const limitKeys = keys.filter((key) => typeByKey.get(key) === \"limit\");\n const limitUnion = limitKeys.length ? limitKeys.map((k) => JSON.stringify(k)).join(\" | \") : \"never\";\n const mapLines = keys.map((key) => {\n const featureType = typeByKey.get(key);\n const accessType =\n featureType === \"boolean\"\n ? \"BooleanFeatureAccess\"\n : featureType === \"limit\"\n ? trackingByKey.get(key) === \"tracked\"\n ? \"TrackedLimitFeatureAccess\"\n : trackingByKey.get(key) === \"untracked\"\n ? \"UntrackedLimitFeatureAccess\"\n : \"LimitFeatureAccess\"\n : \"FeatureAccessEntry\";\n return ` ${JSON.stringify(key)}: ${accessType};`;\n });\n\n const content = `// Auto-generated by PriceOS (priceos generate-types). Do not edit.\nexport type FeatureKey = ${union};\nexport type LimitFeatureKey = ${limitUnion};\nexport type BooleanFeatureAccess = {\n type: \"boolean\";\n hasAccess: boolean;\n};\nexport type LimitFeatureUsage = {\n used: number;\n remaining: number | null;\n bonusRemaining: number;\n bonusUsed: number;\n nextReset: number | null;\n lastReset: number | null;\n};\nexport type TrackedLimitFeatureAccess = {\n type: \"limit\";\n hasAccess: boolean;\n isUnlimited: boolean;\n limit: number | null;\n usage: LimitFeatureUsage;\n};\nexport type UntrackedLimitFeatureAccess = {\n type: \"limit\";\n hasAccess: boolean;\n isUnlimited: boolean;\n limit: number | null;\n};\nexport type LimitFeatureAccess = TrackedLimitFeatureAccess | UntrackedLimitFeatureAccess;\nexport type FeatureAccessEntry = BooleanFeatureAccess | LimitFeatureAccess;\nexport type FeatureAccessMap = {\n${mapLines.join(\"\\n\")}\n};\n`;\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, content, \"utf8\");\n\n console.log(`Generated ${outDisplay} (${keys.length} feature keys)`);\n}\n\nmain().catch((e) => {\n console.error(e);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\ntype Feature = {\n featureKey: string;\n type?: \"boolean\" | \"limit\" | null;\n tracksUsage?: boolean | null;\n};\n\nfunction argValue(args: string[], name: string) {\n const idx = args.indexOf(name);\n if (idx === -1) return undefined;\n return args[idx + 1];\n}\n\nfunction hasFlag(args: string[], name: string) {\n return args.includes(name);\n}\n\nasync function readEnvFile(filePath: string) {\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n const entries: Record<string, string> = {};\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIdx = trimmed.indexOf(\"=\");\n if (eqIdx === -1) continue;\n const rawKey = trimmed.slice(0, eqIdx).trim();\n const key = rawKey.startsWith(\"export \") ? rawKey.slice(\"export \".length).trim() : rawKey;\n let value = trimmed.slice(eqIdx + 1).trim();\n if (\n (value.startsWith(\"\\\"\") && value.endsWith(\"\\\"\")) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (key) {\n entries[key] = value;\n }\n }\n return entries;\n } catch {\n return {};\n }\n}\n\nfunction printHelp() {\n console.log(`\npriceos generate-types\n\nGenerates TypeScript feature access types for your PriceOS workspace.\n\nOptions:\n --api-key <key> PriceOS API key (defaults to .env.local, .env, or env PRICEOS_API_KEY) [required]\n --out <path> Output .d.ts file (default: priceos.d.ts in current directory)\n --out-dir <path> Output directory for priceos.d.ts (ignored if --out is set)\n -h, --help Show help\n\nExamples:\n priceos generate-types --api-key sk_test_... --out ./priceos.d.ts\n priceos generate-types --api-key sk_test_... --out-dir ./src\n`.trim());\n}\n\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.length === 0 || hasFlag(args, \"--help\") || hasFlag(args, \"-h\")) {\n printHelp();\n process.exit(args.length === 0 ? 1 : 0);\n }\n\n const cmd = args[0];\n if (cmd !== \"generate-types\") {\n console.error(`Unknown command: ${cmd}`);\n printHelp();\n process.exit(1);\n }\n\n const envLocal = await readEnvFile(path.resolve(process.cwd(), \".env.local\"));\n const envDefault = await readEnvFile(path.resolve(process.cwd(), \".env\"));\n const apiKey =\n argValue(args, \"--api-key\") ??\n envLocal.PRICEOS_API_KEY ??\n envDefault.PRICEOS_API_KEY ??\n process.env.PRICEOS_API_KEY;\n\n if (!apiKey) {\n console.error(\"Missing API key. Provide --api-key <key> or set PRICEOS_API_KEY in .env.local/.env.\");\n process.exit(1);\n }\n\n const outRel = argValue(args, \"--out\");\n const outDir = argValue(args, \"--out-dir\");\n const outFile = outRel ?? \"priceos.d.ts\";\n const outPath = outDir && !outRel\n ? path.resolve(process.cwd(), outDir, outFile)\n : path.resolve(process.cwd(), outFile);\n const outDisplay = outDir && !outRel ? path.join(outDir, outFile) : outFile;\n\n const url = \"https://api.priceos.com/v1/features\";\n const res = await fetch(url, {\n headers: { \"x-api-key\": apiKey },\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n console.error(`Failed to fetch features: ${res.status} ${res.statusText}\\n${text}`);\n process.exit(1);\n }\n\n const features = (await res.json()) as Feature[];\n const typeByKey = new Map<string, \"boolean\" | \"limit\" | \"unknown\">();\n const trackingByKey = new Map<string, \"tracked\" | \"untracked\" | \"unknown\">();\n\n for (const feature of features ?? []) {\n if (!feature?.featureKey) continue;\n const key = feature.featureKey;\n const nextType = feature.type === \"boolean\" || feature.type === \"limit\" ? feature.type : \"unknown\";\n const currentType = typeByKey.get(key);\n if (!currentType) {\n typeByKey.set(key, nextType);\n } else if (currentType !== nextType) {\n typeByKey.set(key, \"unknown\");\n }\n\n if (nextType !== \"limit\") continue;\n\n const nextTracking =\n feature.tracksUsage === true\n ? \"tracked\"\n : feature.tracksUsage === false\n ? \"untracked\"\n : \"unknown\";\n const currentTracking = trackingByKey.get(key);\n if (!currentTracking) {\n trackingByKey.set(key, nextTracking);\n continue;\n }\n if (currentTracking !== nextTracking) {\n trackingByKey.set(key, \"unknown\");\n }\n }\n\n const keys = [...typeByKey.keys()].sort();\n const union = keys.length ? keys.map((k) => JSON.stringify(k)).join(\" | \") : \"never\";\n const limitKeys = keys.filter((key) => typeByKey.get(key) === \"limit\");\n const limitUnion = limitKeys.length ? limitKeys.map((k) => JSON.stringify(k)).join(\" | \") : \"never\";\n const mapLines = keys.map((key) => {\n const featureType = typeByKey.get(key);\n const accessType =\n featureType === \"boolean\"\n ? \"BooleanFeatureAccess\"\n : featureType === \"limit\"\n ? trackingByKey.get(key) === \"tracked\"\n ? \"TrackedLimitFeatureAccess\"\n : trackingByKey.get(key) === \"untracked\"\n ? \"UntrackedLimitFeatureAccess\"\n : \"LimitFeatureAccess\"\n : \"FeatureAccessEntry\";\n return ` ${JSON.stringify(key)}: ${accessType};`;\n });\n\n const content = `// Auto-generated by PriceOS (priceos generate-types). Do not edit.\nexport type FeatureKey = ${union};\nexport type LimitFeatureKey = ${limitUnion};\nexport type BooleanFeatureAccess = {\n type: \"boolean\";\n hasAccess: boolean;\n};\nexport type LimitFeatureUsage = {\n used: number;\n remaining: number | null;\n bonusRemaining: number;\n hasReachedLimit: boolean;\n bonusUsed: number;\n nextReset: number | null;\n lastReset: number | null;\n};\nexport type TrackedLimitFeatureAccess = {\n type: \"limit\";\n hasAccess: boolean;\n isUnlimited: boolean;\n limit: number | null;\n usage: LimitFeatureUsage;\n};\nexport type UntrackedLimitFeatureAccess = {\n type: \"limit\";\n hasAccess: boolean;\n isUnlimited: boolean;\n limit: number | null;\n};\nexport type LimitFeatureAccess = TrackedLimitFeatureAccess | UntrackedLimitFeatureAccess;\nexport type FeatureAccessEntry = BooleanFeatureAccess | LimitFeatureAccess;\nexport type MyFeatures = {\n${mapLines.join(\"\\n\")}\n};\n`;\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, content, \"utf8\");\n\n console.log(`Generated ${outDisplay} (${keys.length} feature keys)`);\n}\n\nmain().catch((e) => {\n console.error(e);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CreateBonusBody, CreateBonusResponse, CreateCustomerRequest, CreateCustomerResponse, DeleteBonusResponse, ListBonusesRequest, ListBonusesResponse, DeleteUsageEventsBody, DeleteUsageEventsResponse, DeleteUsageEventResponse, DeleteCustomerResponse, GetUsageEventResponse, GetUsageEventByKeyResponse, GetCustomerResponse, GetFeatureAccessResponse, LinkCustomerBody, LinkCustomerResponse, LimitFeatureKeyFromAccessMap, TrackedLimitFeatureKeyFromAccessMap, ListUsageEventsBody, ListUsageEventsResponse, SetUsageBody, SetUsageResponse, UpdateUsageEventRequest, UpdateUsageEventResponse, VoidUsageEventRequest, VoidUsageEventResponse, UpdateBonusRequest, UpdateBonusResponse, TrackUsageBody, TrackUsageBatchBody, TrackUsageBatchResponse, TrackUsageResponse, UpdateCustomerBody, UpdateCustomerResponse } from "./types";
1
+ import { CreateBonusBody, CreateBonusResponse, CreateCustomerRequest, CreateCustomerResponse, DeleteBonusResponse, ListBonusesRequest, ListBonusesResponse, DeleteUsageEventsBody, DeleteUsageEventsResponse, DeleteUsageEventResponse, DeleteCustomerResponse, GetUsageEventResponse, GetUsageEventByKeyResponse, GetCustomerResponse, GetFeatureAccessResponse, LinkCustomerBody, LinkCustomerResponse, LimitFeatureKeyFromAccessMap, TrackedLimitFeatureKeyFromAccessMap, ListUsageEventsBody, ListUsageEventsResponse, SetUsageBody, SetUsageResponse, UpdateUsageEventRequest, UpdateUsageEventResponse, VoidUsageEventRequest, VoidUsageEventResponse, UpdateBonusRequest, UpdateBonusResponse, TrackUsageBody, TrackUsageBatchBody, TrackUsageBatchResponse, TrackUsageResponse, UpdateCustomerBody, UpdateCustomerResponse, GetPricingTableRequest, GetPricingTableResponse, CreateCheckoutRequest, CreateCheckoutResponse } from "./types";
2
2
  export type PriceOSLogLevel = "none" | "error" | "warning" | "info" | "debug";
3
3
  export type PriceOSClientOptions = {
4
4
  logLevel?: PriceOSLogLevel;
@@ -10,8 +10,17 @@ export type PriceOSCustomersClient<TFeatureAccessMap = GetFeatureAccessResponse>
10
10
  update(input: UpdateCustomerBody): Promise<UpdateCustomerResponse<TFeatureAccessMap>>;
11
11
  delete(customerId: string): Promise<DeleteCustomerResponse>;
12
12
  };
13
+ type FeatureAccessRecord<TFeatureAccessMap> = TFeatureAccessMap extends Record<string, unknown> ? TFeatureAccessMap : Record<string, never>;
14
+ type FeatureAccessKey<TFeatureAccessMap> = keyof FeatureAccessRecord<TFeatureAccessMap> & string;
13
15
  export type PriceOSFeaturesClient<TFeatureAccessMap = GetFeatureAccessResponse> = {
14
16
  getAccess(customerId: string): Promise<TFeatureAccessMap>;
17
+ getAccess<TFeatureKey extends FeatureAccessKey<TFeatureAccessMap>>(customerId: string, featureKey: TFeatureKey): Promise<FeatureAccessRecord<TFeatureAccessMap>[TFeatureKey]>;
18
+ };
19
+ export type PriceOSPricingClient = {
20
+ getTable(input?: GetPricingTableRequest): Promise<GetPricingTableResponse>;
21
+ };
22
+ export type PriceOSCheckoutClient = {
23
+ create(input: CreateCheckoutRequest): Promise<CreateCheckoutResponse>;
15
24
  };
16
25
  export type PriceOSBonusesClient<TFeatureAccessMap = GetFeatureAccessResponse> = {
17
26
  create(input: CreateBonusBody<TrackedLimitFeatureKeyFromAccessMap<TFeatureAccessMap>>): Promise<CreateBonusResponse>;
@@ -34,6 +43,8 @@ export type PriceOSUsageClient<TFeatureAccessMap = GetFeatureAccessResponse> = {
34
43
  export type PriceOSHttpClient<TFeatureAccessMap = GetFeatureAccessResponse> = {
35
44
  customers: PriceOSCustomersClient<TFeatureAccessMap>;
36
45
  features: PriceOSFeaturesClient<TFeatureAccessMap>;
46
+ pricing: PriceOSPricingClient;
47
+ checkout: PriceOSCheckoutClient;
37
48
  bonuses: PriceOSBonusesClient<TFeatureAccessMap>;
38
49
  usage: PriceOSUsageClient<TFeatureAccessMap>;
39
50
  };
@@ -51,7 +62,10 @@ export declare class PriceOS<TFeatureAccessMap = GetFeatureAccessResponse> imple
51
62
  private log;
52
63
  customers: PriceOSCustomersClient<TFeatureAccessMap>;
53
64
  features: PriceOSFeaturesClient<TFeatureAccessMap>;
65
+ pricing: PriceOSPricingClient;
66
+ checkout: PriceOSCheckoutClient;
54
67
  bonuses: PriceOSBonusesClient<TFeatureAccessMap>;
55
68
  usage: PriceOSUsageClient<TFeatureAccessMap>;
56
69
  constructor(apiKey: string, opts?: PriceOSClientOptions);
57
70
  }
71
+ export {};