@bunizao/contracts 0.23.0 → 0.26.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 +6 -0
- package/dist/analytics.d.ts +103 -0
- package/dist/analytics.js +25 -1
- package/dist/index.js +24 -0
- package/dist/runtime/env.d.ts +31 -0
- package/dist/runtime/json-response.d.ts +5 -0
- package/dist/runtime/query.d.ts +5 -0
- package/dist/runtime.d.ts +7 -0
- package/dist/runtime.js +138 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -16,5 +16,11 @@ npm install @bunizao/contracts@0.1.0
|
|
|
16
16
|
The package exports the complete contract from `@bunizao/contracts` and the
|
|
17
17
|
feature modules from `@bunizao/contracts/{analytics,admin,content,listening,mood,notify,routes,telegram-ops}`.
|
|
18
18
|
|
|
19
|
+
`@bunizao/contracts/runtime` is the one subpath that ships code rather than
|
|
20
|
+
types: the env readers (`createEnvReaders`, `readRuntimeValue`,
|
|
21
|
+
`setRuntimeEnvSource`), the JSON response helpers and the query parsers both
|
|
22
|
+
Workers run. Bind the env readers to the bundle's own `import.meta.env` once,
|
|
23
|
+
in a local module, since bundlers only replace it in application source.
|
|
24
|
+
|
|
19
25
|
The package is source-available but not licensed for redistribution. See
|
|
20
26
|
[`LICENSE`](LICENSE) for the applicable terms.
|
package/dist/analytics.d.ts
CHANGED
|
@@ -359,3 +359,106 @@ export interface SiteAnalyticsReportResult {
|
|
|
359
359
|
}> | null;
|
|
360
360
|
notices: string[];
|
|
361
361
|
}
|
|
362
|
+
export declare const SITE_EXPLORE_ENDPOINT: '/api/analytics/explore';
|
|
363
|
+
export declare const SITE_EXPLORE_VIEWS: readonly ['traffic', 'decoy'];
|
|
364
|
+
export type SiteExploreView = typeof SITE_EXPLORE_VIEWS[number];
|
|
365
|
+
export declare const SITE_EXPLORE_RANGES: readonly ['24h', '7d', '30d', '90d'];
|
|
366
|
+
export type SiteExploreRange = typeof SITE_EXPLORE_RANGES[number];
|
|
367
|
+
export declare const SITE_EXPLORE_CLASSES: readonly ['human', 'bot', 'owner', 'all'];
|
|
368
|
+
export type SiteExploreClass = typeof SITE_EXPLORE_CLASSES[number];
|
|
369
|
+
export declare const SITE_EXPLORE_PARTS: readonly ['summary', 'panel', 'clicks', 'log'];
|
|
370
|
+
export type SiteExplorePart = typeof SITE_EXPLORE_PARTS[number];
|
|
371
|
+
export declare const SITE_EXPLORE_DIMS: {
|
|
372
|
+
readonly traffic: readonly ['page', 'section', 'referrer', 'channel', 'utm', 'country', 'city', 'device', 'browser', 'os', 'visitor'];
|
|
373
|
+
readonly decoy: readonly ['client', 'kind', 'reason', 'ua', 'path', 'network', 'country'];
|
|
374
|
+
};
|
|
375
|
+
export type SiteExploreDim<V extends SiteExploreView = SiteExploreView> = typeof SITE_EXPLORE_DIMS[V][number];
|
|
376
|
+
export declare const SITE_EXPLORE_METRICS: {
|
|
377
|
+
readonly traffic: readonly ['visitors', 'views', 'engagement', 'dwell'];
|
|
378
|
+
readonly decoy: readonly ['hits', 'clients', 'networks', 'named'];
|
|
379
|
+
};
|
|
380
|
+
export type SiteExploreMetric<V extends SiteExploreView = SiteExploreView> = typeof SITE_EXPLORE_METRICS[V][number];
|
|
381
|
+
export declare const SITE_EXPLORE_PANEL_LIMIT = 100;
|
|
382
|
+
export declare const SITE_EXPLORE_EMPTY = "(none)";
|
|
383
|
+
export interface SiteExploreSeries {
|
|
384
|
+
totals: Record<string, number>;
|
|
385
|
+
points: Record<string, number[]>;
|
|
386
|
+
}
|
|
387
|
+
export interface SiteExploreSummary {
|
|
388
|
+
view: SiteExploreView;
|
|
389
|
+
range: SiteExploreRange;
|
|
390
|
+
timezone: 'Australia/Melbourne';
|
|
391
|
+
bucket: 'hour' | 'day';
|
|
392
|
+
buckets: string[];
|
|
393
|
+
from: string;
|
|
394
|
+
to: string;
|
|
395
|
+
previousFrom: string | null;
|
|
396
|
+
current: SiteExploreSeries;
|
|
397
|
+
previous: SiteExploreSeries | null;
|
|
398
|
+
notices: Array<'compare_beyond_retention'>;
|
|
399
|
+
}
|
|
400
|
+
export interface SiteExploreRow {
|
|
401
|
+
key: string;
|
|
402
|
+
label: string;
|
|
403
|
+
count: number;
|
|
404
|
+
visitors: number;
|
|
405
|
+
}
|
|
406
|
+
export interface SiteExplorePanel {
|
|
407
|
+
dim: SiteExploreDim;
|
|
408
|
+
rows: SiteExploreRow[];
|
|
409
|
+
more: boolean;
|
|
410
|
+
}
|
|
411
|
+
export interface SiteExploreClickRow {
|
|
412
|
+
name: string;
|
|
413
|
+
label: string;
|
|
414
|
+
href: string;
|
|
415
|
+
clicks: number;
|
|
416
|
+
visitors: number;
|
|
417
|
+
}
|
|
418
|
+
export interface SiteExploreClicks {
|
|
419
|
+
rows: SiteExploreClickRow[];
|
|
420
|
+
more: boolean;
|
|
421
|
+
ignored: SiteExploreDim<'traffic'>[];
|
|
422
|
+
}
|
|
423
|
+
export interface SiteExploreVisit {
|
|
424
|
+
at: string;
|
|
425
|
+
until: string;
|
|
426
|
+
visitor: string;
|
|
427
|
+
session: string;
|
|
428
|
+
class: SiteAnalyticsTrafficClass;
|
|
429
|
+
country: string;
|
|
430
|
+
city: string;
|
|
431
|
+
network: string;
|
|
432
|
+
org: string;
|
|
433
|
+
device: string;
|
|
434
|
+
browser: string;
|
|
435
|
+
os: string;
|
|
436
|
+
entry: string;
|
|
437
|
+
referrer: string;
|
|
438
|
+
channel: string;
|
|
439
|
+
pages: number;
|
|
440
|
+
dwellMs: number;
|
|
441
|
+
interactions: number;
|
|
442
|
+
}
|
|
443
|
+
export interface SiteExploreDecoyHit {
|
|
444
|
+
at: string;
|
|
445
|
+
reason: string;
|
|
446
|
+
kind: string;
|
|
447
|
+
client: string;
|
|
448
|
+
ua: string;
|
|
449
|
+
path: string;
|
|
450
|
+
network: string;
|
|
451
|
+
org: string;
|
|
452
|
+
country: string;
|
|
453
|
+
method: string;
|
|
454
|
+
}
|
|
455
|
+
export type SiteExploreLog = {
|
|
456
|
+
view: 'traffic';
|
|
457
|
+
rows: SiteExploreVisit[];
|
|
458
|
+
more: boolean;
|
|
459
|
+
next: string | null;
|
|
460
|
+
} | {
|
|
461
|
+
view: 'decoy';
|
|
462
|
+
rows: SiteExploreDecoyHit[];
|
|
463
|
+
more: boolean;
|
|
464
|
+
};
|
package/dist/analytics.js
CHANGED
|
@@ -36,6 +36,21 @@ var SITE_ANALYTICS_SURFACES = [
|
|
|
36
36
|
"other"
|
|
37
37
|
];
|
|
38
38
|
var SITE_ANALYTICS_REPORTS = ["overview", "pages", "clicks", "sources", "audience", "quality", "log", "visitor"];
|
|
39
|
+
var SITE_EXPLORE_ENDPOINT = "/api/analytics/explore";
|
|
40
|
+
var SITE_EXPLORE_VIEWS = ["traffic", "decoy"];
|
|
41
|
+
var SITE_EXPLORE_RANGES = ["24h", "7d", "30d", "90d"];
|
|
42
|
+
var SITE_EXPLORE_CLASSES = ["human", "bot", "owner", "all"];
|
|
43
|
+
var SITE_EXPLORE_PARTS = ["summary", "panel", "clicks", "log"];
|
|
44
|
+
var SITE_EXPLORE_DIMS = {
|
|
45
|
+
traffic: ["page", "section", "referrer", "channel", "utm", "country", "city", "device", "browser", "os", "visitor"],
|
|
46
|
+
decoy: ["client", "kind", "reason", "ua", "path", "network", "country"]
|
|
47
|
+
};
|
|
48
|
+
var SITE_EXPLORE_METRICS = {
|
|
49
|
+
traffic: ["visitors", "views", "engagement", "dwell"],
|
|
50
|
+
decoy: ["hits", "clients", "networks", "named"]
|
|
51
|
+
};
|
|
52
|
+
var SITE_EXPLORE_PANEL_LIMIT = 100;
|
|
53
|
+
var SITE_EXPLORE_EMPTY = "(none)";
|
|
39
54
|
export {
|
|
40
55
|
BLOG_ANALYTICS_ARTICLE_ENDPOINT,
|
|
41
56
|
BLOG_ANALYTICS_COMPLETION_SCROLL_DEPTH,
|
|
@@ -53,5 +68,14 @@ export {
|
|
|
53
68
|
SITE_ANALYTICS_REPORTS,
|
|
54
69
|
SITE_ANALYTICS_REPORT_ENDPOINT,
|
|
55
70
|
SITE_ANALYTICS_SESSION_IDLE_MS,
|
|
56
|
-
SITE_ANALYTICS_SURFACES
|
|
71
|
+
SITE_ANALYTICS_SURFACES,
|
|
72
|
+
SITE_EXPLORE_CLASSES,
|
|
73
|
+
SITE_EXPLORE_DIMS,
|
|
74
|
+
SITE_EXPLORE_EMPTY,
|
|
75
|
+
SITE_EXPLORE_ENDPOINT,
|
|
76
|
+
SITE_EXPLORE_METRICS,
|
|
77
|
+
SITE_EXPLORE_PANEL_LIMIT,
|
|
78
|
+
SITE_EXPLORE_PARTS,
|
|
79
|
+
SITE_EXPLORE_RANGES,
|
|
80
|
+
SITE_EXPLORE_VIEWS
|
|
57
81
|
};
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,21 @@ var SITE_ANALYTICS_SURFACES = [
|
|
|
36
36
|
"other"
|
|
37
37
|
];
|
|
38
38
|
var SITE_ANALYTICS_REPORTS = ["overview", "pages", "clicks", "sources", "audience", "quality", "log", "visitor"];
|
|
39
|
+
var SITE_EXPLORE_ENDPOINT = "/api/analytics/explore";
|
|
40
|
+
var SITE_EXPLORE_VIEWS = ["traffic", "decoy"];
|
|
41
|
+
var SITE_EXPLORE_RANGES = ["24h", "7d", "30d", "90d"];
|
|
42
|
+
var SITE_EXPLORE_CLASSES = ["human", "bot", "owner", "all"];
|
|
43
|
+
var SITE_EXPLORE_PARTS = ["summary", "panel", "clicks", "log"];
|
|
44
|
+
var SITE_EXPLORE_DIMS = {
|
|
45
|
+
traffic: ["page", "section", "referrer", "channel", "utm", "country", "city", "device", "browser", "os", "visitor"],
|
|
46
|
+
decoy: ["client", "kind", "reason", "ua", "path", "network", "country"]
|
|
47
|
+
};
|
|
48
|
+
var SITE_EXPLORE_METRICS = {
|
|
49
|
+
traffic: ["visitors", "views", "engagement", "dwell"],
|
|
50
|
+
decoy: ["hits", "clients", "networks", "named"]
|
|
51
|
+
};
|
|
52
|
+
var SITE_EXPLORE_PANEL_LIMIT = 100;
|
|
53
|
+
var SITE_EXPLORE_EMPTY = "(none)";
|
|
39
54
|
// src/admin.ts
|
|
40
55
|
var ADMIN_COMMENT_REJECT_REASONS = ["spam", "promotional", "abuse", "off_topic", "personal_info"];
|
|
41
56
|
var ADMIN_ACTIVITY_EVENTS = [
|
|
@@ -408,6 +423,15 @@ export {
|
|
|
408
423
|
SITE_ANALYTICS_REPORT_ENDPOINT,
|
|
409
424
|
SITE_ANALYTICS_SESSION_IDLE_MS,
|
|
410
425
|
SITE_ANALYTICS_SURFACES,
|
|
426
|
+
SITE_EXPLORE_CLASSES,
|
|
427
|
+
SITE_EXPLORE_DIMS,
|
|
428
|
+
SITE_EXPLORE_EMPTY,
|
|
429
|
+
SITE_EXPLORE_ENDPOINT,
|
|
430
|
+
SITE_EXPLORE_METRICS,
|
|
431
|
+
SITE_EXPLORE_PANEL_LIMIT,
|
|
432
|
+
SITE_EXPLORE_PARTS,
|
|
433
|
+
SITE_EXPLORE_RANGES,
|
|
434
|
+
SITE_EXPLORE_VIEWS,
|
|
411
435
|
SUBSCRIPTION_SOURCES,
|
|
412
436
|
TELEGRAM_OPS_BASE_PATH,
|
|
413
437
|
TELEGRAM_OPS_BROADCASTS_PATH,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime environment readers shared by the public site and the API Worker.
|
|
3
|
+
*
|
|
4
|
+
* A value is looked up in this order: `process.env` (local shells and tests),
|
|
5
|
+
* the build-time env the consumer binds through `createEnvReaders`, then the
|
|
6
|
+
* request-time Worker env: `locals.env`, `locals.runtime.env`, and finally the
|
|
7
|
+
* env a Worker entrypoint registered with `setRuntimeEnvSource` for code that
|
|
8
|
+
* runs without request locals (queues, crons, webhooks).
|
|
9
|
+
*
|
|
10
|
+
* This module never touches `import.meta.env` itself: bundlers only replace it
|
|
11
|
+
* in application source, so each consumer passes its own build env in.
|
|
12
|
+
*/
|
|
13
|
+
export type EnvSource = Record<string, unknown>;
|
|
14
|
+
export interface RuntimeEnvLocals {
|
|
15
|
+
runtime?: {
|
|
16
|
+
env?: EnvSource;
|
|
17
|
+
};
|
|
18
|
+
env?: EnvSource;
|
|
19
|
+
}
|
|
20
|
+
export declare function setRuntimeEnvSource(env: EnvSource): void;
|
|
21
|
+
export declare function readRuntimeEnvSource(locals: unknown): EnvSource | undefined;
|
|
22
|
+
export declare function readRuntimeValue(locals: unknown, name: string): string | undefined;
|
|
23
|
+
export interface EnvReaders {
|
|
24
|
+
readOptionalEnv(locals: unknown, name: string, buildEnv?: EnvSource): string | undefined;
|
|
25
|
+
readEnv(locals: unknown, name: string, buildEnv?: EnvSource): string;
|
|
26
|
+
readPublicEnv(locals: unknown, name: string, buildEnv?: EnvSource): string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Binds the readers to a consumer's build-time env, usually `import.meta.env`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createEnvReaders(defaultBuildEnv: EnvSource): EnvReaders;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function json(status: number, data: unknown, headers?: HeadersInit): Response;
|
|
2
|
+
export declare function jsonOk(data: unknown, headers?: HeadersInit): Response;
|
|
3
|
+
export declare function jsonError(status: number, error: string, headers?: HeadersInit, extras?: Record<string, unknown>): Response;
|
|
4
|
+
export declare function jsonBadRequest(error: string, headers?: HeadersInit, extras?: Record<string, unknown>): Response;
|
|
5
|
+
export declare function jsonTooManyRequests(headers?: HeadersInit): Response;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function readCursorQuery(url: URL, name: string): string;
|
|
2
|
+
export declare function isValidCursor(value: string): boolean;
|
|
3
|
+
export declare function readIntQuery(url: URL, name: string): number | null;
|
|
4
|
+
export declare function readEnumQuery<T extends string>(url: URL, name: string, allowedValues: readonly T[], defaultValue: T): T;
|
|
5
|
+
export declare function readBooleanFlag(url: URL, name: string, defaultValue?: boolean): boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime helpers both Workers execute: env lookup, JSON responses and query
|
|
3
|
+
* parsing. Everything else in this package is types and constants.
|
|
4
|
+
*/
|
|
5
|
+
export { createEnvReaders, readRuntimeEnvSource, readRuntimeValue, setRuntimeEnvSource, type EnvReaders, type EnvSource, type RuntimeEnvLocals, } from './runtime/env';
|
|
6
|
+
export { json, jsonBadRequest, jsonError, jsonOk, jsonTooManyRequests, } from './runtime/json-response';
|
|
7
|
+
export { isValidCursor, readBooleanFlag, readCursorQuery, readEnumQuery, readIntQuery, } from './runtime/query';
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// src/runtime/env.ts
|
|
2
|
+
function record(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
4
|
+
}
|
|
5
|
+
function readValue(source, name) {
|
|
6
|
+
const raw = source?.[name];
|
|
7
|
+
if (typeof raw !== "string") {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const value = raw.trim();
|
|
11
|
+
return value ? value : undefined;
|
|
12
|
+
}
|
|
13
|
+
function readWorkerEnv() {
|
|
14
|
+
return record(globalThis.__BUXX_RUNTIME_ENV__);
|
|
15
|
+
}
|
|
16
|
+
function setRuntimeEnvSource(env) {
|
|
17
|
+
globalThis.__BUXX_RUNTIME_ENV__ = env;
|
|
18
|
+
}
|
|
19
|
+
function readRuntimeEnvSource(locals) {
|
|
20
|
+
const localRecord = record(locals);
|
|
21
|
+
const directEnv = record(localRecord.env);
|
|
22
|
+
if (Object.keys(directEnv).length > 0) {
|
|
23
|
+
return directEnv;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const runtimeEnv = record(record(localRecord.runtime).env);
|
|
27
|
+
if (Object.keys(runtimeEnv).length > 0) {
|
|
28
|
+
return runtimeEnv;
|
|
29
|
+
}
|
|
30
|
+
} catch {}
|
|
31
|
+
const workerEnv = readWorkerEnv();
|
|
32
|
+
return Object.keys(workerEnv).length > 0 ? workerEnv : undefined;
|
|
33
|
+
}
|
|
34
|
+
function readRuntimeValue(locals, name) {
|
|
35
|
+
const localRecord = record(locals);
|
|
36
|
+
const directValue = readValue(record(localRecord.env), name);
|
|
37
|
+
if (directValue) {
|
|
38
|
+
return directValue;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const runtimeValue = readValue(record(record(localRecord.runtime).env), name);
|
|
42
|
+
if (runtimeValue) {
|
|
43
|
+
return runtimeValue;
|
|
44
|
+
}
|
|
45
|
+
} catch {}
|
|
46
|
+
return readValue(readWorkerEnv(), name);
|
|
47
|
+
}
|
|
48
|
+
function readProcessEnv(name) {
|
|
49
|
+
const processEnv = globalThis.process?.env;
|
|
50
|
+
return readValue(processEnv, name);
|
|
51
|
+
}
|
|
52
|
+
function createEnvReaders(defaultBuildEnv) {
|
|
53
|
+
const readOptionalEnv = (locals, name, buildEnv = defaultBuildEnv) => {
|
|
54
|
+
return readProcessEnv(name) ?? readValue(buildEnv, name) ?? readRuntimeValue(locals, name);
|
|
55
|
+
};
|
|
56
|
+
const readEnv = (locals, name, buildEnv = defaultBuildEnv) => {
|
|
57
|
+
return readOptionalEnv(locals, name, buildEnv) ?? "";
|
|
58
|
+
};
|
|
59
|
+
const readPublicEnv = (locals, name, buildEnv = defaultBuildEnv) => {
|
|
60
|
+
const publicName = name.startsWith("PUBLIC_") ? name : `PUBLIC_${name}`;
|
|
61
|
+
return readEnv(locals, publicName, buildEnv);
|
|
62
|
+
};
|
|
63
|
+
return { readOptionalEnv, readEnv, readPublicEnv };
|
|
64
|
+
}
|
|
65
|
+
// src/runtime/json-response.ts
|
|
66
|
+
function createJsonHeaders(headers) {
|
|
67
|
+
const next = new Headers(headers);
|
|
68
|
+
if (!next.has("Content-Type")) {
|
|
69
|
+
next.set("Content-Type", "application/json");
|
|
70
|
+
}
|
|
71
|
+
return next;
|
|
72
|
+
}
|
|
73
|
+
function json(status, data, headers) {
|
|
74
|
+
return new Response(JSON.stringify(data), {
|
|
75
|
+
status,
|
|
76
|
+
headers: createJsonHeaders(headers)
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function jsonOk(data, headers) {
|
|
80
|
+
return json(200, data, headers);
|
|
81
|
+
}
|
|
82
|
+
function jsonError(status, error, headers, extras) {
|
|
83
|
+
return json(status, { error, ...extras ?? {} }, headers);
|
|
84
|
+
}
|
|
85
|
+
function jsonBadRequest(error, headers, extras) {
|
|
86
|
+
return jsonError(400, error, headers, extras);
|
|
87
|
+
}
|
|
88
|
+
function jsonTooManyRequests(headers) {
|
|
89
|
+
return jsonError(429, "Too Many Requests", headers);
|
|
90
|
+
}
|
|
91
|
+
// src/runtime/query.ts
|
|
92
|
+
var CURSOR_PATTERN = /^\d{1,20}$/;
|
|
93
|
+
var INTEGER_PATTERN = /^-?\d+$/;
|
|
94
|
+
function readCursorQuery(url, name) {
|
|
95
|
+
return (url.searchParams.get(name) ?? "").trim();
|
|
96
|
+
}
|
|
97
|
+
function isValidCursor(value) {
|
|
98
|
+
return value === "" || CURSOR_PATTERN.test(value);
|
|
99
|
+
}
|
|
100
|
+
function readIntQuery(url, name) {
|
|
101
|
+
const value = (url.searchParams.get(name) ?? "").trim();
|
|
102
|
+
if (!value || !INTEGER_PATTERN.test(value)) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const parsed = Number.parseInt(value, 10);
|
|
106
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
107
|
+
}
|
|
108
|
+
function readEnumQuery(url, name, allowedValues, defaultValue) {
|
|
109
|
+
const value = (url.searchParams.get(name) ?? "").trim();
|
|
110
|
+
return allowedValues.includes(value) ? value : defaultValue;
|
|
111
|
+
}
|
|
112
|
+
function readBooleanFlag(url, name, defaultValue = false) {
|
|
113
|
+
const value = url.searchParams.get(name);
|
|
114
|
+
if (value === null) {
|
|
115
|
+
return defaultValue;
|
|
116
|
+
}
|
|
117
|
+
const normalized = value.trim().toLowerCase();
|
|
118
|
+
if (!normalized) {
|
|
119
|
+
return defaultValue;
|
|
120
|
+
}
|
|
121
|
+
return normalized !== "0" && normalized !== "false" && normalized !== "no" && normalized !== "off";
|
|
122
|
+
}
|
|
123
|
+
export {
|
|
124
|
+
createEnvReaders,
|
|
125
|
+
isValidCursor,
|
|
126
|
+
json,
|
|
127
|
+
jsonBadRequest,
|
|
128
|
+
jsonError,
|
|
129
|
+
jsonOk,
|
|
130
|
+
jsonTooManyRequests,
|
|
131
|
+
readBooleanFlag,
|
|
132
|
+
readCursorQuery,
|
|
133
|
+
readEnumQuery,
|
|
134
|
+
readIntQuery,
|
|
135
|
+
readRuntimeEnvSource,
|
|
136
|
+
readRuntimeValue,
|
|
137
|
+
setRuntimeEnvSource
|
|
138
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bunizao/contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Shared TypeScript contracts for buxx.me services and clients.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -83,6 +83,11 @@
|
|
|
83
83
|
"import": "./dist/routes.js",
|
|
84
84
|
"default": "./dist/routes.js"
|
|
85
85
|
},
|
|
86
|
+
"./runtime": {
|
|
87
|
+
"types": "./dist/runtime.d.ts",
|
|
88
|
+
"import": "./dist/runtime.js",
|
|
89
|
+
"default": "./dist/runtime.js"
|
|
90
|
+
},
|
|
86
91
|
"./telegram-ops": {
|
|
87
92
|
"types": "./dist/telegram-ops.d.ts",
|
|
88
93
|
"import": "./dist/telegram-ops.js",
|