@oliviersm199/rate-card-sync 0.1.0

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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +122 -0
  3. package/dist/cli.d.ts +6 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +72 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/diff.d.ts +16 -0
  8. package/dist/diff.d.ts.map +1 -0
  9. package/dist/diff.js +37 -0
  10. package/dist/diff.js.map +1 -0
  11. package/dist/extract.d.ts +7 -0
  12. package/dist/extract.d.ts.map +1 -0
  13. package/dist/extract.js +29 -0
  14. package/dist/extract.js.map +1 -0
  15. package/dist/providers/index.d.ts +4 -0
  16. package/dist/providers/index.d.ts.map +1 -0
  17. package/dist/providers/index.js +13 -0
  18. package/dist/providers/index.js.map +1 -0
  19. package/dist/providers/metronome.d.ts +12 -0
  20. package/dist/providers/metronome.d.ts.map +1 -0
  21. package/dist/providers/metronome.js +163 -0
  22. package/dist/providers/metronome.js.map +1 -0
  23. package/dist/providers/types.d.ts +62 -0
  24. package/dist/providers/types.d.ts.map +1 -0
  25. package/dist/providers/types.js +2 -0
  26. package/dist/providers/types.js.map +1 -0
  27. package/dist/resources/index.d.ts +30 -0
  28. package/dist/resources/index.d.ts.map +1 -0
  29. package/dist/resources/index.js +7 -0
  30. package/dist/resources/index.js.map +1 -0
  31. package/dist/resources/rates.d.ts +203 -0
  32. package/dist/resources/rates.d.ts.map +1 -0
  33. package/dist/resources/rates.js +171 -0
  34. package/dist/resources/rates.js.map +1 -0
  35. package/dist/resources/types.d.ts +19 -0
  36. package/dist/resources/types.d.ts.map +1 -0
  37. package/dist/resources/types.js +2 -0
  38. package/dist/resources/types.js.map +1 -0
  39. package/dist/spec.d.ts +10 -0
  40. package/dist/spec.d.ts.map +1 -0
  41. package/dist/spec.js +35 -0
  42. package/dist/spec.js.map +1 -0
  43. package/dist/sync.d.ts +11 -0
  44. package/dist/sync.d.ts.map +1 -0
  45. package/dist/sync.js +85 -0
  46. package/dist/sync.js.map +1 -0
  47. package/package.json +76 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 rate-card-sync contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Rate Card Sync
2
+
3
+ CLI to extract and sync billing rate card pricing as YAML. [Metronome](https://metronome.com) is supported today.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @oliviersm199/rate-card-sync
9
+ ```
10
+
11
+ Or run without installing:
12
+
13
+ ```bash
14
+ npx @oliviersm199/rate-card-sync extract --rate-card "Standard rate card"
15
+ ```
16
+
17
+ ## Authentication
18
+
19
+ Set a Metronome API bearer token:
20
+
21
+ ```bash
22
+ export METRONOME_BEARER_TOKEN="your-token"
23
+ ```
24
+
25
+ ## Commands
26
+
27
+ ### Extract
28
+
29
+ Pull the current rate card from Metronome into YAML:
30
+
31
+ ```bash
32
+ rate-card extract --rate-card "Standard rate card" --out rate-card.yaml
33
+ ```
34
+
35
+ Omit `--out` to print to stdout.
36
+
37
+ ### Sync
38
+
39
+ Apply a YAML spec to Metronome:
40
+
41
+ ```bash
42
+ rate-card sync rate-card.yaml
43
+ ```
44
+
45
+ Preview changes without applying:
46
+
47
+ ```bash
48
+ rate-card sync rate-card.yaml --dry-run
49
+ ```
50
+
51
+ Exit with code `2` when changes are pending (useful in CI):
52
+
53
+ ```bash
54
+ rate-card sync rate-card.yaml --dry-run --exit-code
55
+ ```
56
+
57
+ ## YAML spec
58
+
59
+ ```yaml
60
+ provider: metronome
61
+ rateCard:
62
+ name: Standard rate card
63
+ rates:
64
+ - product: GPT-5 input tokens
65
+ rateType: FLAT
66
+ price: 500
67
+ entitled: true
68
+ startingAt: "2026-06-19T00:00:00.000Z"
69
+ pricingGroupValues:
70
+ region: us-west-2
71
+ billingFrequency: MONTHLY
72
+ - product: LLM output tokens
73
+ rateType: FLAT
74
+ price: 0
75
+ entitled: true
76
+ commitRate:
77
+ rateType: FLAT
78
+ price: 1200
79
+ ```
80
+
81
+ - `provider` defaults to `metronome`
82
+ - `rateCard` requires `name` or `id`
83
+ - `startingAt` is optional on sync; defaults to now
84
+ - `price` is in the credit type's base unit (e.g. USD cents)
85
+ - `commitRate` sets the rate charged when usage is drawn down against a commit or credit; the list `price` is often `0` when pricing is defined here
86
+
87
+ See [`examples/rate-card.yaml`](examples/rate-card.yaml) for a full sample.
88
+
89
+ ## GitHub Actions
90
+
91
+ Copy the workflows in [`examples/github-actions/`](examples/github-actions/):
92
+
93
+ - `validate.yml` — run `sync --dry-run --exit-code` on pull requests to gate pricing drift
94
+ - `sync.yml` — apply changes when the spec changes on `main`
95
+
96
+ Both workflows expect a `METRONOME_BEARER_TOKEN` repository secret and reuse the repo's CI workflow as a quality gate.
97
+
98
+ ## Development
99
+
100
+ ```bash
101
+ npm install
102
+ npm test
103
+ npm run coverage
104
+ npm run build
105
+ ```
106
+
107
+ ## Limitations
108
+
109
+ Need something not listed here? Open a [GitHub Issue](https://github.com/oliviersm199/rate-card-sync/issues) describing your use case (use a Feature Request) — additional rate types and capabilities can be added on request.
110
+
111
+ - Rates only — does not create, update, or archive products, rate cards, credit types, or pricing units (they must already exist in Metronome)
112
+ - Single rate card per spec file
113
+ - FLAT is the first-class rate type; `PERCENTAGE`, `SUBSCRIPTION`, `TIERED`, `TIERED_PERCENTAGE`, and `CUSTOM` are preserved on extract and passed through on sync.
114
+ - Append-only sync — never deletes or ends existing rates; rates in Metronome but absent from YAML are reported as warnings only
115
+ - `commitRate` (the rate applied when consuming a commit or credit) is extracted and synced; other contract-level overrides are not handled
116
+ - Diff identity is limited to `product` + `pricingGroupValues` + `billingFrequency`
117
+ - Metronome is the only supported provider today. If you would like to see another provider, please create an issue.
118
+ - Rates are the only declaratively managed resource today; products, credit types, and pricing units must already exist. The architecture supports adding them later as new resource modules without breaking existing specs
119
+
120
+ ## License
121
+
122
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ export declare function formatError(error: unknown): string;
4
+ export declare function buildProgram(): Command;
5
+ export declare function run(argv: string[]): Promise<void>;
6
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAmBlD;AAED,wBAAgB,YAAY,IAAI,OAAO,CAwCtC;AAED,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvD"}
package/dist/cli.js ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ import { APIError } from "@metronome/sdk";
3
+ import { Command } from "commander";
4
+ import { fileURLToPath } from "node:url";
5
+ import { extract } from "./extract.js";
6
+ import { resolveSyncExitCode, sync } from "./sync.js";
7
+ export function formatError(error) {
8
+ if (error instanceof APIError) {
9
+ const lines = [`Provider API error (HTTP ${error.status ?? "unknown"})`];
10
+ const requestId = error.headers?.get("x-request-id");
11
+ if (requestId) {
12
+ lines.push(`Request ID: ${requestId}`);
13
+ }
14
+ if (error.error !== undefined) {
15
+ lines.push(`Response body: ${JSON.stringify(error.error)}`);
16
+ }
17
+ else if (error.message) {
18
+ lines.push(error.message);
19
+ }
20
+ return lines.join("\n");
21
+ }
22
+ return error instanceof Error ? error.message : String(error);
23
+ }
24
+ export function buildProgram() {
25
+ const program = new Command();
26
+ program.name("rate-card").description("Extract and sync billing rate card pricing as YAML").version("0.1.0");
27
+ program
28
+ .command("extract")
29
+ .description("Extract a rate card from a provider into YAML")
30
+ .requiredOption("--rate-card <nameOrId>", "Rate card name or UUID")
31
+ .option("--provider <name>", "Billing provider", "metronome")
32
+ .option("--out <file>", "Write YAML to file instead of stdout")
33
+ .action(async (options) => {
34
+ const yaml = await extract({
35
+ rateCard: options.rateCard,
36
+ providerName: options.provider,
37
+ out: options.out
38
+ });
39
+ if (!options.out) {
40
+ process.stdout.write(yaml);
41
+ }
42
+ });
43
+ program
44
+ .command("sync")
45
+ .description("Sync a YAML spec to the provider")
46
+ .argument("<spec>", "Path to the YAML spec file")
47
+ .option("--dry-run", "Preview changes without applying them", false)
48
+ .option("--exit-code", "Exit 2 when changes are pending (for CI)", false)
49
+ .action(async (specPath, options) => {
50
+ const result = await sync({
51
+ specPath,
52
+ dryRun: options.dryRun,
53
+ exitCode: options.exitCode
54
+ });
55
+ process.exitCode = resolveSyncExitCode(result, options.exitCode, options.dryRun);
56
+ });
57
+ return program;
58
+ }
59
+ export async function run(argv) {
60
+ try {
61
+ await buildProgram().parseAsync(argv);
62
+ }
63
+ catch (error) {
64
+ console.error(formatError(error));
65
+ process.exitCode = 1;
66
+ }
67
+ }
68
+ // Only run if the script is called directly
69
+ if (process.argv[1] === fileURLToPath(import.meta.url)) {
70
+ void run(process.argv);
71
+ }
72
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/diff.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ export interface DiffOptions<T> {
2
+ identity: (item: T) => string;
3
+ equals: (a: T, b: T) => boolean;
4
+ }
5
+ export interface DiffResult<T> {
6
+ toAdd: T[];
7
+ changed: Array<{
8
+ current: T;
9
+ desired: T;
10
+ }>;
11
+ unchanged: T[];
12
+ extra: T[];
13
+ }
14
+ export declare function diff<T>(current: T[], desired: T[], options: DiffOptions<T>): DiffResult<T>;
15
+ export declare function hasChanges<T>(result: DiffResult<T>): boolean;
16
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW,CAAC,CAAC;IAC1B,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;IAC7B,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAA;CAClC;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IACzB,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC,CAAC;QAAC,OAAO,EAAE,CAAC,CAAA;KAAE,CAAC,CAAA;IAC1C,SAAS,EAAE,CAAC,EAAE,CAAA;IACd,KAAK,EAAE,CAAC,EAAE,CAAA;CACb;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAuC1F;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAE5D"}
package/dist/diff.js ADDED
@@ -0,0 +1,37 @@
1
+ export function diff(current, desired, options) {
2
+ const currentById = new Map();
3
+ const desiredById = new Map();
4
+ for (const item of current) {
5
+ currentById.set(options.identity(item), item);
6
+ }
7
+ for (const item of desired) {
8
+ desiredById.set(options.identity(item), item);
9
+ }
10
+ const toAdd = [];
11
+ const changed = [];
12
+ const unchanged = [];
13
+ const extra = [];
14
+ for (const [id, desiredItem] of desiredById) {
15
+ const currentItem = currentById.get(id);
16
+ if (!currentItem) {
17
+ toAdd.push(desiredItem);
18
+ continue;
19
+ }
20
+ if (options.equals(currentItem, desiredItem)) {
21
+ unchanged.push(desiredItem);
22
+ }
23
+ else {
24
+ changed.push({ current: currentItem, desired: desiredItem });
25
+ }
26
+ }
27
+ for (const [id, currentItem] of currentById) {
28
+ if (!desiredById.has(id)) {
29
+ extra.push(currentItem);
30
+ }
31
+ }
32
+ return { toAdd, changed, unchanged, extra };
33
+ }
34
+ export function hasChanges(result) {
35
+ return result.toAdd.length > 0 || result.changed.length > 0;
36
+ }
37
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,IAAI,CAAI,OAAY,EAAE,OAAY,EAAE,OAAuB;IACvE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAa,CAAA;IACxC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAa,CAAA;IAExC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QACzB,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QACzB,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,KAAK,GAAQ,EAAE,CAAA;IACrB,MAAM,OAAO,GAAsC,EAAE,CAAA;IACrD,MAAM,SAAS,GAAQ,EAAE,CAAA;IACzB,MAAM,KAAK,GAAQ,EAAE,CAAA;IAErB,KAAK,MAAM,CAAC,EAAE,EAAE,WAAW,CAAC,IAAI,WAAW,EAAE,CAAC;QAC1C,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAEvC,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YACvB,SAAQ;QACZ,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;YAC3C,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC/B,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAA;QAChE,CAAC;IACL,CAAC;IAED,KAAK,MAAM,CAAC,EAAE,EAAE,WAAW,CAAC,IAAI,WAAW,EAAE,CAAC;QAC1C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC3B,CAAC;IACL,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAA;AAC/C,CAAC;AAED,MAAM,UAAU,UAAU,CAAI,MAAqB;IAC/C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAA;AAC/D,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface ExtractOptions {
2
+ rateCard: string;
3
+ providerName?: string;
4
+ out?: string;
5
+ }
6
+ export declare function extract(options: ExtractOptions): Promise<string>;
7
+ //# sourceMappingURL=extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BtE"}
@@ -0,0 +1,29 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import { getProvider } from "./providers/index.js";
3
+ import { getResourceModules } from "./resources/index.js";
4
+ import { dumpSpec } from "./spec.js";
5
+ export async function extract(options) {
6
+ const provider = getProvider(options.providerName ?? "metronome");
7
+ const rateCard = await provider.resolveRateCard(options.rateCard);
8
+ const products = await provider.listProducts();
9
+ const ctx = {
10
+ rateCardId: rateCard.id,
11
+ rateCardName: rateCard.name,
12
+ products
13
+ };
14
+ const spec = {
15
+ provider: "metronome",
16
+ rateCard: { name: rateCard.name, id: rateCard.id },
17
+ rates: []
18
+ };
19
+ for (const module of getResourceModules()) {
20
+ const items = await module.list(provider, ctx);
21
+ Object.assign(spec, { [module.key]: items });
22
+ }
23
+ const yaml = dumpSpec(spec);
24
+ if (options.out) {
25
+ await writeFile(options.out, yaml, "utf8");
26
+ }
27
+ return yaml;
28
+ }
29
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAqB,QAAQ,EAAE,MAAM,WAAW,CAAA;AAQvD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAuB;IACjD,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,YAAY,IAAI,WAAW,CAAC,CAAA;IACjE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACjE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAA;IAE9C,MAAM,GAAG,GAAoB;QACzB,UAAU,EAAE,QAAQ,CAAC,EAAE;QACvB,YAAY,EAAE,QAAQ,CAAC,IAAI;QAC3B,QAAQ;KACX,CAAA;IAED,MAAM,IAAI,GAAiB;QACvB,QAAQ,EAAE,WAAW;QACrB,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE;QAClD,KAAK,EAAE,EAAE;KACZ,CAAA;IAED,KAAK,MAAM,MAAM,IAAI,kBAAkB,EAAE,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;QAC9C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAChD,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAE3B,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,IAAI,CAAA;AACf,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { RateCardProvider } from "./types.js";
2
+ export declare function getProvider(name?: string): RateCardProvider;
3
+ export type { RateCardProvider } from "./types.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAMlD,wBAAgB,WAAW,CAAC,IAAI,SAAc,GAAG,gBAAgB,CAShE;AAED,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,13 @@
1
+ import { MetronomeProvider } from "./metronome.js";
2
+ const providers = {
3
+ metronome: () => new MetronomeProvider()
4
+ };
5
+ export function getProvider(name = "metronome") {
6
+ const factory = providers[name];
7
+ if (!factory) {
8
+ const supported = Object.keys(providers).join(", ");
9
+ throw new Error(`Unknown provider "${name}". Supported providers: ${supported}`);
10
+ }
11
+ return factory();
12
+ }
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAGlD,MAAM,SAAS,GAA2C;IACtD,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,iBAAiB,EAAE;CAC3C,CAAA;AAED,MAAM,UAAU,WAAW,CAAC,IAAI,GAAG,WAAW;IAC1C,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;IAE/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACnD,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,2BAA2B,SAAS,EAAE,CAAC,CAAA;IACpF,CAAC;IAED,OAAO,OAAO,EAAE,CAAA;AACpB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import Metronome from "@metronome/sdk";
2
+ import type { CanonicalRate, CanonicalRateAdd, ProductMaps, RateCardProvider, RateCardRef } from "./types.js";
3
+ export declare class MetronomeProvider implements RateCardProvider {
4
+ readonly name = "metronome";
5
+ private readonly client;
6
+ constructor(client?: Metronome);
7
+ resolveRateCard(nameOrId: string): Promise<RateCardRef>;
8
+ listProducts(): Promise<ProductMaps>;
9
+ getRates(rateCardId: string, at: string): Promise<CanonicalRate[]>;
10
+ addRates(rateCardId: string, rates: CanonicalRateAdd[]): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=metronome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metronome.d.ts","sourceRoot":"","sources":["../../src/providers/metronome.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,gBAAgB,CAAA;AAGtC,OAAO,KAAK,EAAyC,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAA;AAuJpK,qBAAa,iBAAkB,YAAW,gBAAgB;IACtD,QAAQ,CAAC,IAAI,eAAc;IAE3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;gBAEtB,MAAM,CAAC,EAAE,SAAS;IAIxB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAevD,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC;IAYpC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAalE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAU/E"}
@@ -0,0 +1,163 @@
1
+ import Metronome from "@metronome/sdk";
2
+ import { validate as validateUuid } from "uuid";
3
+ function normalizeRateType(value) {
4
+ return value.toUpperCase();
5
+ }
6
+ function mapTiers(tiers) {
7
+ return tiers.map(tier => {
8
+ const mapped = { price: tier.price };
9
+ if (tier.size !== undefined) {
10
+ mapped.size = tier.size;
11
+ }
12
+ return mapped;
13
+ });
14
+ }
15
+ function mapCommitRateFromSdk(commitRate) {
16
+ const mapped = { rateType: normalizeRateType(commitRate.rate_type) };
17
+ if (commitRate.price !== undefined) {
18
+ mapped.price = commitRate.price;
19
+ }
20
+ if (commitRate.tiers) {
21
+ mapped.tiers = mapTiers(commitRate.tiers);
22
+ }
23
+ return mapped;
24
+ }
25
+ function mapCommitRateToSdk(commitRate) {
26
+ const mapped = { rate_type: commitRate.rateType };
27
+ if (commitRate.price !== undefined) {
28
+ mapped.price = commitRate.price;
29
+ }
30
+ if (commitRate.tiers) {
31
+ mapped.tiers = mapTiers(commitRate.tiers);
32
+ }
33
+ return mapped;
34
+ }
35
+ function normalizeBillingFrequency(value) {
36
+ if (!value) {
37
+ return undefined;
38
+ }
39
+ return value.toUpperCase();
40
+ }
41
+ function mapListResponse(entry) {
42
+ const rate = {
43
+ productId: entry.product_id,
44
+ productName: entry.product_name,
45
+ rateType: normalizeRateType(entry.rate.rate_type),
46
+ entitled: entry.entitled
47
+ };
48
+ if (entry.rate.price !== undefined) {
49
+ rate.price = entry.rate.price;
50
+ }
51
+ if (entry.rate.credit_type?.id) {
52
+ rate.creditTypeId = entry.rate.credit_type.id;
53
+ }
54
+ if (entry.pricing_group_values) {
55
+ rate.pricingGroupValues = entry.pricing_group_values;
56
+ }
57
+ if (entry.billing_frequency) {
58
+ const billingFrequency = normalizeBillingFrequency(entry.billing_frequency);
59
+ if (billingFrequency) {
60
+ rate.billingFrequency = billingFrequency;
61
+ }
62
+ }
63
+ if (entry.rate.tiers) {
64
+ rate.tiers = mapTiers(entry.rate.tiers);
65
+ }
66
+ if (entry.rate.custom_rate) {
67
+ rate.customRate = entry.rate.custom_rate;
68
+ }
69
+ if (entry.rate.quantity !== undefined) {
70
+ rate.quantity = entry.rate.quantity;
71
+ }
72
+ if (entry.rate.is_prorated !== undefined) {
73
+ rate.isProrated = entry.rate.is_prorated;
74
+ }
75
+ if (entry.commit_rate) {
76
+ rate.commitRate = mapCommitRateFromSdk(entry.commit_rate);
77
+ }
78
+ return rate;
79
+ }
80
+ function mapAddRate(rate) {
81
+ const payload = {
82
+ product_id: rate.productId,
83
+ rate_type: rate.rateType,
84
+ entitled: rate.entitled,
85
+ starting_at: rate.startingAt
86
+ };
87
+ if (rate.price !== undefined) {
88
+ payload.price = rate.price;
89
+ }
90
+ if (rate.creditTypeId) {
91
+ payload.credit_type_id = rate.creditTypeId;
92
+ }
93
+ if (rate.pricingGroupValues) {
94
+ payload.pricing_group_values = rate.pricingGroupValues;
95
+ }
96
+ if (rate.billingFrequency) {
97
+ payload.billing_frequency = rate.billingFrequency;
98
+ }
99
+ if (rate.tiers) {
100
+ payload.tiers = mapTiers(rate.tiers);
101
+ }
102
+ if (rate.customRate) {
103
+ payload.custom_rate = rate.customRate;
104
+ }
105
+ if (rate.quantity !== undefined) {
106
+ payload.quantity = rate.quantity;
107
+ }
108
+ if (rate.isProrated !== undefined) {
109
+ payload.is_prorated = rate.isProrated;
110
+ }
111
+ if (rate.commitRate) {
112
+ payload.commit_rate = mapCommitRateToSdk(rate.commitRate);
113
+ }
114
+ return payload;
115
+ }
116
+ export class MetronomeProvider {
117
+ name = "metronome";
118
+ client;
119
+ constructor(client) {
120
+ this.client = client ?? new Metronome();
121
+ }
122
+ async resolveRateCard(nameOrId) {
123
+ if (validateUuid(nameOrId)) {
124
+ const response = await this.client.v1.contracts.rateCards.retrieve({ id: nameOrId });
125
+ return { id: response.data.id, name: response.data.name };
126
+ }
127
+ for await (const card of this.client.v1.contracts.rateCards.list({ body: {} })) {
128
+ if (card.name === nameOrId) {
129
+ return { id: card.id, name: card.name };
130
+ }
131
+ }
132
+ throw new Error(`Rate card not found: ${nameOrId}`);
133
+ }
134
+ async listProducts() {
135
+ const nameToId = new Map();
136
+ const idToName = new Map();
137
+ for await (const product of this.client.v1.contracts.products.list({ archive_filter: "NOT_ARCHIVED" })) {
138
+ nameToId.set(product.current.name, product.id);
139
+ idToName.set(product.id, product.current.name);
140
+ }
141
+ return { nameToId, idToName };
142
+ }
143
+ async getRates(rateCardId, at) {
144
+ const rates = [];
145
+ for await (const entry of this.client.v1.contracts.rateCards.rates.list({
146
+ rate_card_id: rateCardId,
147
+ at
148
+ })) {
149
+ rates.push(mapListResponse(entry));
150
+ }
151
+ return rates;
152
+ }
153
+ async addRates(rateCardId, rates) {
154
+ if (rates.length === 0) {
155
+ return;
156
+ }
157
+ await this.client.v1.contracts.rateCards.rates.addMany({
158
+ rate_card_id: rateCardId,
159
+ rates: rates.map(mapAddRate)
160
+ });
161
+ }
162
+ }
163
+ //# sourceMappingURL=metronome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metronome.js","sourceRoot":"","sources":["../../src/providers/metronome.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,MAAM,CAAA;AAM/C,SAAS,iBAAiB,CAAC,KAAa;IACpC,OAAO,KAAK,CAAC,WAAW,EAAc,CAAA;AAC1C,CAAC;AAED,SAAS,QAAQ,CAAC,KAAsD;IACpE,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACpB,MAAM,MAAM,GAAS,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAA;QAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QAC3B,CAAC;QACD,OAAO,MAAM,CAAA;IACjB,CAAC,CAAC,CAAA;AACN,CAAC;AAED,SAAS,oBAAoB,CAAC,UAAyB;IACnD,MAAM,MAAM,GAAwB,EAAE,QAAQ,EAAE,iBAAiB,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAA;IAEzF,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;IACnC,CAAC;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC;AAED,SAAS,kBAAkB,CAAC,UAA+B;IACvD,MAAM,MAAM,GAAkB,EAAE,SAAS,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAA;IAEhE,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;IACnC,CAAC;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAyB;IACxD,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,OAAO,SAAS,CAAA;IACpB,CAAC;IAED,OAAO,KAAK,CAAC,WAAW,EAAsB,CAAA;AAClD,CAAC;AAED,SAAS,eAAe,CAAC,KAA8D;IACnF,MAAM,IAAI,GAAkB;QACxB,SAAS,EAAE,KAAK,CAAC,UAAU;QAC3B,WAAW,EAAE,KAAK,CAAC,YAAY;QAC/B,QAAQ,EAAE,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;QACjD,QAAQ,EAAE,KAAK,CAAC,QAAQ;KAC3B,CAAA;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAA;IACjC,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAA;IACjD,CAAC;IAED,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC,oBAAoB,CAAA;IACxD,CAAC;IAED,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;QAC3E,IAAI,gBAAgB,EAAE,CAAC;YACnB,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAA;QAC5C,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC3C,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAA;IAC5C,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAA;IACvC,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAA;IAC5C,CAAC;IAED,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACpB,IAAI,CAAC,UAAU,GAAG,oBAAoB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IAC7D,CAAC;IAED,OAAO,IAAI,CAAA;AACf,CAAC;AAED,SAAS,UAAU,CAAC,IAAsB;IACtC,MAAM,OAAO,GAAkE;QAC3E,UAAU,EAAE,IAAI,CAAC,SAAS;QAC1B,SAAS,EAAE,IAAI,CAAC,QAAQ;QACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,WAAW,EAAE,IAAI,CAAC,UAAU;KAC/B,CAAA;IAED,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;IAC9B,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,YAAY,CAAA;IAC9C,CAAC;IAED,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,kBAAkB,CAAA;IAC1D,CAAC;IAED,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,CAAA;IACrD,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAA;IACzC,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IACpC,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAA;IACzC,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,CAAC,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC7D,CAAC;IAED,OAAO,OAAO,CAAA;AAClB,CAAC;AAED,MAAM,OAAO,iBAAiB;IACjB,IAAI,GAAG,WAAW,CAAA;IAEV,MAAM,CAAW;IAElC,YAAY,MAAkB;QAC1B,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,IAAI,SAAS,EAAE,CAAA;IAC3C,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,QAAgB;QAClC,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;YACpF,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;QAC7D,CAAC;QAED,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;YAC7E,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAA;YAC3C,CAAC;QACL,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,EAAE,CAAC,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,YAAY;QACd,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAA;QAC1C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAA;QAE1C,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;YACrG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;YAC9C,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAClD,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;IACjC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,UAAkB,EAAE,EAAU;QACzC,MAAM,KAAK,GAAoB,EAAE,CAAA;QAEjC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;YACpE,YAAY,EAAE,UAAU;YACxB,EAAE;SACL,CAAC,EAAE,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAA;QACtC,CAAC;QAED,OAAO,KAAK,CAAA;IAChB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,UAAkB,EAAE,KAAyB;QACxD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAM;QACV,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;YACnD,YAAY,EAAE,UAAU;YACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC;SAC/B,CAAC,CAAA;IACN,CAAC;CACJ"}
@@ -0,0 +1,62 @@
1
+ export type RateType = "FLAT" | "PERCENTAGE" | "SUBSCRIPTION" | "TIERED" | "TIERED_PERCENTAGE" | "CUSTOM";
2
+ export type BillingFrequency = "MONTHLY" | "QUARTERLY" | "ANNUAL" | "WEEKLY";
3
+ export interface Tier {
4
+ size?: number;
5
+ price: number;
6
+ }
7
+ export interface CanonicalCommitRate {
8
+ rateType: RateType;
9
+ price?: number;
10
+ tiers?: Tier[];
11
+ }
12
+ export interface CanonicalRate {
13
+ productId: string;
14
+ productName: string;
15
+ rateType: RateType;
16
+ entitled: boolean;
17
+ price?: number;
18
+ creditTypeId?: string;
19
+ pricingGroupValues?: Record<string, string>;
20
+ billingFrequency?: BillingFrequency;
21
+ tiers?: Tier[];
22
+ customRate?: Record<string, unknown>;
23
+ quantity?: number;
24
+ isProrated?: boolean;
25
+ commitRate?: CanonicalCommitRate;
26
+ }
27
+ export interface CanonicalRateAdd {
28
+ productId: string;
29
+ rateType: RateType;
30
+ entitled: boolean;
31
+ startingAt: string;
32
+ price?: number;
33
+ creditTypeId?: string;
34
+ pricingGroupValues?: Record<string, string>;
35
+ billingFrequency?: BillingFrequency;
36
+ tiers?: Tier[];
37
+ customRate?: Record<string, unknown>;
38
+ quantity?: number;
39
+ isProrated?: boolean;
40
+ commitRate?: CanonicalCommitRate;
41
+ }
42
+ export interface ProductMaps {
43
+ nameToId: Map<string, string>;
44
+ idToName: Map<string, string>;
45
+ }
46
+ export interface RateCardRef {
47
+ id: string;
48
+ name: string;
49
+ }
50
+ export interface RateCardProvider {
51
+ readonly name: string;
52
+ resolveRateCard(nameOrId: string): Promise<RateCardRef>;
53
+ listProducts(): Promise<ProductMaps>;
54
+ getRates(rateCardId: string, at: string): Promise<CanonicalRate[]>;
55
+ addRates(rateCardId: string, rates: CanonicalRateAdd[]): Promise<void>;
56
+ }
57
+ export interface ResourceContext {
58
+ rateCardId: string;
59
+ rateCardName: string;
60
+ products: ProductMaps;
61
+ }
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,YAAY,GAAG,cAAc,GAAG,QAAQ,GAAG,mBAAmB,GAAG,QAAQ,CAAA;AAEzG,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE5E,MAAM,WAAW,IAAI;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAChC,QAAQ,EAAE,QAAQ,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,mBAAmB,CAAA;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,mBAAmB,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IACvD,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;IAClE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACzE;AAED,MAAM,WAAW,eAAe;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,WAAW,CAAA;CACxB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}