@hasna/economy 0.2.43 → 0.3.1
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/dashboard/README.md +73 -0
- package/dist/cli/commands/brief.d.ts +4 -69
- package/dist/cli/commands/brief.d.ts.map +1 -1
- package/dist/cli/commands/extras.d.ts.map +1 -1
- package/dist/cli/commands/tui.d.ts +21 -5
- package/dist/cli/commands/tui.d.ts.map +1 -1
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/index.js +8227 -6395
- package/dist/db/database.d.ts +18 -0
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/pg-migrations.d.ts.map +1 -1
- package/dist/index.d.ts +1 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1855 -1613
- package/dist/lib/analytics.d.ts +68 -0
- package/dist/lib/analytics.d.ts.map +1 -0
- package/dist/lib/brief.d.ts +72 -0
- package/dist/lib/brief.d.ts.map +1 -0
- package/dist/lib/cloud-storage.d.ts +48 -0
- package/dist/lib/cloud-storage.d.ts.map +1 -0
- package/dist/lib/contracts-client/index.d.ts +3 -0
- package/dist/lib/contracts-client/index.d.ts.map +1 -0
- package/dist/lib/contracts-client/mode.d.ts +20 -0
- package/dist/lib/contracts-client/mode.d.ts.map +1 -0
- package/dist/lib/contracts-client/storage.d.ts +83 -0
- package/dist/lib/contracts-client/storage.d.ts.map +1 -0
- package/dist/lib/contracts-client/transport.d.ts +148 -0
- package/dist/lib/contracts-client/transport.d.ts.map +1 -0
- package/dist/lib/pricing.d.ts +3 -0
- package/dist/lib/pricing.d.ts.map +1 -1
- package/dist/lib/store/index.d.ts +283 -0
- package/dist/lib/store/index.d.ts.map +1 -0
- package/dist/lib/sync-all.d.ts +0 -2
- package/dist/lib/sync-all.d.ts.map +1 -1
- package/dist/mcp/http.d.ts.map +1 -1
- package/dist/mcp/index.js +1934 -536
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/otel/index.js +21 -267
- package/dist/server/index.js +2794 -331
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +4 -2
- package/dashboard/dist/assets/charts-BtCbslx4.js +0 -36
- package/dashboard/dist/assets/index-BDmtt3RI.css +0 -1
- package/dashboard/dist/assets/index-BFwRLqg7.js +0 -6
- package/dashboard/dist/assets/vendor-Cz8jb743.js +0 -53
- package/dashboard/dist/index.html +0 -16
- package/dashboard/dist/logo.jpg +0 -0
- package/dashboard/dist/vite.svg +0 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { SqliteAdapter as Database } from '@hasna/cloud';
|
|
2
|
+
export interface ProjectDetailModel {
|
|
3
|
+
model: string;
|
|
4
|
+
requests: number;
|
|
5
|
+
cost_usd: number;
|
|
6
|
+
}
|
|
7
|
+
export interface ProjectDetailSession {
|
|
8
|
+
id: string;
|
|
9
|
+
total_cost_usd: number;
|
|
10
|
+
started_at: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ProjectDetail {
|
|
13
|
+
project_name: string;
|
|
14
|
+
project_path: string;
|
|
15
|
+
total_cost_usd: number;
|
|
16
|
+
total_tokens: number;
|
|
17
|
+
sessions: number;
|
|
18
|
+
daily: Array<{
|
|
19
|
+
date: string;
|
|
20
|
+
cost_usd: number;
|
|
21
|
+
}>;
|
|
22
|
+
models: ProjectDetailModel[];
|
|
23
|
+
top_sessions: ProjectDetailSession[];
|
|
24
|
+
}
|
|
25
|
+
/** Detailed breakdown for a single project matched by name or path substring. */
|
|
26
|
+
export declare function queryProjectDetail(db: Database, nameOrPath: string): ProjectDetail | null;
|
|
27
|
+
export type ExportType = 'sessions' | 'requests';
|
|
28
|
+
/** Raw rows for a CSV export. CSV formatting stays in the caller. */
|
|
29
|
+
export declare function queryExportRows(db: Database, type: ExportType, period: string): Array<Record<string, unknown>>;
|
|
30
|
+
export interface RangeStats {
|
|
31
|
+
cost: number;
|
|
32
|
+
requests: number;
|
|
33
|
+
tokens: number;
|
|
34
|
+
sessions: number;
|
|
35
|
+
}
|
|
36
|
+
/** Cost/request/token/session totals for an inclusive [from,to] date range. */
|
|
37
|
+
export declare function queryRangeStats(db: Database, from: string, to: string): RangeStats;
|
|
38
|
+
export interface ForecastData {
|
|
39
|
+
day_of_month: number;
|
|
40
|
+
days_in_month: number;
|
|
41
|
+
spent_so_far_usd: number;
|
|
42
|
+
daily_avg_usd: number;
|
|
43
|
+
projected_usd: number;
|
|
44
|
+
last7_daily_avg_usd: number;
|
|
45
|
+
last7_projected_usd: number;
|
|
46
|
+
cheapest_day: {
|
|
47
|
+
date: string;
|
|
48
|
+
cost_usd: number;
|
|
49
|
+
} | null;
|
|
50
|
+
most_expensive_day: {
|
|
51
|
+
date: string;
|
|
52
|
+
cost_usd: number;
|
|
53
|
+
} | null;
|
|
54
|
+
}
|
|
55
|
+
/** End-of-month projection based on current burn rate. */
|
|
56
|
+
export declare function queryForecast(db: Database, now?: Date): ForecastData;
|
|
57
|
+
export interface ModelEfficiency {
|
|
58
|
+
model: string;
|
|
59
|
+
input: number;
|
|
60
|
+
output: number;
|
|
61
|
+
cache_read: number;
|
|
62
|
+
cache_write: number;
|
|
63
|
+
requests: number;
|
|
64
|
+
cost: number;
|
|
65
|
+
}
|
|
66
|
+
/** Per-model token efficiency (output/input ratio, cache hit %, cost/1k out). */
|
|
67
|
+
export declare function queryModelEfficiency(db: Database): ModelEfficiency[];
|
|
68
|
+
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/lib/analytics.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,cAAc,CAAA;AAI7D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAChD,MAAM,EAAE,kBAAkB,EAAE,CAAA;IAC5B,YAAY,EAAE,oBAAoB,EAAE,CAAA;CACrC;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAmDzF;AAID,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,CAAA;AAWhD,qEAAqE;AACrE,wBAAgB,eAAe,CAC7B,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,GACb,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAOhC;AAID,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,CAUlF;AAID,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACvD,kBAAkB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAC9D;AAED,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,GAAE,IAAiB,GAAG,YAAY,CAkChF;AAID,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,iFAAiF;AACjF,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,GAAG,eAAe,EAAE,CAWpE"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { SqliteAdapter as Database } from '@hasna/cloud';
|
|
2
|
+
type BriefPeriod = 'today' | 'week';
|
|
3
|
+
export interface BriefTotals {
|
|
4
|
+
sessions: number;
|
|
5
|
+
requests: number;
|
|
6
|
+
input_tokens: number;
|
|
7
|
+
output_tokens: number;
|
|
8
|
+
cache_read_tokens: number;
|
|
9
|
+
cache_create_tokens: number;
|
|
10
|
+
cache_create_5m_tokens: number;
|
|
11
|
+
cache_create_1h_tokens: number;
|
|
12
|
+
total_tokens: number;
|
|
13
|
+
cost_usd: number;
|
|
14
|
+
last_active: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface BriefPeriodSummary extends BriefTotals {
|
|
17
|
+
label: string;
|
|
18
|
+
period: BriefPeriod | 'since';
|
|
19
|
+
since?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface BriefMachineRow extends BriefTotals {
|
|
22
|
+
machine_id: string;
|
|
23
|
+
last_data_at: string | null;
|
|
24
|
+
last_data_age: string;
|
|
25
|
+
}
|
|
26
|
+
export interface BriefAgentRow extends BriefTotals {
|
|
27
|
+
agent: string;
|
|
28
|
+
}
|
|
29
|
+
export interface BriefAccountRow extends BriefTotals {
|
|
30
|
+
account_key: string;
|
|
31
|
+
account_tool: string;
|
|
32
|
+
account_name: string;
|
|
33
|
+
account_email: string | null;
|
|
34
|
+
account_source: string;
|
|
35
|
+
}
|
|
36
|
+
export interface BriefFreshnessMachine {
|
|
37
|
+
machine_id: string;
|
|
38
|
+
max_request_at: string | null;
|
|
39
|
+
request_age: string;
|
|
40
|
+
last_merge_sync_at: string | null;
|
|
41
|
+
merge_sync_age: string;
|
|
42
|
+
}
|
|
43
|
+
export interface EconomyBrief {
|
|
44
|
+
generated_at: string;
|
|
45
|
+
machine: string;
|
|
46
|
+
since: {
|
|
47
|
+
input: string;
|
|
48
|
+
timestamp: string;
|
|
49
|
+
label: string;
|
|
50
|
+
};
|
|
51
|
+
summaries: BriefPeriodSummary[];
|
|
52
|
+
machines: BriefMachineRow[];
|
|
53
|
+
agents: BriefAgentRow[];
|
|
54
|
+
accounts: BriefAccountRow[];
|
|
55
|
+
freshness: {
|
|
56
|
+
machines: BriefFreshnessMachine[];
|
|
57
|
+
max_request_line: string;
|
|
58
|
+
merge_sync_line: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export interface BriefOptions {
|
|
62
|
+
since?: string;
|
|
63
|
+
machine?: string;
|
|
64
|
+
now?: Date;
|
|
65
|
+
currentMachineId?: string;
|
|
66
|
+
localSyncAt?: Date;
|
|
67
|
+
}
|
|
68
|
+
/** Human-readable age of a timestamp relative to now (never/<1m/Nm/Nh/Nd). */
|
|
69
|
+
export declare function formatAge(timestamp: string | null | undefined, now: Date): string;
|
|
70
|
+
export declare function buildBrief(db: Database, opts?: BriefOptions): EconomyBrief;
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=brief.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brief.d.ts","sourceRoot":"","sources":["../../src/lib/brief.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,cAAc,CAAA;AAU7D,KAAK,WAAW,GAAG,OAAO,GAAG,MAAM,CAAA;AAEnC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,sBAAsB,EAAE,MAAM,CAAA;IAC9B,sBAAsB,EAAE,MAAM,CAAA;IAC9B,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,WAAW,GAAG,OAAO,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,SAAS,EAAE,kBAAkB,EAAE,CAAA;IAC/B,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,SAAS,EAAE;QACT,QAAQ,EAAE,qBAAqB,EAAE,CAAA;QACjC,gBAAgB,EAAE,MAAM,CAAA;QACxB,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;CACF;AAcD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,IAAI,CAAA;CACnB;AAyBD,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,CAWjF;AAsmBD,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAE,YAAiB,GAAG,YAAY,CAmD9E"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { resolveStorageClient, type HasnaStorageClient } from "./contracts-client/storage.js";
|
|
2
|
+
/** Transport overrides (test injection: fetchImpl, headers, timeout, retry). */
|
|
3
|
+
type StorageClientOverrides = Parameters<typeof resolveStorageClient>[2];
|
|
4
|
+
/** The economy app slug used for the HASNA_<APP>_* env lookups. */
|
|
5
|
+
export declare const ECONOMY_APP = "economy";
|
|
6
|
+
export type EconomyCloudStorage = {
|
|
7
|
+
/** True when reads/writes must go to the cloud HTTP API. */
|
|
8
|
+
readonly active: true;
|
|
9
|
+
/** The ready HTTP storage client. */
|
|
10
|
+
readonly client: HasnaStorageClient;
|
|
11
|
+
} | {
|
|
12
|
+
readonly active: false;
|
|
13
|
+
readonly client: null;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the economy client storage transport for the current environment.
|
|
17
|
+
*
|
|
18
|
+
* Returns `{ active: true, client }` only when mode=self_hosted/cloud AND
|
|
19
|
+
* HASNA_ECONOMY_API_URL + HASNA_ECONOMY_API_KEY are set. Otherwise
|
|
20
|
+
* `{ active: false }` (local store). Throws if cloud was requested but is
|
|
21
|
+
* misconfigured.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveEconomyCloudStorage(env?: NodeJS.ProcessEnv, overrides?: StorageClientOverrides): EconomyCloudStorage;
|
|
24
|
+
/** Memoized {@link resolveEconomyCloudStorage} for the process lifetime. */
|
|
25
|
+
export declare function economyCloudStorage(env?: NodeJS.ProcessEnv): EconomyCloudStorage;
|
|
26
|
+
/** Test-only: drop the memoized resolution so a new env can be resolved. */
|
|
27
|
+
export declare function resetEconomyCloudStorageCache(): void;
|
|
28
|
+
/** Active cloud storage (narrowed so `client` is non-null). */
|
|
29
|
+
export type ActiveEconomyCloudStorage = Extract<EconomyCloudStorage, {
|
|
30
|
+
active: true;
|
|
31
|
+
}>;
|
|
32
|
+
/** Query params accepted by the read helpers below. */
|
|
33
|
+
export type CloudQuery = Record<string, string | number | boolean | null | undefined>;
|
|
34
|
+
/**
|
|
35
|
+
* Read a collection resource from the cloud API and return the extracted array
|
|
36
|
+
* (the serve envelope's `data`/`items`). Used by the read commands (sessions,
|
|
37
|
+
* top, breakdown, accounts) so they render cloud data — never the local store —
|
|
38
|
+
* when the client is in self_hosted/cloud mode.
|
|
39
|
+
*/
|
|
40
|
+
export declare function cloudListItems<T = unknown>(storage: ActiveEconomyCloudStorage, resource: string, query?: CloudQuery): Promise<T[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Read a single (non-collection) resource and return the unwrapped `data`
|
|
43
|
+
* payload (e.g. `/usage` -> `{ snapshots, summary }`). Falls back to the raw
|
|
44
|
+
* body if the server does not use the `{ data }` envelope.
|
|
45
|
+
*/
|
|
46
|
+
export declare function cloudObject<T = unknown>(storage: ActiveEconomyCloudStorage, path: string, query?: CloudQuery): Promise<T>;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=cloud-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-storage.d.ts","sourceRoot":"","sources":["../../src/lib/cloud-storage.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,oBAAoB,EAAE,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAE9F,gFAAgF;AAChF,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzE,mEAAmE;AACnE,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,MAAM,MAAM,mBAAmB,GAC3B;IACE,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;CACrC,GACD;IACE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;CACvB,CAAC;AAIN;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,SAAS,CAAC,EAAE,sBAAsB,GACjC,mBAAmB,CAKrB;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,mBAAmB,CAG7F;AAED,4EAA4E;AAC5E,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD;AAED,+DAA+D;AAC/D,MAAM,MAAM,yBAAyB,GAAG,OAAO,CAAC,mBAAmB,EAAE;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC;AAEvF,uDAAuD;AACvD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAYtF;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,CAAC,GAAG,OAAO,EAC9C,OAAO,EAAE,yBAAyB,EAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,UAAU,GACjB,OAAO,CAAC,CAAC,EAAE,CAAC,CAId;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3C,OAAO,EAAE,yBAAyB,EAClC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,UAAU,GACjB,OAAO,CAAC,CAAC,CAAC,CAOZ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/contracts-client/index.ts"],"names":[],"mappings":"AAGA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Environment map (subset of NodeJS.ProcessEnv). */
|
|
2
|
+
export type Env = Record<string, string | undefined>;
|
|
3
|
+
/** Runtime storage enum. `local | cloud` ONLY (Amendment A1: PURE REMOTE). */
|
|
4
|
+
export type StorageMode = "local" | "cloud";
|
|
5
|
+
/** Deprecated storage-mode aliases accepted at parse time and mapped to cloud. */
|
|
6
|
+
export declare const DEPRECATED_STORAGE_MODE_ALIASES: readonly ["remote", "hybrid", "self_hosted"];
|
|
7
|
+
export interface StorageModeNormalization {
|
|
8
|
+
mode: StorageMode;
|
|
9
|
+
/** The deprecated alias that was normalized to `cloud`, if any. */
|
|
10
|
+
deprecatedAlias: string | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Normalize a raw storage-mode string to the `local | cloud` runtime enum.
|
|
14
|
+
* Accepts deprecated aliases (`remote`, `hybrid`, `self_hosted`) and maps them
|
|
15
|
+
* to `cloud`. Throws on any other value.
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeStorageMode(value: string): StorageModeNormalization;
|
|
18
|
+
/** Upper-snake env token for an app name, e.g. `economy` -> `ECONOMY`. */
|
|
19
|
+
export declare function envToken(name: string): string;
|
|
20
|
+
//# sourceMappingURL=mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode.d.ts","sourceRoot":"","sources":["../../../src/lib/contracts-client/mode.ts"],"names":[],"mappings":"AAaA,qDAAqD;AACrD,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAErD,8EAA8E;AAC9E,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5C,kFAAkF;AAClF,eAAO,MAAM,+BAA+B,8CAA+C,CAAC;AAE5F,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,WAAW,CAAC;IAClB,mEAAmE;IACnE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,wBAAwB,CAQ5E;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Env } from "./mode.js";
|
|
2
|
+
import { createClientTransport, type HasnaHttpTransport, type HasnaRequestOptions, type QueryParams } from "./transport.js";
|
|
3
|
+
/** Options for a list() call: filters/pagination as query params. */
|
|
4
|
+
export interface StorageListOptions extends Pick<HasnaRequestOptions, "timeoutMs" | "headers" | "retry" | "signal"> {
|
|
5
|
+
/** Query params (limit, offset, cursor, filters, ...). */
|
|
6
|
+
query?: QueryParams;
|
|
7
|
+
}
|
|
8
|
+
/** Options for a get() call. */
|
|
9
|
+
export type StorageGetOptions = Pick<HasnaRequestOptions, "timeoutMs" | "headers" | "retry" | "signal" | "query">;
|
|
10
|
+
/** Options for a create() call. */
|
|
11
|
+
export interface StorageCreateOptions extends Pick<HasnaRequestOptions, "timeoutMs" | "headers" | "retry" | "signal" | "query"> {
|
|
12
|
+
/**
|
|
13
|
+
* Idempotency key for the create. Defaults to a fresh UUID so a transparently
|
|
14
|
+
* retried POST is deduped by the server instead of creating a duplicate. Pass
|
|
15
|
+
* a stable value to make an app-level operation idempotent across calls.
|
|
16
|
+
*/
|
|
17
|
+
idempotencyKey?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Options for an update() call. */
|
|
20
|
+
export interface StorageUpdateOptions extends Pick<HasnaRequestOptions, "timeoutMs" | "headers" | "retry" | "signal" | "query"> {
|
|
21
|
+
/** HTTP verb for the update. Default `PATCH` (partial); use `PUT` for replace. */
|
|
22
|
+
method?: "PATCH" | "PUT";
|
|
23
|
+
/** Idempotency key. PUT is idempotent by definition; set this to make PATCH retry-safe too. */
|
|
24
|
+
idempotencyKey?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Options for a delete() call. */
|
|
27
|
+
export type StorageDeleteOptions = Pick<HasnaRequestOptions, "timeoutMs" | "headers" | "retry" | "signal" | "query">;
|
|
28
|
+
/** Result of a list() call. `items` is the extracted array; `raw` is the full envelope. */
|
|
29
|
+
export interface StorageListResult<T> {
|
|
30
|
+
items: T[];
|
|
31
|
+
/** Total count when the server reports one (`total`/`count`), else null. */
|
|
32
|
+
total: number | null;
|
|
33
|
+
/** Opaque pagination cursor when the server reports one, else null. */
|
|
34
|
+
cursor: string | null;
|
|
35
|
+
/** The full parsed response body (envelope preserved). */
|
|
36
|
+
raw: unknown;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The app storage interface, HTTP edition. This is deliberately the same small
|
|
40
|
+
* CRUD surface a local store exposes, so an app's resolver can return either a
|
|
41
|
+
* local implementation or this one behind one interface.
|
|
42
|
+
*/
|
|
43
|
+
export interface HasnaStorageClient {
|
|
44
|
+
/** App slug this client targets. */
|
|
45
|
+
readonly name: string;
|
|
46
|
+
/** `<origin>/v1` base URL. */
|
|
47
|
+
readonly baseUrl: string;
|
|
48
|
+
/** The underlying HTTP transport (escape hatch for non-CRUD routes). */
|
|
49
|
+
readonly transport: HasnaHttpTransport;
|
|
50
|
+
/** List a collection. Returns extracted `items` plus the raw envelope. */
|
|
51
|
+
list<T = unknown>(resource: string, options?: StorageListOptions): Promise<StorageListResult<T>>;
|
|
52
|
+
/** Fetch one entity by id. Returns `null` on 404. */
|
|
53
|
+
get<T = unknown>(resource: string, id: string, options?: StorageGetOptions): Promise<T | null>;
|
|
54
|
+
/** Create one entity. Retry-safe via an auto `Idempotency-Key`. */
|
|
55
|
+
create<T = unknown>(resource: string, body: unknown, options?: StorageCreateOptions): Promise<T>;
|
|
56
|
+
/** Update one entity by id (PATCH by default). */
|
|
57
|
+
update<T = unknown>(resource: string, id: string, patch: unknown, options?: StorageUpdateOptions): Promise<T>;
|
|
58
|
+
/** Delete one entity by id. Resolves for 2xx and 404 (already gone). */
|
|
59
|
+
delete(resource: string, id: string, options?: StorageDeleteOptions): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Wrap an HTTP transport with the resource CRUD storage interface. Use this when
|
|
63
|
+
* you already have a transport (e.g. from `createClientTransport`).
|
|
64
|
+
*/
|
|
65
|
+
export declare function createHasnaStorageClient(name: string, transport: HasnaHttpTransport): HasnaStorageClient;
|
|
66
|
+
/** Result of {@link resolveStorageClient}. */
|
|
67
|
+
export type ResolveStorageClientResult = {
|
|
68
|
+
transport: "local";
|
|
69
|
+
client: null;
|
|
70
|
+
} | {
|
|
71
|
+
transport: "cloud-http";
|
|
72
|
+
client: HasnaStorageClient;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* The one call an app's storage resolver makes. Reads the client-flip env for
|
|
76
|
+
* `name`; when it resolves to `cloud-http` (mode=cloud/self_hosted + API_URL +
|
|
77
|
+
* API_KEY), returns a ready {@link HasnaStorageClient}. Otherwise returns
|
|
78
|
+
* `{ transport: 'local', client: null }` so the app uses its local store.
|
|
79
|
+
* Throws if cloud was requested but is misconfigured (so callers never silently
|
|
80
|
+
* read the wrong dataset).
|
|
81
|
+
*/
|
|
82
|
+
export declare function resolveStorageClient(name: string, env?: Env, overrides?: Parameters<typeof createClientTransport>[2]): ResolveStorageClientResult;
|
|
83
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/lib/contracts-client/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { type Env, type StorageMode } from "./mode.js";
|
|
2
|
+
/** Default cloud host template. `<app>` is the app slug. */
|
|
3
|
+
export declare function defaultCloudBaseUrl(name: string): string;
|
|
4
|
+
export interface ClientTransportEnvKeys {
|
|
5
|
+
/** Mode keys, in precedence order. */
|
|
6
|
+
modeKeys: string[];
|
|
7
|
+
/** API base-URL keys, in precedence order. */
|
|
8
|
+
apiUrlKeys: string[];
|
|
9
|
+
/** API-key keys, in precedence order. */
|
|
10
|
+
apiKeyKeys: string[];
|
|
11
|
+
}
|
|
12
|
+
/** Resolve the canonical client-flip env-key spec for an app. */
|
|
13
|
+
export declare function clientTransportEnvKeys(name: string): ClientTransportEnvKeys;
|
|
14
|
+
/** Normalize a base URL to `<origin>/v1` (dropping any trailing slash or existing /v1). */
|
|
15
|
+
export declare function toV1BaseUrl(apiUrl: string): string;
|
|
16
|
+
export type ClientTransportKind = "local" | "cloud-http";
|
|
17
|
+
export interface ClientTransportResolution {
|
|
18
|
+
/** Where the client should read/write from. */
|
|
19
|
+
transport: ClientTransportKind;
|
|
20
|
+
/** Resolved storage mode (`local` | `cloud`). */
|
|
21
|
+
mode: StorageMode;
|
|
22
|
+
/** Deprecated mode alias that was normalized (e.g. `self_hosted`), if any. */
|
|
23
|
+
deprecatedAlias: string | null;
|
|
24
|
+
/** Env key the mode was read from, or `"default"`. */
|
|
25
|
+
modeSource: string;
|
|
26
|
+
/** `<origin>/v1` base for the cloud API when transport is cloud-http, else null. */
|
|
27
|
+
baseUrl: string | null;
|
|
28
|
+
/** Env key the API URL came from, `"default"` (host template), or null. */
|
|
29
|
+
apiUrlSource: string | null;
|
|
30
|
+
/** Whether an API key is present (value never exposed). */
|
|
31
|
+
apiKeyPresent: boolean;
|
|
32
|
+
/** Env key the API key came from, or null. */
|
|
33
|
+
apiKeySource: string | null;
|
|
34
|
+
/**
|
|
35
|
+
* True when the operator asked for cloud but the config is incomplete (no API
|
|
36
|
+
* key), so we fell back to local. Callers SHOULD treat this as an error rather
|
|
37
|
+
* than silently reading local data.
|
|
38
|
+
*/
|
|
39
|
+
misconfigured: boolean;
|
|
40
|
+
/** Human-readable warning, or null. Never contains secret values. */
|
|
41
|
+
warning: string | null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve how a client should reach an app's data given the environment.
|
|
45
|
+
*
|
|
46
|
+
* Precedence for the mode: the first present of `HASNA_<NAME>_STORAGE_MODE`,
|
|
47
|
+
* `HASNA_<NAME>_MODE`, `<NAME>_STORAGE_MODE`, `<NAME>_MODE`, else `local`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveClientTransport(name: string, env?: Env): ClientTransportResolution;
|
|
50
|
+
/** Thrown when a cloud HTTP request returns a non-2xx status. */
|
|
51
|
+
export declare class HasnaHttpError extends Error {
|
|
52
|
+
readonly status: number;
|
|
53
|
+
readonly method: string;
|
|
54
|
+
readonly path: string;
|
|
55
|
+
readonly body: unknown;
|
|
56
|
+
constructor(method: string, path: string, status: number, body: unknown);
|
|
57
|
+
}
|
|
58
|
+
type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
59
|
+
/** Query params for a request. Nullish values are dropped; arrays repeat the key. */
|
|
60
|
+
export type QueryParams = URLSearchParams | Record<string, string | number | boolean | null | undefined | ReadonlyArray<string | number | boolean>>;
|
|
61
|
+
/** Retry policy for transient failures (network errors, timeouts, 5xx, 429). */
|
|
62
|
+
export interface HasnaRetryOptions {
|
|
63
|
+
/** Max RETRY attempts after the first try. Default 2 (=> up to 3 total tries). */
|
|
64
|
+
retries?: number;
|
|
65
|
+
/** Base backoff in ms for exponential backoff. Default 200. */
|
|
66
|
+
baseDelayMs?: number;
|
|
67
|
+
/** Backoff ceiling in ms. Default 2000. */
|
|
68
|
+
maxDelayMs?: number;
|
|
69
|
+
/** HTTP statuses that trigger a retry. Default 408, 425, 429, 500, 502, 503, 504. */
|
|
70
|
+
retryStatuses?: number[];
|
|
71
|
+
}
|
|
72
|
+
/** Per-call request options: query, idempotency, timeout, retry, extra headers. */
|
|
73
|
+
export interface HasnaRequestOptions {
|
|
74
|
+
/** Query string params appended to the URL. */
|
|
75
|
+
query?: QueryParams;
|
|
76
|
+
/**
|
|
77
|
+
* Idempotency key sent as `Idempotency-Key`. When set, unsafe methods (POST)
|
|
78
|
+
* become safe to retry: the server dedupes replays. Auto-generated for
|
|
79
|
+
* `create()` in the storage client.
|
|
80
|
+
*/
|
|
81
|
+
idempotencyKey?: string;
|
|
82
|
+
/** Override the transport timeout for this call (ms). */
|
|
83
|
+
timeoutMs?: number;
|
|
84
|
+
/** Extra headers merged into this call (override transport headers). */
|
|
85
|
+
headers?: Record<string, string>;
|
|
86
|
+
/** Override or disable retry for this call. `false` disables retries. */
|
|
87
|
+
retry?: HasnaRetryOptions | false;
|
|
88
|
+
/** Caller abort signal, combined with the internal timeout. */
|
|
89
|
+
signal?: AbortSignal;
|
|
90
|
+
}
|
|
91
|
+
export interface HasnaHttpTransportOptions {
|
|
92
|
+
/** App slug (for error context / default host). */
|
|
93
|
+
name: string;
|
|
94
|
+
/** `<origin>/v1` base. Usually from `resolveClientTransport().baseUrl`. */
|
|
95
|
+
baseUrl: string;
|
|
96
|
+
/** The API key (secret). Sent as both `x-api-key` and `Authorization: Bearer`. */
|
|
97
|
+
apiKey: string;
|
|
98
|
+
/** Override fetch (tests). Defaults to global fetch. */
|
|
99
|
+
fetchImpl?: FetchLike;
|
|
100
|
+
/** Extra headers merged into every request. */
|
|
101
|
+
headers?: Record<string, string>;
|
|
102
|
+
/** Per-request timeout in ms. Default 30000. */
|
|
103
|
+
timeoutMs?: number;
|
|
104
|
+
/** Default retry policy for all requests. Pass `false` to disable. */
|
|
105
|
+
retry?: HasnaRetryOptions | false;
|
|
106
|
+
/** Injectable sleep (tests). Defaults to a real timer. */
|
|
107
|
+
sleepImpl?: (ms: number) => Promise<void>;
|
|
108
|
+
}
|
|
109
|
+
export interface HasnaHttpTransport {
|
|
110
|
+
readonly baseUrl: string;
|
|
111
|
+
request<T = unknown>(method: string, path: string, body?: unknown, opts?: HasnaRequestOptions): Promise<T>;
|
|
112
|
+
get<T = unknown>(path: string, opts?: HasnaRequestOptions): Promise<T>;
|
|
113
|
+
post<T = unknown>(path: string, body?: unknown, opts?: HasnaRequestOptions): Promise<T>;
|
|
114
|
+
put<T = unknown>(path: string, body?: unknown, opts?: HasnaRequestOptions): Promise<T>;
|
|
115
|
+
patch<T = unknown>(path: string, body?: unknown, opts?: HasnaRequestOptions): Promise<T>;
|
|
116
|
+
del<T = unknown>(path: string, body?: unknown, opts?: HasnaRequestOptions): Promise<T>;
|
|
117
|
+
}
|
|
118
|
+
/** Append query params to a `/v1`-relative path (no-op when empty). */
|
|
119
|
+
export declare function appendQuery(path: string, query?: QueryParams): string;
|
|
120
|
+
/**
|
|
121
|
+
* Build an authenticated HTTP transport for an app's cloud `/v1` API. Sends the
|
|
122
|
+
* API key on every request as BOTH `x-api-key` and `Authorization: Bearer`
|
|
123
|
+
* (serve apps accept either), returns parsed JSON, times out, and retries
|
|
124
|
+
* transient failures with exponential backoff + jitter. Never logs the key.
|
|
125
|
+
*
|
|
126
|
+
* Retry safety: idempotent methods (GET/HEAD/PUT/DELETE/OPTIONS) are always
|
|
127
|
+
* retried on transient failure; POST/PATCH are retried ONLY when an
|
|
128
|
+
* `Idempotency-Key` is supplied, so replays can't create duplicates.
|
|
129
|
+
*/
|
|
130
|
+
export declare function createHasnaHttpTransport(options: HasnaHttpTransportOptions): HasnaHttpTransport;
|
|
131
|
+
/**
|
|
132
|
+
* Convenience: resolve transport from env and, when cloud-http, build the HTTP
|
|
133
|
+
* client in one call. Returns `{ transport: 'local', resolution }` for local, or
|
|
134
|
+
* `{ transport: 'cloud-http', client, resolution }` for cloud. Throws if the
|
|
135
|
+
* config is `misconfigured` (cloud requested but unusable) so callers can't drift
|
|
136
|
+
* onto local data by accident.
|
|
137
|
+
*/
|
|
138
|
+
export declare function createClientTransport(name: string, env?: Env, overrides?: Partial<Pick<HasnaHttpTransportOptions, "fetchImpl" | "headers" | "timeoutMs" | "retry" | "sleepImpl">>): {
|
|
139
|
+
transport: "local";
|
|
140
|
+
client: null;
|
|
141
|
+
resolution: ClientTransportResolution;
|
|
142
|
+
} | {
|
|
143
|
+
transport: "cloud-http";
|
|
144
|
+
client: HasnaHttpTransport;
|
|
145
|
+
resolution: ClientTransportResolution;
|
|
146
|
+
};
|
|
147
|
+
export {};
|
|
148
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/lib/contracts-client/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/pricing.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SqliteAdapter as Database } from '@hasna/cloud';
|
|
2
2
|
import type { ModelPricing } from '../types/index.js';
|
|
3
|
+
import { type DbModelPricing } from '../db/database.js';
|
|
3
4
|
export declare const DEFAULT_PRICING: Record<string, ModelPricing>;
|
|
4
5
|
export declare function normalizeModelName(raw: string): string;
|
|
5
6
|
export declare function ensurePricingSeeded(db: Database): void;
|
|
@@ -7,4 +8,6 @@ export declare function getPricingFromDb(db: Database, model: string): ModelPric
|
|
|
7
8
|
export declare function getPricing(model: string): ModelPricing | null;
|
|
8
9
|
export declare function computeCost(model: string, inputTokens: number, outputTokens: number, cacheReadTokens?: number, cacheWriteTokens?: number, cacheWrite1hTokens?: number, cacheStorageTokenHours?: number): number;
|
|
9
10
|
export declare function computeCostFromDb(db: Database, model: string, inputTokens: number, outputTokens: number, cacheReadTokens?: number, cacheWriteTokens?: number, cacheWrite1hTokens?: number, cacheStorageTokenHours?: number): number;
|
|
11
|
+
export declare function getPricingFromRows(rows: DbModelPricing[], model: string): ModelPricing | null;
|
|
12
|
+
export declare function estimateCostFromRows(rows: DbModelPricing[], model: string, inputTokens: number, outputTokens: number, cacheReadTokens?: number, cacheWriteTokens?: number, cacheWrite1hTokens?: number, cacheStorageTokenHours?: number): number;
|
|
10
13
|
//# sourceMappingURL=pricing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/lib/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/lib/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAA6E,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAIlI,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CA+FxD,CAAA;AAqND,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOtD;AA2CD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAMtD;AA+GD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAoBjF;AA4BD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAG7D;AAMD,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,SAAI,EACnB,gBAAgB,SAAI,EACpB,kBAAkB,SAAI,EACtB,sBAAsB,SAAI,GACzB,MAAM,CAIR;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,SAAI,EACnB,gBAAgB,SAAI,EACpB,kBAAkB,SAAI,EACtB,sBAAsB,SAAI,GACzB,MAAM,CAIR;AAMD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAW7F;AAMD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,cAAc,EAAE,EACtB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,SAAI,EACnB,gBAAgB,SAAI,EACpB,kBAAkB,SAAI,EACtB,sBAAsB,SAAI,GACzB,MAAM,CAIR"}
|