@volter/twin-polar 2.0.36 → 3.0.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/README.md +24 -27
- package/dist/generated/pack-facts.json +69 -0
- package/dist/journeys/coverage.json +223 -0
- package/dist/journeys/customer-life.json +1222 -0
- package/dist/journeys/customer-life.outline.md +69 -0
- package/dist/journeys/customer-life.outline.verdict.json +41 -0
- package/dist/journeys/customer-life.verdict.json +71 -0
- package/dist/journeys/decisions.json +149 -0
- package/dist/journeys/demand.json +45 -0
- package/dist/journeys/score.json +249 -0
- package/dist/journeys/unreachable.json +13 -0
- package/dist/journeys/vendor-examples.json +9621 -0
- package/dist/journeys/vendor-examples.verdict.json +33 -0
- package/dist/spec/SOURCE.md +25 -0
- package/dist/spec/doc-examples.json +681 -0
- package/dist/spec/openapi.json.gz +0 -0
- package/dist/spec/sources.json +71 -0
- package/dist/src/cli.js +7 -16
- package/dist/src/fetch.d.ts +2 -0
- package/dist/src/fetch.js +24 -0
- package/dist/src/generated/surface.gen.json +1 -0
- package/dist/src/generated/ui.gen.json +1 -0
- package/dist/src/index.d.ts +5 -9
- package/dist/src/index.js +10 -55
- package/dist/src/manifest.d.ts +2 -0
- package/dist/src/manifest.js +123 -0
- package/dist/src/screens/checkout.d.ts +2 -0
- package/dist/src/screens/checkout.js +25 -0
- package/dist/src/screens/portal.d.ts +2 -0
- package/dist/src/screens/portal.js +18 -0
- package/dist/src/semantics/around.d.ts +2 -0
- package/dist/src/semantics/around.js +25 -0
- package/dist/src/semantics/checkouts.d.ts +14 -0
- package/dist/src/semantics/checkouts.js +131 -0
- package/dist/src/semantics/clock.d.ts +2 -0
- package/dist/src/semantics/clock.js +22 -0
- package/dist/src/semantics/customer-sessions.d.ts +2 -0
- package/dist/src/semantics/customer-sessions.js +12 -0
- package/dist/src/semantics/customers.d.ts +9 -0
- package/dist/src/semantics/customers.js +61 -0
- package/dist/src/semantics/doors.d.ts +11 -0
- package/dist/src/semantics/doors.js +47 -0
- package/dist/src/semantics/events.d.ts +12 -0
- package/dist/src/semantics/events.js +60 -0
- package/dist/src/semantics/index.d.ts +2 -0
- package/dist/src/semantics/index.js +27 -0
- package/dist/src/semantics/orders.d.ts +4 -0
- package/dist/src/semantics/orders.js +11 -0
- package/dist/src/semantics/products.d.ts +5 -0
- package/dist/src/semantics/products.js +43 -0
- package/dist/src/semantics/shared.d.ts +82 -0
- package/dist/src/semantics/shared.js +327 -0
- package/dist/src/semantics/states.d.ts +27 -0
- package/dist/src/semantics/states.js +43 -0
- package/dist/src/semantics/subscriptions.d.ts +4 -0
- package/dist/src/semantics/subscriptions.js +15 -0
- package/dist/src/semantics/tenant.d.ts +2 -0
- package/dist/src/semantics/tenant.js +2 -0
- package/dist/src/semantics/webhooks.d.ts +4 -0
- package/dist/src/semantics/webhooks.js +30 -0
- package/dist/src/server.d.ts +7 -0
- package/dist/src/server.js +7 -0
- package/generated/pack-facts.json +69 -0
- package/journeys/coverage.json +223 -0
- package/journeys/customer-life.json +1222 -0
- package/journeys/customer-life.outline.md +69 -0
- package/journeys/customer-life.outline.verdict.json +41 -0
- package/journeys/customer-life.verdict.json +71 -0
- package/journeys/decisions.json +149 -0
- package/journeys/demand.json +45 -0
- package/journeys/score.json +249 -0
- package/journeys/unreachable.json +13 -0
- package/journeys/vendor-examples.json +9621 -0
- package/journeys/vendor-examples.verdict.json +33 -0
- package/package.json +19 -31
- package/spec/SOURCE.md +25 -0
- package/spec/doc-examples.json +681 -0
- package/spec/openapi.json.gz +0 -0
- package/spec/sources.json +71 -0
- package/src/cli.ts +7 -14
- package/src/fetch.ts +25 -0
- package/src/generated/surface.gen.json +1 -0
- package/src/generated/ui.gen.json +1 -0
- package/src/index.ts +11 -85
- package/src/manifest.ts +135 -0
- package/src/screens/checkout.ts +33 -0
- package/src/screens/portal.ts +20 -0
- package/src/semantics/around.ts +25 -0
- package/src/semantics/checkouts.ts +133 -0
- package/src/semantics/clock.ts +24 -0
- package/src/semantics/customer-sessions.ts +13 -0
- package/src/semantics/customers.ts +68 -0
- package/src/semantics/doors.ts +51 -0
- package/src/semantics/events.ts +62 -0
- package/src/semantics/index.ts +31 -0
- package/src/semantics/orders.ts +15 -0
- package/src/semantics/products.ts +45 -0
- package/src/semantics/shared.ts +352 -0
- package/src/semantics/states.ts +50 -0
- package/src/semantics/subscriptions.ts +18 -0
- package/src/semantics/tenant.ts +5 -0
- package/src/semantics/webhooks.ts +29 -0
- package/src/server.ts +8 -0
- package/dist/src/polar-budget.d.ts +0 -83
- package/dist/src/polar-budget.js +0 -413
- package/dist/src/polar-capabilities.d.ts +0 -4
- package/dist/src/polar-capabilities.js +0 -389
- package/dist/src/polar-conformance.d.ts +0 -7
- package/dist/src/polar-conformance.js +0 -25
- package/dist/src/polar-connector.d.ts +0 -113
- package/dist/src/polar-connector.js +0 -146
- package/dist/src/polar-server.d.ts +0 -14
- package/dist/src/polar-server.js +0 -52
- package/dist/src/polar-twin.d.ts +0 -24
- package/dist/src/polar-twin.js +0 -941
- package/src/polar-budget.ts +0 -459
- package/src/polar-capabilities.ts +0 -448
- package/src/polar-conformance.ts +0 -33
- package/src/polar-connector.ts +0 -172
- package/src/polar-server.ts +0 -57
- package/src/polar-twin.ts +0 -938
package/README.md
CHANGED
|
@@ -1,36 +1,33 @@
|
|
|
1
1
|
# @volter/twin-polar
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
The Polar twin (Protocol 3): Polar's API (`api.polar.sh`) derived from its own OpenAPI document (`spec/`, provenance
|
|
4
|
+
in `spec/SOURCE.md`), scoped to what the applications that bill through Polar call
|
|
5
|
+
([journeys/demand.json](./journeys/demand.json)): Volter's platform biller (twin-world `apps/billing`) and Open Autonomy's patronage.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
| area | served |
|
|
8
|
+
|---|---|
|
|
9
|
+
| catalog | meters (listed, made) and products (listed, made) |
|
|
10
|
+
| checkout | checkouts made, listed and read back by id, and Polar's hosted checkout page (`buy.polar.sh/<client secret>`), which reads and confirms it (making the order and, for a recurring product, the subscription) |
|
|
11
|
+
| customers | made, listed, read by id, their state (active subscriptions, meter usage) by external id, and a customer session and its pre-authenticated portal overview (subscriptions and purchase history) |
|
|
12
|
+
| usage | events ingested and listed |
|
|
13
|
+
| subscriptions | listed |
|
|
14
|
+
| orders | listed (by checkout, customer, product, subscription, status), each paid order told by `order.created` and `order.paid` |
|
|
15
|
+
| webhooks | checkout creation and order events delivered, signed with Standard Webhooks, to endpoints registered and listed through the API (`/v1/webhooks/endpoints`) |
|
|
9
16
|
|
|
10
|
-
|
|
17
|
+
Portal email sign-in, cancellation, invoice downloads and payment-method changes are outside this scope. Calendar-month subscription renewals and trial conversion run on the World clock; payments use deterministic test confirmation tokens and succeed. Fixed/custom paid checkouts require the client confirmation token; trial orders are deferred. Production and sandbox credentials and records are independent. Checkouts expire after 24 hours.
|
|
11
18
|
|
|
12
|
-
|
|
13
|
-
merchant-of-record API. Coverage is partial and will read low as the denominator grows — see the
|
|
14
|
-
manifest's `todo` entries for what is enumerated but not yet modeled.
|
|
19
|
+
Every other operation of Polar's API is the gap (`src/manifest.ts` `unmodeled`, and the operations no handler serves).
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
usage-events, license keys, discounts, webhooks, OAuth, and the connector's pull/push.
|
|
21
|
+
## Credentials
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
An organization's operations take an Organization Access Token the World issued (held by its SHA-256); a customer
|
|
24
|
+
portal operation takes a live customer session's token; the checkout's client operations take the checkout's client
|
|
25
|
+
secret in their path (each operation's security schemes, from the spec's security as the derive keeps them). The World's application is issued its token when
|
|
26
|
+
the World boots (`POST /_twin/app-credentials`, the descriptor's credential door), the same at every boot.
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
it returns deterministic checkout/order shapes and "confirms" payment offline.
|
|
24
|
-
- `polar.tax.real_calculation` — tax-authority integrations and live jurisdiction rules are
|
|
25
|
-
outside a deterministic local twin.
|
|
28
|
+
## Doors
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
which does mirror — so under the rule in
|
|
32
|
-
[../../../docs/contributing/adding-a-twin.md](../../../docs/contributing/adding-a-twin.md) ("Does this vendor get a mirror?") it
|
|
33
|
-
should have one. The work is tracked in the manifest as `polar.mirror.ui`
|
|
34
|
-
(operator mirror for customers/subscriptions/orders/events).
|
|
35
|
-
|
|
36
|
-
Do **not** cite this pack as precedent for omitting a mirror.
|
|
30
|
+
- `POST /_twin/access-tokens {comment, expires_in_days?}` and `DELETE /_twin/access-tokens/{n}`: tokens (including their returned id) made and revoked
|
|
31
|
+
on the settings page.
|
|
32
|
+
- `POST /_twin/app-credentials`: the application's token.
|
|
33
|
+
- `GET /_twin/deliveries?to=&type=`: every webhook sent, as the receiving server got it.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"//": "GENERATED by scripts/pack-facts.ts — current pack descriptors and explicit world-runtime server backings; no prior-artifact entries are retained.",
|
|
3
|
+
"packs": {
|
|
4
|
+
"polar": {
|
|
5
|
+
"adoption": {
|
|
6
|
+
"sdks": [
|
|
7
|
+
"@polar-sh/sdk"
|
|
8
|
+
],
|
|
9
|
+
"pypi": [
|
|
10
|
+
"polar-sdk"
|
|
11
|
+
],
|
|
12
|
+
"scopes": [
|
|
13
|
+
"@polar-sh/"
|
|
14
|
+
],
|
|
15
|
+
"envStems": [
|
|
16
|
+
"POLAR"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"hosts": [
|
|
20
|
+
{
|
|
21
|
+
"host": "api.polar.sh"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"host": "sandbox-api.polar.sh"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"host": "buy.polar.sh"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"host": "polar.sh",
|
|
31
|
+
"pathPattern": "^/[^/]+/portal"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"host": "sandbox.polar.sh"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"archetype": "crud",
|
|
38
|
+
"protocol": {
|
|
39
|
+
"declared": "3",
|
|
40
|
+
"major": 3,
|
|
41
|
+
"standing": "current"
|
|
42
|
+
},
|
|
43
|
+
"transport": "rest",
|
|
44
|
+
"resources": [
|
|
45
|
+
"customer",
|
|
46
|
+
"product",
|
|
47
|
+
"checkout",
|
|
48
|
+
"subscription",
|
|
49
|
+
"order",
|
|
50
|
+
"event",
|
|
51
|
+
"meter",
|
|
52
|
+
"customer_session",
|
|
53
|
+
"webhook_endpoint"
|
|
54
|
+
],
|
|
55
|
+
"endpointEnvNone": "@polar-sh/sdk reads no base-URL variable: its `server` option picks production or sandbox, both claimed by the host rules.",
|
|
56
|
+
"credentialDoor": {
|
|
57
|
+
"path": "/_twin/app-credentials",
|
|
58
|
+
"body": {},
|
|
59
|
+
"fill": {
|
|
60
|
+
"POLAR_ACCESS_TOKEN": "access_token",
|
|
61
|
+
"POLAR_API_KEY": "access_token",
|
|
62
|
+
"POLAR_ORGANIZATION_TOKEN": "access_token"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"serveExport": "createPolarTwinServer"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"undeclared": []
|
|
69
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
{
|
|
2
|
+
"vendor": "polar",
|
|
3
|
+
"missing": 27,
|
|
4
|
+
"stale": [],
|
|
5
|
+
"code": {
|
|
6
|
+
"lines": 763,
|
|
7
|
+
"run": 750,
|
|
8
|
+
"recorded": 2,
|
|
9
|
+
"missing": 11
|
|
10
|
+
},
|
|
11
|
+
"state": {
|
|
12
|
+
"declared": 9,
|
|
13
|
+
"reached": 2,
|
|
14
|
+
"recorded": 0,
|
|
15
|
+
"missing": [
|
|
16
|
+
"refusal Checkout.status: checkouts:client_confirm confirmed|succeeded|failed|expired → (stays)",
|
|
17
|
+
"move Checkout.status: vendor confirmed → succeeded",
|
|
18
|
+
"move Checkout.status: time open → expired",
|
|
19
|
+
"refusal Subscription.status: checkouts:client_confirm active|trialing → (stays)",
|
|
20
|
+
"move Subscription.status: vendor incomplete → active",
|
|
21
|
+
"move Subscription.status: vendor incomplete → trialing",
|
|
22
|
+
"move Subscription.status: time trialing → active"
|
|
23
|
+
],
|
|
24
|
+
"undeclared": [
|
|
25
|
+
"Checkout.status: confirmed → succeeded by checkout.update",
|
|
26
|
+
"Checkout.status: confirmed → succeeded by checkouts:client_confirm",
|
|
27
|
+
"Checkout.status: open → expired by checkout.update",
|
|
28
|
+
"Order.status: pending → paid by checkouts:client_confirm",
|
|
29
|
+
"Order.status: pending → paid by order.pay",
|
|
30
|
+
"Subscription.status: incomplete → active by checkouts:client_confirm",
|
|
31
|
+
"Subscription.status: incomplete → active by subscription.activate",
|
|
32
|
+
"Subscription.status: incomplete → trialing by subscription.activate",
|
|
33
|
+
"Subscription.status: trialing → active by subscription.update"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
{
|
|
38
|
+
"file": "semantics/doors.ts",
|
|
39
|
+
"lines": {
|
|
40
|
+
"found": 28,
|
|
41
|
+
"hit": 28
|
|
42
|
+
},
|
|
43
|
+
"missing": []
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"file": "semantics/states.ts",
|
|
47
|
+
"lines": {
|
|
48
|
+
"found": 34,
|
|
49
|
+
"hit": 34
|
|
50
|
+
},
|
|
51
|
+
"missing": []
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"file": "semantics/customers.ts",
|
|
55
|
+
"lines": {
|
|
56
|
+
"found": 34,
|
|
57
|
+
"hit": 32
|
|
58
|
+
},
|
|
59
|
+
"missing": [
|
|
60
|
+
{
|
|
61
|
+
"from": 60,
|
|
62
|
+
"to": 60,
|
|
63
|
+
"fn": "duplicateExternal"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"from": 66,
|
|
67
|
+
"to": 66,
|
|
68
|
+
"fn": "duplicateEmail"
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"file": "semantics/customer-sessions.ts",
|
|
74
|
+
"lines": {
|
|
75
|
+
"found": 7,
|
|
76
|
+
"hit": 7
|
|
77
|
+
},
|
|
78
|
+
"missing": []
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"file": "semantics/webhooks.ts",
|
|
82
|
+
"lines": {
|
|
83
|
+
"found": 17,
|
|
84
|
+
"hit": 17
|
|
85
|
+
},
|
|
86
|
+
"missing": []
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"file": "semantics/shared.ts",
|
|
90
|
+
"lines": {
|
|
91
|
+
"found": 245,
|
|
92
|
+
"hit": 236
|
|
93
|
+
},
|
|
94
|
+
"missing": [
|
|
95
|
+
{
|
|
96
|
+
"from": 331,
|
|
97
|
+
"to": 339,
|
|
98
|
+
"fn": "compareClause"
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"file": "semantics/around.ts",
|
|
104
|
+
"lines": {
|
|
105
|
+
"found": 12,
|
|
106
|
+
"hit": 12
|
|
107
|
+
},
|
|
108
|
+
"missing": []
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"file": "semantics/products.ts",
|
|
112
|
+
"lines": {
|
|
113
|
+
"found": 34,
|
|
114
|
+
"hit": 34
|
|
115
|
+
},
|
|
116
|
+
"missing": []
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"file": "semantics/orders.ts",
|
|
120
|
+
"lines": {
|
|
121
|
+
"found": 7,
|
|
122
|
+
"hit": 7
|
|
123
|
+
},
|
|
124
|
+
"missing": []
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"file": "semantics/subscriptions.ts",
|
|
128
|
+
"lines": {
|
|
129
|
+
"found": 10,
|
|
130
|
+
"hit": 10
|
|
131
|
+
},
|
|
132
|
+
"missing": []
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"file": "semantics/clock.ts",
|
|
136
|
+
"lines": {
|
|
137
|
+
"found": 17,
|
|
138
|
+
"hit": 17
|
|
139
|
+
},
|
|
140
|
+
"missing": []
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"file": "semantics/events.ts",
|
|
144
|
+
"lines": {
|
|
145
|
+
"found": 37,
|
|
146
|
+
"hit": 37
|
|
147
|
+
},
|
|
148
|
+
"missing": []
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"file": "semantics/index.ts",
|
|
152
|
+
"lines": {
|
|
153
|
+
"found": 27,
|
|
154
|
+
"hit": 27
|
|
155
|
+
},
|
|
156
|
+
"missing": []
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"file": "semantics/tenant.ts",
|
|
160
|
+
"lines": {
|
|
161
|
+
"found": 2,
|
|
162
|
+
"hit": 2
|
|
163
|
+
},
|
|
164
|
+
"missing": []
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"file": "semantics/checkouts.ts",
|
|
168
|
+
"lines": {
|
|
169
|
+
"found": 85,
|
|
170
|
+
"hit": 85
|
|
171
|
+
},
|
|
172
|
+
"missing": []
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"file": "screens/checkout.ts",
|
|
176
|
+
"lines": {
|
|
177
|
+
"found": 21,
|
|
178
|
+
"hit": 21
|
|
179
|
+
},
|
|
180
|
+
"missing": []
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"file": "screens/portal.ts",
|
|
184
|
+
"lines": {
|
|
185
|
+
"found": 13,
|
|
186
|
+
"hit": 13
|
|
187
|
+
},
|
|
188
|
+
"missing": []
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"file": "manifest.ts",
|
|
192
|
+
"lines": {
|
|
193
|
+
"found": 101,
|
|
194
|
+
"hit": 101
|
|
195
|
+
},
|
|
196
|
+
"missing": []
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"file": "index.ts",
|
|
200
|
+
"lines": {
|
|
201
|
+
"found": 7,
|
|
202
|
+
"hit": 7
|
|
203
|
+
},
|
|
204
|
+
"missing": []
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"file": "server.ts",
|
|
208
|
+
"lines": {
|
|
209
|
+
"found": 4,
|
|
210
|
+
"hit": 2
|
|
211
|
+
},
|
|
212
|
+
"missing": []
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"file": "fetch.ts",
|
|
216
|
+
"lines": {
|
|
217
|
+
"found": 21,
|
|
218
|
+
"hit": 21
|
|
219
|
+
},
|
|
220
|
+
"missing": []
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
}
|