@volter/twin-polar 2.0.37 → 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.
Files changed (121) hide show
  1. package/README.md +24 -27
  2. package/dist/generated/pack-facts.json +69 -0
  3. package/dist/journeys/coverage.json +223 -0
  4. package/dist/journeys/customer-life.json +1222 -0
  5. package/dist/journeys/customer-life.outline.md +69 -0
  6. package/dist/journeys/customer-life.outline.verdict.json +41 -0
  7. package/dist/journeys/customer-life.verdict.json +71 -0
  8. package/dist/journeys/decisions.json +149 -0
  9. package/dist/journeys/demand.json +45 -0
  10. package/dist/journeys/score.json +249 -0
  11. package/dist/journeys/unreachable.json +13 -0
  12. package/dist/journeys/vendor-examples.json +9621 -0
  13. package/dist/journeys/vendor-examples.verdict.json +33 -0
  14. package/dist/spec/SOURCE.md +25 -0
  15. package/dist/spec/doc-examples.json +681 -0
  16. package/dist/spec/openapi.json.gz +0 -0
  17. package/dist/spec/sources.json +71 -0
  18. package/dist/src/cli.js +7 -16
  19. package/dist/src/fetch.d.ts +2 -0
  20. package/dist/src/fetch.js +24 -0
  21. package/dist/src/generated/surface.gen.json +1 -0
  22. package/dist/src/generated/ui.gen.json +1 -0
  23. package/dist/src/index.d.ts +5 -9
  24. package/dist/src/index.js +10 -55
  25. package/dist/src/manifest.d.ts +2 -0
  26. package/dist/src/manifest.js +123 -0
  27. package/dist/src/screens/checkout.d.ts +2 -0
  28. package/dist/src/screens/checkout.js +25 -0
  29. package/dist/src/screens/portal.d.ts +2 -0
  30. package/dist/src/screens/portal.js +18 -0
  31. package/dist/src/semantics/around.d.ts +2 -0
  32. package/dist/src/semantics/around.js +25 -0
  33. package/dist/src/semantics/checkouts.d.ts +14 -0
  34. package/dist/src/semantics/checkouts.js +131 -0
  35. package/dist/src/semantics/clock.d.ts +2 -0
  36. package/dist/src/semantics/clock.js +22 -0
  37. package/dist/src/semantics/customer-sessions.d.ts +2 -0
  38. package/dist/src/semantics/customer-sessions.js +12 -0
  39. package/dist/src/semantics/customers.d.ts +9 -0
  40. package/dist/src/semantics/customers.js +61 -0
  41. package/dist/src/semantics/doors.d.ts +11 -0
  42. package/dist/src/semantics/doors.js +47 -0
  43. package/dist/src/semantics/events.d.ts +12 -0
  44. package/dist/src/semantics/events.js +60 -0
  45. package/dist/src/semantics/index.d.ts +2 -0
  46. package/dist/src/semantics/index.js +27 -0
  47. package/dist/src/semantics/orders.d.ts +4 -0
  48. package/dist/src/semantics/orders.js +11 -0
  49. package/dist/src/semantics/products.d.ts +5 -0
  50. package/dist/src/semantics/products.js +43 -0
  51. package/dist/src/semantics/shared.d.ts +82 -0
  52. package/dist/src/semantics/shared.js +327 -0
  53. package/dist/src/semantics/states.d.ts +27 -0
  54. package/dist/src/semantics/states.js +43 -0
  55. package/dist/src/semantics/subscriptions.d.ts +4 -0
  56. package/dist/src/semantics/subscriptions.js +15 -0
  57. package/dist/src/semantics/tenant.d.ts +2 -0
  58. package/dist/src/semantics/tenant.js +2 -0
  59. package/dist/src/semantics/webhooks.d.ts +4 -0
  60. package/dist/src/semantics/webhooks.js +30 -0
  61. package/dist/src/server.d.ts +7 -0
  62. package/dist/src/server.js +7 -0
  63. package/generated/pack-facts.json +69 -0
  64. package/journeys/coverage.json +223 -0
  65. package/journeys/customer-life.json +1222 -0
  66. package/journeys/customer-life.outline.md +69 -0
  67. package/journeys/customer-life.outline.verdict.json +41 -0
  68. package/journeys/customer-life.verdict.json +71 -0
  69. package/journeys/decisions.json +149 -0
  70. package/journeys/demand.json +45 -0
  71. package/journeys/score.json +249 -0
  72. package/journeys/unreachable.json +13 -0
  73. package/journeys/vendor-examples.json +9621 -0
  74. package/journeys/vendor-examples.verdict.json +33 -0
  75. package/package.json +19 -31
  76. package/spec/SOURCE.md +25 -0
  77. package/spec/doc-examples.json +681 -0
  78. package/spec/openapi.json.gz +0 -0
  79. package/spec/sources.json +71 -0
  80. package/src/cli.ts +7 -14
  81. package/src/fetch.ts +25 -0
  82. package/src/generated/surface.gen.json +1 -0
  83. package/src/generated/ui.gen.json +1 -0
  84. package/src/index.ts +11 -85
  85. package/src/manifest.ts +135 -0
  86. package/src/screens/checkout.ts +33 -0
  87. package/src/screens/portal.ts +20 -0
  88. package/src/semantics/around.ts +25 -0
  89. package/src/semantics/checkouts.ts +133 -0
  90. package/src/semantics/clock.ts +24 -0
  91. package/src/semantics/customer-sessions.ts +13 -0
  92. package/src/semantics/customers.ts +68 -0
  93. package/src/semantics/doors.ts +51 -0
  94. package/src/semantics/events.ts +62 -0
  95. package/src/semantics/index.ts +31 -0
  96. package/src/semantics/orders.ts +15 -0
  97. package/src/semantics/products.ts +45 -0
  98. package/src/semantics/shared.ts +352 -0
  99. package/src/semantics/states.ts +50 -0
  100. package/src/semantics/subscriptions.ts +18 -0
  101. package/src/semantics/tenant.ts +5 -0
  102. package/src/semantics/webhooks.ts +29 -0
  103. package/src/server.ts +8 -0
  104. package/dist/src/polar-budget.d.ts +0 -83
  105. package/dist/src/polar-budget.js +0 -413
  106. package/dist/src/polar-capabilities.d.ts +0 -4
  107. package/dist/src/polar-capabilities.js +0 -389
  108. package/dist/src/polar-conformance.d.ts +0 -7
  109. package/dist/src/polar-conformance.js +0 -25
  110. package/dist/src/polar-connector.d.ts +0 -113
  111. package/dist/src/polar-connector.js +0 -146
  112. package/dist/src/polar-server.d.ts +0 -14
  113. package/dist/src/polar-server.js +0 -52
  114. package/dist/src/polar-twin.d.ts +0 -24
  115. package/dist/src/polar-twin.js +0 -941
  116. package/src/polar-budget.ts +0 -459
  117. package/src/polar-capabilities.ts +0 -448
  118. package/src/polar-conformance.ts +0 -33
  119. package/src/polar-connector.ts +0 -172
  120. package/src/polar-server.ts +0 -57
  121. package/src/polar-twin.ts +0 -938
@@ -0,0 +1,47 @@
1
+ // The World's doors (docs/contributing/architecture.md, "Doors, screens and the gap"), each declared in the manifest's
2
+ // `doors`: the organization's access tokens, as its settings page makes them (the API makes none), and the webhooks
3
+ // the World sent the application's server, as that server received them.
4
+ import { sha256 } from '@volter/world-core';
5
+ import { bodyOf, environment, secret } from "./shared.js";
6
+ /** An Organization Access Token as the settings page makes it (`polar_oat_…`, shown once): its name, scopes and
7
+ * expiration (none: it does not expire), kept by its SHA-256. */
8
+ // source: spec:/components/securitySchemes/oat "You can generate an **Organization Access Token** from your organization's settings."
9
+ async function makeToken(ctx, comment, expiresInDays) {
10
+ const id = ctx.mint('_access_token');
11
+ const token = await secret(ctx, 'polar_oat_', `access-token:${id}`);
12
+ await ctx.record('_access_token', { comment, _environment: environment(ctx), _sha256: sha256(token), created_at: ctx.occurredAt, expires_at: expiresInDays === null ? null : new Date(Date.parse(ctx.occurredAt) + expiresInDays * 86_400_000).toISOString(), deleted: false }, id);
13
+ return { token, id };
14
+ }
15
+ /** POST /_twin/access-tokens {comment, expires_in_days?}: an Organization Access Token made on the settings page. */
16
+ export async function accessTokens(ctx) {
17
+ const b = bodyOf(ctx);
18
+ const days = typeof b.expires_in_days === 'number' ? b.expires_in_days : null;
19
+ return Response.json(await makeToken(ctx, typeof b.comment === 'string' ? b.comment : 'token', days), { status: 201 });
20
+ }
21
+ /** DELETE /_twin/access-tokens/{n}: a token revoked on the settings page. */
22
+ export async function revokeToken(ctx) {
23
+ const id = String(ctx.call.params.n);
24
+ if (!ctx.rowsRaw('_access_token').some((t) => t.id === id && t.deleted !== true))
25
+ return Response.json({ error: 'no such token' }, { status: 404 });
26
+ await ctx.record('_access_token', { deleted: true }, id);
27
+ return new Response(null, { status: 204 });
28
+ }
29
+ /** POST /_twin/app-credentials: the access token an application holds, as the runtime issues it (the descriptor's
30
+ * credentialDoor). */
31
+ export async function appCredentials(ctx) {
32
+ // the application's one token, made the first time the runtime asks and the same at every boot after
33
+ const token = await secret(ctx, 'polar_oat_', `access-token:app:${environment(ctx)}`);
34
+ if (!ctx.rowsRaw('_access_token', { withDeleted: true }).some((t) => t.id === `oat_app_${environment(ctx)}` && t._sha256 === sha256(token))) {
35
+ await ctx.record('_access_token', { comment: 'world', _environment: environment(ctx), _sha256: sha256(token), created_at: ctx.occurredAt, expires_at: null, deleted: false }, `oat_app_${environment(ctx)}`);
36
+ }
37
+ return Response.json({ access_token: token }, { status: 201 });
38
+ }
39
+ /** GET /_twin/deliveries[?to=<url>][&type=<event>]: every webhook Polar sent (the kernel's record of each delivery, in
40
+ * the order sent): what the application's server was told, and when. */
41
+ export async function deliveries(ctx) {
42
+ const q = new URL(ctx.call.request.url).searchParams;
43
+ const rows = ctx.rowsRaw('_webhook_delivery')
44
+ .filter((d) => (q.get('to') === null || d.url === q.get('to')) && (q.get('type') === null || d.event_type === q.get('type')))
45
+ .sort((a, b) => Number(a.sent_at) - Number(b.sent_at));
46
+ return Response.json({ data: rows.map((d) => ({ url: d.url, type: d.event_type, sent_at: d.sent_at, headers: d.headers, body: JSON.parse(String(d.body)) })) });
47
+ }
@@ -0,0 +1,12 @@
1
+ import type { EventWrite, HandlerContext, WriteHookContext } from '@volter/world-core';
2
+ /** `POST /v1/events/ingest`: a batch of events. An event's `external_id` is the application's id for it: a second
3
+ * ingest of it is a duplicate, not a second event. An `external_customer_id` names the customer by the application's
4
+ * id; it does not create an unresolved customer. */
5
+ export declare function events_ingest(ctx: HandlerContext): Promise<Response>;
6
+ /** `GET /v1/events/`: the organization's events, newest first, by customer (Polar's id or the application's), name,
7
+ * source, a meter's filter, or a time window. */
8
+ export declare function events_list(ctx: HandlerContext): Promise<Response>;
9
+ /** A webhook's `data`: the written object as the API answers it. */
10
+ export declare function data(ctx: WriteHookContext, write: EventWrite): Record<string, unknown>;
11
+ /** Private routing value: sandbox endpoints only receive sandbox writes. */
12
+ export declare function values(ctx: WriteHookContext): Record<string, unknown>;
@@ -0,0 +1,60 @@
1
+ import { rowOf, admits, among, bodyOf, eventFields, environment, CHECKOUT, checkoutView, customerBy, EVENT, eventView, invalid, METER, missing, newest, newId, notFound, orderView, rowsOf, } from "./shared.js";
2
+ /** `POST /v1/events/ingest`: a batch of events. An event's `external_id` is the application's id for it: a second
3
+ * ingest of it is a duplicate, not a second event. An `external_customer_id` names the customer by the application's
4
+ * id; it does not create an unresolved customer. */
5
+ // source: spec:events:ingest "Ingest batch of events."
6
+ export async function events_ingest(ctx) {
7
+ const events = bodyOf(ctx).events;
8
+ if (!Array.isArray(events))
9
+ return missing('events');
10
+ // Validate the complete batch before mutating it. External identities may remain unresolved.
11
+ // source: spec:events:ingest "Validation Error"
12
+ for (const [i, e] of events.entries()) {
13
+ if (!e || typeof e.name !== 'string')
14
+ return invalid(['events', i, 'name'], 'Field required', 'missing');
15
+ if (e.customer_id !== undefined && !customerBy(ctx, { id: e.customer_id }))
16
+ return invalid(['events', i, 'customer_id'], 'Customer does not exist.');
17
+ }
18
+ let inserted = 0;
19
+ let duplicates = 0;
20
+ for (const e of events) {
21
+ if (e.external_id != null && rowsOf(ctx, '_event_key').some((x) => x.external_id === e.external_id)) {
22
+ duplicates += 1;
23
+ continue;
24
+ }
25
+ const customer = e.customer_id !== undefined ? customerBy(ctx, { id: e.customer_id }) : e.external_customer_id !== undefined ? customerBy(ctx, { external: e.external_customer_id }) : undefined;
26
+ const id = newId(ctx, EVENT);
27
+ await ctx.write(EVENT, id, { ...eventFields(ctx, { id, timestamp: e.timestamp ?? ctx.occurredAt, name: e.name, customer_id: customer?.id ?? null, external_customer_id: e.external_customer_id ?? null, metadata: e.metadata ?? {} }), _environment: environment(ctx), _received_at: ctx.occurredAt }, 'event.ingest');
28
+ if (e.external_id != null)
29
+ await ctx.record('_event_key', { external_id: e.external_id, _environment: environment(ctx) });
30
+ inserted += 1;
31
+ }
32
+ return Response.json({ inserted, duplicates });
33
+ }
34
+ /** `GET /v1/events/`: the organization's events, newest first, by customer (Polar's id or the application's), name,
35
+ * source, a meter's filter, or a time window. */
36
+ // source: spec:events:list "List events."
37
+ export async function events_list(ctx) {
38
+ const meter = ctx.params.meter_id === undefined ? undefined : rowOf(ctx, METER, String(ctx.params.meter_id));
39
+ if (ctx.params.meter_id !== undefined && (!meter || meter.deleted === true))
40
+ return notFound('Meter');
41
+ // source: spec:events:list "Filter events after this timestamp."
42
+ const after = ctx.params.start_timestamp === undefined ? undefined : Date.parse(String(ctx.params.start_timestamp));
43
+ const before = ctx.params.end_timestamp === undefined ? undefined : Date.parse(String(ctx.params.end_timestamp));
44
+ const q = String(ctx.params.query ?? '').toLowerCase();
45
+ const rows = rowsOf(ctx, EVENT)
46
+ .filter((e) => among(ctx, 'customer_id', e.customer_id) && among(ctx, 'external_customer_id', e.external_customer_id) && among(ctx, 'name', e.name) && among(ctx, 'source', 'user'))
47
+ .filter((e) => !meter || admits(meter.filter, e))
48
+ .filter((e) => (after === undefined || Date.parse(String(e.timestamp)) > after) && (before === undefined || Date.parse(String(e.timestamp)) < before))
49
+ .filter((e) => q === '' || String(e.name).toLowerCase().includes(q))
50
+ .sort(newest('timestamp'));
51
+ return ctx.list(EVENT, rows.map((e) => eventView(ctx, e)));
52
+ }
53
+ /** A webhook's `data`: the written object as the API answers it. */
54
+ export function data(ctx, write) {
55
+ const id = String(write.body.id ?? '');
56
+ const row = rowOf(ctx, write.storedType, id) ?? write.body;
57
+ return write.storedType === CHECKOUT ? checkoutView(ctx, row) : orderView(ctx, row);
58
+ }
59
+ /** Private routing value: sandbox endpoints only receive sandbox writes. */
60
+ export function values(ctx) { return { '$environment': environment(ctx) }; }
@@ -0,0 +1,2 @@
1
+ import type { Handler } from '@volter/world-core';
2
+ export declare const polarSemantics: Record<string, Handler>;
@@ -0,0 +1,27 @@
1
+ import * as checkouts from "./checkouts.js";
2
+ import * as customer_sessions from "./customer-sessions.js";
3
+ import * as customers from "./customers.js";
4
+ import * as events from "./events.js";
5
+ import * as orders from "./orders.js";
6
+ import * as products from "./products.js";
7
+ import * as subscriptions from "./subscriptions.js";
8
+ import * as webhooks from "./webhooks.js";
9
+ export const polarSemantics = {
10
+ "checkouts:client_confirm": checkouts.checkouts_client_confirm,
11
+ "checkouts:client_get": checkouts.checkouts_client_get,
12
+ "checkouts:create": checkouts.checkouts_create,
13
+ "checkouts:get": checkouts.checkouts_get,
14
+ "checkouts:list": checkouts.checkouts_list,
15
+ "customer-sessions:create": customer_sessions.customer_sessions_create,
16
+ "customers:create": customers.customers_create,
17
+ "customers:get": customers.customers_get,
18
+ "customers:get_state_external": customers.customers_get_state_external,
19
+ "customers:list": customers.customers_list,
20
+ "events:ingest": events.events_ingest,
21
+ "events:list": events.events_list,
22
+ "orders:list": orders.orders_list,
23
+ "products:create": products.products_create,
24
+ "products:list": products.products_list,
25
+ "subscriptions:list": subscriptions.subscriptions_list,
26
+ "webhooks:create_webhook_endpoint": webhooks.webhooks_create_webhook_endpoint,
27
+ };
@@ -0,0 +1,4 @@
1
+ import type { HandlerContext } from '@volter/world-core';
2
+ /** `GET /v1/orders/`: the organization's orders, newest first, filtered by the checkout, customer, product,
3
+ * subscription or status named. */
4
+ export declare function orders_list(ctx: HandlerContext): Promise<Response>;
@@ -0,0 +1,11 @@
1
+ import { ORDER, orderView, rowsOf } from "./shared.js";
2
+ const FILTERS = ['checkout_id', 'customer_id', 'product_id', 'subscription_id', 'status'];
3
+ /** `GET /v1/orders/`: the organization's orders, newest first, filtered by the checkout, customer, product,
4
+ * subscription or status named. */
5
+ // source: spec:orders:list "List orders."
6
+ export async function orders_list(ctx) {
7
+ const rows = rowsOf(ctx, ORDER)
8
+ .filter((o) => FILTERS.every((k) => ctx.params[k] === undefined || [].concat(ctx.params[k]).map(String).includes(String(o[k]))))
9
+ .sort((a, b) => String(b.created_at).localeCompare(String(a.created_at)));
10
+ return ctx.list('Order', rows.map((o) => orderView(ctx, o)));
11
+ }
@@ -0,0 +1,5 @@
1
+ import type { HandlerContext } from '@volter/world-core';
2
+ /** `POST /v1/products/`: a product with its prices, each given an id. */
3
+ export declare function products_create(ctx: HandlerContext): Promise<Response>;
4
+ /** `GET /v1/products/`: filtered by archived, recurring, a query over names, or a benefit they grant. */
5
+ export declare function products_list(ctx: HandlerContext): Promise<Response>;
@@ -0,0 +1,43 @@
1
+ import { rowOf, bodyOf, environment, productFields, priceView, invalid, missing, newId, PRODUCT, productView, rowsOf } from "./shared.js";
2
+ const AMOUNT_TYPES = new Set(['fixed', 'free', 'custom', 'metered_unit', 'seat_based']);
3
+ /** `POST /v1/products/`: a product with its prices, each given an id. */
4
+ // source: spec:products:create "Create a product."
5
+ export async function products_create(ctx) {
6
+ const body = bodyOf(ctx);
7
+ if (typeof body.name !== 'string' || body.name === '')
8
+ return missing('name');
9
+ const prices = Array.isArray(body.prices) ? body.prices : [];
10
+ if (prices.length === 0)
11
+ return missing('prices');
12
+ const bad = prices.findIndex((p) => !AMOUNT_TYPES.has(String(p.amount_type)));
13
+ if (bad >= 0)
14
+ return invalid(['prices', bad, 'amount_type'], 'Input tag does not match any of the expected tags', 'union_tag_invalid');
15
+ const id = newId(ctx, PRODUCT);
16
+ const stored = [];
17
+ for (const price of prices) {
18
+ const priceId = ctx.mint('_price');
19
+ await ctx.record('_price', {}, priceId);
20
+ stored.push(priceView(ctx, { ...price, id: priceId }, { ...body, id, created_at: ctx.occurredAt }));
21
+ }
22
+ await ctx.write(PRODUCT, id, { ...productFields(ctx, {
23
+ id, created_at: ctx.occurredAt, modified_at: null, name: body.name, description: body.description ?? null, recurring_interval: body.recurring_interval ?? null,
24
+ recurring_interval_count: body.recurring_interval_count ?? (body.recurring_interval ? 1 : null), trial_interval: body.trial_interval ?? null,
25
+ trial_interval_count: body.trial_interval_count ?? null, visibility: body.visibility ?? 'public', is_archived: false, prices: stored, benefit_ids: [], metadata: body.metadata ?? {},
26
+ }), _environment: environment(ctx) }, 'product.create');
27
+ return Response.json(productView(ctx, rowOf(ctx, PRODUCT, id)), { status: 201 });
28
+ }
29
+ /** `GET /v1/products/`: filtered by archived, recurring, a query over names, or a benefit they grant. */
30
+ // source: spec:products:list "List products."
31
+ export async function products_list(ctx) {
32
+ const flag = (v) => (v === undefined ? undefined : String(v) === 'true');
33
+ const archived = flag(ctx.params.is_archived);
34
+ const recurring = flag(ctx.params.is_recurring);
35
+ const q = String(ctx.params.query ?? '').toLowerCase();
36
+ const rows = rowsOf(ctx, PRODUCT)
37
+ .filter((p) => archived === undefined || Boolean(p.is_archived) === archived)
38
+ .filter((p) => recurring === undefined || (p.recurring_interval != null) === recurring)
39
+ .filter((p) => q === '' || String(p.name).toLowerCase().includes(q))
40
+ .filter((p) => ctx.params.benefit_id === undefined || (p.benefit_ids ?? []).includes(String(ctx.params.benefit_id)))
41
+ .sort((a, b) => String(b.created_at).localeCompare(String(a.created_at)));
42
+ return ctx.list(PRODUCT, rows.map((p) => productView(ctx, p)));
43
+ }
@@ -0,0 +1,82 @@
1
+ import type { HandlerContext, WriteHookContext } from '@volter/world-core';
2
+ export type Row = Record<string, unknown>;
3
+ type Reader = Pick<HandlerContext, 'row' | 'rowsRaw' | 'crypto' | 'own' | 'call'> | Pick<WriteHookContext, 'row' | 'rowsRaw' | 'crypto' | 'own' | 'call'>;
4
+ /** A customer by its id or its external id. */
5
+ export declare function customerBy(ctx: Reader, key: {
6
+ id?: unknown;
7
+ external?: unknown;
8
+ }): Row | undefined;
9
+ export declare const ORGANIZATION = "organization";
10
+ export declare const CUSTOMER = "customer";
11
+ export declare const PRODUCT = "product";
12
+ export declare const CHECKOUT = "checkout";
13
+ export declare const SUBSCRIPTION = "subscription";
14
+ export declare const ORDER = "order";
15
+ export declare const EVENT = "event";
16
+ export declare const METER = "meter";
17
+ export declare const SESSION = "customer_session";
18
+ export declare const ENDPOINT = "webhook_endpoint";
19
+ /** Where Polar's hosted pages are: the checkout (`buy.polar.sh`) and the portal (`polar.sh`), rewritten to the twin. */
20
+ export declare const CHECKOUT_ORIGIN = "https://buy.polar.sh";
21
+ export declare const PORTAL_ORIGIN = "https://polar.sh";
22
+ /** Polar's error body: `{ error: <kind>, detail }`. */
23
+ export declare const fail: (status: number, error: string, detail: string) => Response;
24
+ export declare const notFound: (what: string) => Response;
25
+ /** FastAPI's 422, one error per field. */
26
+ export declare const invalid: (loc: Array<string | number>, msg: string, type?: string) => Response;
27
+ export declare const missing: (field: string) => Response;
28
+ export declare const bodyOf: (ctx: HandlerContext) => Row;
29
+ export declare const newId: (ctx: Pick<HandlerContext, "mint">, type: string) => string;
30
+ /** A secret of Polar's form (`polar_cst_…`, `polar_c_…`, `polar_whs_…`, `polar_oat_…`): its prefix and 43 letters and
31
+ * digits drawn from a secret the World holds for the seed (ctx.secret), so none is computed from the ids it names. */
32
+ export declare function secret(ctx: Pick<HandlerContext, 'secret'>, prefix: string, seed: string): Promise<string>;
33
+ /** The World's one organization: the one its token names. */
34
+ export declare const ORG_ID = "1dbfc517-0bbf-4301-9ba8-555ca42b9737";
35
+ export declare const orgId: (ctx: Pick<HandlerContext, "call">) => string;
36
+ export declare const organizationView: (ctx: Reader) => Row;
37
+ /** Whether a row's field is among the values a list's query names (one value or several), or the query names none. */
38
+ export declare const among: (ctx: Pick<HandlerContext, "params">, key: string, value: unknown) => boolean;
39
+ /** Newest first by a timestamp field. */
40
+ export declare const newest: (field: string) => (a: Row, b: Row) => number;
41
+ /** Stored rows without the kernel's bookkeeping. */
42
+ export declare const environment: (ctx: Pick<HandlerContext, "call">) => string;
43
+ export declare const rowsOf: (ctx: Reader, type: string) => Row[];
44
+ export declare const rowOf: (ctx: Reader, type: string, id: string) => Row | undefined;
45
+ /** The stored vendor shape; bookkeeping is private, including the environment boundary. */
46
+ export declare const vendorFields: (ctx: Pick<HandlerContext, "own">, row: Row) => Row;
47
+ export declare const customerView: (ctx: Reader, c: Row) => Row;
48
+ export declare const productView: (ctx: Reader, p: Row) => Row;
49
+ export declare const subscriptionView: (ctx: Reader, s: Row) => Row;
50
+ export declare const orderView: (ctx: Reader, o: Row) => Row;
51
+ export declare const eventView: (ctx: Reader, e: Row) => Row;
52
+ export declare const checkoutView: (ctx: Reader, c: Row) => Row;
53
+ export declare function customerFields(ctx: Reader, c: Row): Row;
54
+ /** A price as the schema of its amount type requires (ProductPriceFixed, ProductPriceFree, ProductPriceCustom,
55
+ * ProductPriceMeteredUnit). */
56
+ export declare function priceView(ctx: Reader, p: Row, product: Row): Row;
57
+ export declare function productFields(ctx: Reader, p: Row): Row;
58
+ export declare function subscriptionFields(ctx: Reader, s: Row): Row;
59
+ export declare function orderFields(ctx: Reader, o: Row): Row;
60
+ /** A usage event as the API answers it (UserEvent): with its customer. */
61
+ export declare function eventFields(ctx: Reader, e: Row): Row;
62
+ export declare function checkoutFields(ctx: Reader, c: Row): Row;
63
+ /** Whether a meter's filter admits an event: clauses on `name`, `source` or a metadata key, joined by the filter's
64
+ * conjunction, nested filters among them. */
65
+ export declare function admits(filter: Row | undefined, e: Row): boolean;
66
+ /** A meter's aggregation over the events it admits: a count, or the sum, max, min or average of a metadata property. */
67
+ export declare function aggregate(agg: Row | undefined, events: Row[]): number;
68
+ /** A customer's meter: consumed (the fold over its events), credited (its meter-credit grants), and the balance. */
69
+ export declare function customerMeter(ctx: Reader, customerId: string, meter: Row): {
70
+ consumed: number;
71
+ credited: number;
72
+ balance: number;
73
+ };
74
+ /** A customer's state: its active subscriptions, granted benefits and meters. */
75
+ export declare function customerState(ctx: HandlerContext, c: Row): Promise<Row>;
76
+ export declare function makeOrder(ctx: HandlerContext, source: Row, reason: string, period?: {
77
+ start: string;
78
+ end: string;
79
+ }): Promise<void>;
80
+ export declare function addInterval(at: string, interval: string, count: number): string;
81
+ export declare function createSession(ctx: HandlerContext, customer: Row, returnUrl?: unknown): Promise<Row>;
82
+ export {};