@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.
- package/LICENSE +21 -0
- package/README.md +122 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +72 -0
- package/dist/cli.js.map +1 -0
- package/dist/diff.d.ts +16 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +37 -0
- package/dist/diff.js.map +1 -0
- package/dist/extract.d.ts +7 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +29 -0
- package/dist/extract.js.map +1 -0
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +13 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/metronome.d.ts +12 -0
- package/dist/providers/metronome.d.ts.map +1 -0
- package/dist/providers/metronome.js +163 -0
- package/dist/providers/metronome.js.map +1 -0
- package/dist/providers/types.d.ts +62 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/resources/index.d.ts +30 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +7 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/rates.d.ts +203 -0
- package/dist/resources/rates.d.ts.map +1 -0
- package/dist/resources/rates.js +171 -0
- package/dist/resources/rates.js.map +1 -0
- package/dist/resources/types.d.ts +19 -0
- package/dist/resources/types.d.ts.map +1 -0
- package/dist/resources/types.js +2 -0
- package/dist/resources/types.js.map +1 -0
- package/dist/spec.d.ts +10 -0
- package/dist/spec.d.ts.map +1 -0
- package/dist/spec.js +35 -0
- package/dist/spec.js.map +1 -0
- package/dist/sync.d.ts +11 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +85 -0
- package/dist/sync.js.map +1 -0
- 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
|
package/dist/cli.js.map
ADDED
|
@@ -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
|
package/dist/diff.js.map
ADDED
|
@@ -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 @@
|
|
|
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"}
|
package/dist/extract.js
ADDED
|
@@ -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 @@
|
|
|
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":"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"}
|
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}
|