@sakeetech/medusa-payment-viva 0.2.2

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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +816 -0
  3. package/dist/api/index.d.ts +15 -0
  4. package/dist/api/index.d.ts.map +1 -0
  5. package/dist/api/index.js +22 -0
  6. package/dist/api/index.js.map +1 -0
  7. package/dist/api/middlewares.d.ts +27 -0
  8. package/dist/api/middlewares.d.ts.map +1 -0
  9. package/dist/api/middlewares.js +62 -0
  10. package/dist/api/middlewares.js.map +1 -0
  11. package/dist/api/viva/admin/_admin-auth.d.ts +26 -0
  12. package/dist/api/viva/admin/_admin-auth.d.ts.map +1 -0
  13. package/dist/api/viva/admin/_admin-auth.js +49 -0
  14. package/dist/api/viva/admin/_admin-auth.js.map +1 -0
  15. package/dist/api/viva/admin/_mode-gate.d.ts +28 -0
  16. package/dist/api/viva/admin/_mode-gate.d.ts.map +1 -0
  17. package/dist/api/viva/admin/_mode-gate.js +45 -0
  18. package/dist/api/viva/admin/_mode-gate.js.map +1 -0
  19. package/dist/api/viva/admin/connected-accounts/[id]/reconcile/route.d.ts +21 -0
  20. package/dist/api/viva/admin/connected-accounts/[id]/reconcile/route.d.ts.map +1 -0
  21. package/dist/api/viva/admin/connected-accounts/[id]/reconcile/route.js +93 -0
  22. package/dist/api/viva/admin/connected-accounts/[id]/reconcile/route.js.map +1 -0
  23. package/dist/api/viva/admin/connected-accounts/[id]/route.d.ts +18 -0
  24. package/dist/api/viva/admin/connected-accounts/[id]/route.d.ts.map +1 -0
  25. package/dist/api/viva/admin/connected-accounts/[id]/route.js +59 -0
  26. package/dist/api/viva/admin/connected-accounts/[id]/route.js.map +1 -0
  27. package/dist/api/viva/admin/connected-accounts/[id]/sources/route.d.ts +34 -0
  28. package/dist/api/viva/admin/connected-accounts/[id]/sources/route.d.ts.map +1 -0
  29. package/dist/api/viva/admin/connected-accounts/[id]/sources/route.js +234 -0
  30. package/dist/api/viva/admin/connected-accounts/[id]/sources/route.js.map +1 -0
  31. package/dist/api/viva/admin/connected-accounts/route.d.ts +19 -0
  32. package/dist/api/viva/admin/connected-accounts/route.d.ts.map +1 -0
  33. package/dist/api/viva/admin/connected-accounts/route.js +78 -0
  34. package/dist/api/viva/admin/connected-accounts/route.js.map +1 -0
  35. package/dist/api/viva/internal/auth-status/route.d.ts +19 -0
  36. package/dist/api/viva/internal/auth-status/route.d.ts.map +1 -0
  37. package/dist/api/viva/internal/auth-status/route.js +91 -0
  38. package/dist/api/viva/internal/auth-status/route.js.map +1 -0
  39. package/dist/api/viva/internal/metrics/route.d.ts +13 -0
  40. package/dist/api/viva/internal/metrics/route.d.ts.map +1 -0
  41. package/dist/api/viva/internal/metrics/route.js +48 -0
  42. package/dist/api/viva/internal/metrics/route.js.map +1 -0
  43. package/dist/api/viva/webhook/health/route.d.ts +16 -0
  44. package/dist/api/viva/webhook/health/route.d.ts.map +1 -0
  45. package/dist/api/viva/webhook/health/route.js +27 -0
  46. package/dist/api/viva/webhook/health/route.js.map +1 -0
  47. package/dist/api/viva/webhook/route.d.ts +57 -0
  48. package/dist/api/viva/webhook/route.d.ts.map +1 -0
  49. package/dist/api/viva/webhook/route.js +269 -0
  50. package/dist/api/viva/webhook/route.js.map +1 -0
  51. package/dist/cli/bin.d.ts +12 -0
  52. package/dist/cli/bin.d.ts.map +1 -0
  53. package/dist/cli/bin.js +78 -0
  54. package/dist/cli/bin.js.map +1 -0
  55. package/dist/cli/index.d.ts +12 -0
  56. package/dist/cli/index.d.ts.map +1 -0
  57. package/dist/cli/index.js +14 -0
  58. package/dist/cli/index.js.map +1 -0
  59. package/dist/cli/plan.d.ts +51 -0
  60. package/dist/cli/plan.d.ts.map +1 -0
  61. package/dist/cli/plan.js +128 -0
  62. package/dist/cli/plan.js.map +1 -0
  63. package/dist/cli/register-webhooks.d.ts +54 -0
  64. package/dist/cli/register-webhooks.d.ts.map +1 -0
  65. package/dist/cli/register-webhooks.js +366 -0
  66. package/dist/cli/register-webhooks.js.map +1 -0
  67. package/dist/cli/types.d.ts +62 -0
  68. package/dist/cli/types.d.ts.map +1 -0
  69. package/dist/cli/types.js +12 -0
  70. package/dist/cli/types.js.map +1 -0
  71. package/dist/config.d.ts +158 -0
  72. package/dist/config.d.ts.map +1 -0
  73. package/dist/config.js +236 -0
  74. package/dist/config.js.map +1 -0
  75. package/dist/index.d.ts +21 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +29 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/loaders/viva-oauth2-strategy.d.ts +26 -0
  80. package/dist/loaders/viva-oauth2-strategy.d.ts.map +1 -0
  81. package/dist/loaders/viva-oauth2-strategy.js +58 -0
  82. package/dist/loaders/viva-oauth2-strategy.js.map +1 -0
  83. package/dist/migrations/Migration_20260425000001_init_viva_payments.d.ts +19 -0
  84. package/dist/migrations/Migration_20260425000001_init_viva_payments.d.ts.map +1 -0
  85. package/dist/migrations/Migration_20260425000001_init_viva_payments.js +136 -0
  86. package/dist/migrations/Migration_20260425000001_init_viva_payments.js.map +1 -0
  87. package/dist/migrations/Migration_20260425000002_allow_null_order_code.d.ts +31 -0
  88. package/dist/migrations/Migration_20260425000002_allow_null_order_code.d.ts.map +1 -0
  89. package/dist/migrations/Migration_20260425000002_allow_null_order_code.js +71 -0
  90. package/dist/migrations/Migration_20260425000002_allow_null_order_code.js.map +1 -0
  91. package/dist/migrations/Migration_20260425000003_webhook_retry_count.d.ts +18 -0
  92. package/dist/migrations/Migration_20260425000003_webhook_retry_count.d.ts.map +1 -0
  93. package/dist/migrations/Migration_20260425000003_webhook_retry_count.js +42 -0
  94. package/dist/migrations/Migration_20260425000003_webhook_retry_count.js.map +1 -0
  95. package/dist/migrations/Migration_20260425000004_webhook_error_and_nullable_merchant.d.ts +29 -0
  96. package/dist/migrations/Migration_20260425000004_webhook_error_and_nullable_merchant.d.ts.map +1 -0
  97. package/dist/migrations/Migration_20260425000004_webhook_error_and_nullable_merchant.js +74 -0
  98. package/dist/migrations/Migration_20260425000004_webhook_error_and_nullable_merchant.js.map +1 -0
  99. package/dist/models/index.d.ts +7 -0
  100. package/dist/models/index.d.ts.map +1 -0
  101. package/dist/models/index.js +10 -0
  102. package/dist/models/index.js.map +1 -0
  103. package/dist/models/viva-tenant-merchant.d.ts +11 -0
  104. package/dist/models/viva-tenant-merchant.d.ts.map +1 -0
  105. package/dist/models/viva-tenant-merchant.js +54 -0
  106. package/dist/models/viva-tenant-merchant.js.map +1 -0
  107. package/dist/models/viva-transaction.d.ts +34 -0
  108. package/dist/models/viva-transaction.d.ts.map +1 -0
  109. package/dist/models/viva-transaction.js +104 -0
  110. package/dist/models/viva-transaction.js.map +1 -0
  111. package/dist/models/viva-webhook-event.d.ts +32 -0
  112. package/dist/models/viva-webhook-event.d.ts.map +1 -0
  113. package/dist/models/viva-webhook-event.js +88 -0
  114. package/dist/models/viva-webhook-event.js.map +1 -0
  115. package/dist/observability/config.d.ts +34 -0
  116. package/dist/observability/config.d.ts.map +1 -0
  117. package/dist/observability/config.js +57 -0
  118. package/dist/observability/config.js.map +1 -0
  119. package/dist/observability/index.d.ts +8 -0
  120. package/dist/observability/index.d.ts.map +1 -0
  121. package/dist/observability/index.js +15 -0
  122. package/dist/observability/index.js.map +1 -0
  123. package/dist/observability/prom-metrics.d.ts +41 -0
  124. package/dist/observability/prom-metrics.d.ts.map +1 -0
  125. package/dist/observability/prom-metrics.js +219 -0
  126. package/dist/observability/prom-metrics.js.map +1 -0
  127. package/dist/providers/payment-provider.d.ts +19 -0
  128. package/dist/providers/payment-provider.d.ts.map +1 -0
  129. package/dist/providers/payment-provider.js +24 -0
  130. package/dist/providers/payment-provider.js.map +1 -0
  131. package/dist/resolvers/auth-strategy-factory.d.ts +42 -0
  132. package/dist/resolvers/auth-strategy-factory.d.ts.map +1 -0
  133. package/dist/resolvers/auth-strategy-factory.js +60 -0
  134. package/dist/resolvers/auth-strategy-factory.js.map +1 -0
  135. package/dist/resolvers/tenant-resolver.d.ts +104 -0
  136. package/dist/resolvers/tenant-resolver.d.ts.map +1 -0
  137. package/dist/resolvers/tenant-resolver.js +118 -0
  138. package/dist/resolvers/tenant-resolver.js.map +1 -0
  139. package/dist/service.d.ts +200 -0
  140. package/dist/service.d.ts.map +1 -0
  141. package/dist/service.js +1003 -0
  142. package/dist/service.js.map +1 -0
  143. package/dist/subscribers/index.d.ts +5 -0
  144. package/dist/subscribers/index.d.ts.map +1 -0
  145. package/dist/subscribers/index.js +10 -0
  146. package/dist/subscribers/index.js.map +1 -0
  147. package/dist/subscribers/viva-webhook-event.d.ts +38 -0
  148. package/dist/subscribers/viva-webhook-event.d.ts.map +1 -0
  149. package/dist/subscribers/viva-webhook-event.js +133 -0
  150. package/dist/subscribers/viva-webhook-event.js.map +1 -0
  151. package/dist/workflows/cleanup-old-webhook-events.d.ts +39 -0
  152. package/dist/workflows/cleanup-old-webhook-events.d.ts.map +1 -0
  153. package/dist/workflows/cleanup-old-webhook-events.js +68 -0
  154. package/dist/workflows/cleanup-old-webhook-events.js.map +1 -0
  155. package/dist/workflows/index.d.ts +14 -0
  156. package/dist/workflows/index.d.ts.map +1 -0
  157. package/dist/workflows/index.js +19 -0
  158. package/dist/workflows/index.js.map +1 -0
  159. package/dist/workflows/per-tenant-semaphore.d.ts +47 -0
  160. package/dist/workflows/per-tenant-semaphore.d.ts.map +1 -0
  161. package/dist/workflows/per-tenant-semaphore.js +89 -0
  162. package/dist/workflows/per-tenant-semaphore.js.map +1 -0
  163. package/dist/workflows/process-webhook-event.d.ts +80 -0
  164. package/dist/workflows/process-webhook-event.d.ts.map +1 -0
  165. package/dist/workflows/process-webhook-event.js +280 -0
  166. package/dist/workflows/process-webhook-event.js.map +1 -0
  167. package/dist/workflows/reprocess-unresolved-tenants.d.ts +58 -0
  168. package/dist/workflows/reprocess-unresolved-tenants.d.ts.map +1 -0
  169. package/dist/workflows/reprocess-unresolved-tenants.js +121 -0
  170. package/dist/workflows/reprocess-unresolved-tenants.js.map +1 -0
  171. package/package.json +63 -0
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VivaTransactionSchema = void 0;
4
+ const core_1 = require("@medusajs/framework/mikro-orm/core");
5
+ exports.VivaTransactionSchema = new core_1.EntitySchema({
6
+ name: "VivaTransaction",
7
+ tableName: "viva_transaction",
8
+ uniques: [
9
+ {
10
+ name: "viva_transaction_idempotency_key_uniq",
11
+ properties: ["idempotency_key"],
12
+ },
13
+ {
14
+ name: "viva_transaction_viva_order_code_uniq",
15
+ properties: ["viva_order_code"],
16
+ },
17
+ ],
18
+ indexes: [
19
+ {
20
+ name: "viva_transaction_medusa_payment_id_idx",
21
+ properties: ["medusa_payment_id"],
22
+ },
23
+ {
24
+ name: "viva_transaction_merchant_created_idx",
25
+ properties: ["viva_merchant_id", "created_at"],
26
+ },
27
+ ],
28
+ properties: {
29
+ viva_transaction_id: {
30
+ type: "string",
31
+ columnType: "uuid",
32
+ primary: true,
33
+ },
34
+ viva_order_code: {
35
+ type: "bigint",
36
+ columnType: "bigint",
37
+ // Nullable per Migration_20260425000002_allow_null_order_code.
38
+ // NULL until createOrder returns successfully (A4 write-pending-first).
39
+ // @see references/viva-docs/md/isv-partner-program.txt:61 (A4)
40
+ nullable: true,
41
+ },
42
+ medusa_payment_id: {
43
+ type: "string",
44
+ columnType: "text",
45
+ nullable: false,
46
+ },
47
+ viva_merchant_id: {
48
+ type: "string",
49
+ columnType: "uuid",
50
+ // Nullable per Migration_20260425000004_webhook_error_and_nullable_merchant.
51
+ // Merchant-mode rows have no per-cart tenant merchant id.
52
+ nullable: true,
53
+ },
54
+ status: {
55
+ type: "string",
56
+ columnType: "text",
57
+ nullable: false,
58
+ },
59
+ claim_substate: {
60
+ type: "string",
61
+ columnType: "text",
62
+ nullable: true,
63
+ },
64
+ amount_minor: {
65
+ type: "bigint",
66
+ columnType: "bigint",
67
+ nullable: false,
68
+ },
69
+ refunded_amount_minor: {
70
+ type: "bigint",
71
+ columnType: "bigint",
72
+ nullable: false,
73
+ default: 0,
74
+ },
75
+ currency_code: {
76
+ type: "string",
77
+ columnType: "text",
78
+ nullable: false,
79
+ },
80
+ idempotency_key: {
81
+ type: "string",
82
+ columnType: "text",
83
+ nullable: false,
84
+ },
85
+ raw_payload: {
86
+ type: "json",
87
+ columnType: "jsonb",
88
+ nullable: true,
89
+ },
90
+ created_at: {
91
+ type: "Date",
92
+ columnType: "timestamptz",
93
+ nullable: false,
94
+ defaultRaw: "now()",
95
+ },
96
+ updated_at: {
97
+ type: "Date",
98
+ columnType: "timestamptz",
99
+ nullable: false,
100
+ defaultRaw: "now()",
101
+ },
102
+ },
103
+ });
104
+ //# sourceMappingURL=viva-transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viva-transaction.js","sourceRoot":"","sources":["../../src/models/viva-transaction.ts"],"names":[],"mappings":";;;AAAA,6DAAkE;AA4CrD,QAAA,qBAAqB,GAAG,IAAI,mBAAY,CAAkB;IACrE,IAAI,EAAE,iBAAiB;IACvB,SAAS,EAAE,kBAAkB;IAC7B,OAAO,EAAE;QACP;YACE,IAAI,EAAE,uCAAuC;YAC7C,UAAU,EAAE,CAAC,iBAAiB,CAAC;SAChC;QACD;YACE,IAAI,EAAE,uCAAuC;YAC7C,UAAU,EAAE,CAAC,iBAAiB,CAAC;SAChC;KACF;IACD,OAAO,EAAE;QACP;YACE,IAAI,EAAE,wCAAwC;YAC9C,UAAU,EAAE,CAAC,mBAAmB,CAAC;SAClC;QACD;YACE,IAAI,EAAE,uCAAuC;YAC7C,UAAU,EAAE,CAAC,kBAAkB,EAAE,YAAY,CAAC;SAC/C;KACF;IACD,UAAU,EAAE;QACV,mBAAmB,EAAE;YACnB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,OAAO,EAAE,IAAI;SACd;QACD,eAAe,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,QAAQ;YACpB,+DAA+D;YAC/D,wEAAwE;YACxE,+DAA+D;YAC/D,QAAQ,EAAE,IAAI;SACf;QACD,iBAAiB,EAAE;YACjB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,KAAK;SAChB;QACD,gBAAgB,EAAE;YAChB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,6EAA6E;YAC7E,0DAA0D;YAC1D,QAAQ,EAAE,IAAI;SACf;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,KAAK;SAChB;QACD,cAAc,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,IAAI;SACf;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,QAAQ;YACpB,QAAQ,EAAE,KAAK;SAChB;QACD,qBAAqB,EAAE;YACrB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,QAAQ;YACpB,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,CAAC;SACX;QACD,aAAa,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,KAAK;SAChB;QACD,eAAe,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,KAAK;SAChB;QACD,WAAW,EAAE;YACX,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,OAAO;YACnB,QAAQ,EAAE,IAAI;SACf;QACD,UAAU,EAAE;YACV,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,OAAO;SACpB;QACD,UAAU,EAAE;YACV,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,OAAO;SACpB;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { EntitySchema } from "@medusajs/framework/mikro-orm/core";
2
+ export interface VivaWebhookEvent {
3
+ viva_webhook_event_id: string;
4
+ /** NULL for onboarding events */
5
+ transaction_id: string | null | undefined;
6
+ event_type_id: number;
7
+ message_id: string;
8
+ /** NULL for onboarding events */
9
+ viva_merchant_id: string | null | undefined;
10
+ /** NULL for non-onboarding events */
11
+ connected_account_id: string | null | undefined;
12
+ processed_at: Date | null | undefined;
13
+ raw_payload: Record<string, unknown>;
14
+ received_at: Date;
15
+ /**
16
+ * Last error envelope (JSON-serialized) recorded when processing failed.
17
+ * NULL on success or before any failure. Operator playbook reads this to
18
+ * diagnose stuck payments — see docs/ERRORS.md §6.
19
+ *
20
+ * Added by Migration_20260425000004_webhook_error_and_nullable_merchant.
21
+ */
22
+ error: string | null | undefined;
23
+ /**
24
+ * Count of processing/resolution attempts. Defaults to 0. Bumped on
25
+ * tenant-resolution retries (A6) and on processing failures (job retry).
26
+ *
27
+ * Added by Migration_20260425000003_webhook_retry_count.
28
+ */
29
+ retry_count: number;
30
+ }
31
+ export declare const VivaWebhookEventSchema: EntitySchema<VivaWebhookEvent, never>;
32
+ //# sourceMappingURL=viva-webhook-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viva-webhook-event.d.ts","sourceRoot":"","sources":["../../src/models/viva-webhook-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,MAAM,WAAW,gBAAgB;IAC/B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iCAAiC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,qCAAqC;IACrC,oBAAoB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,YAAY,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,WAAW,EAAE,IAAI,CAAC;IAClB;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACjC;;;;;OAKG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,sBAAsB,uCAmFjC,CAAC"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VivaWebhookEventSchema = void 0;
4
+ const core_1 = require("@medusajs/framework/mikro-orm/core");
5
+ exports.VivaWebhookEventSchema = new core_1.EntitySchema({
6
+ name: "VivaWebhookEvent",
7
+ tableName: "viva_webhook_event",
8
+ uniques: [
9
+ {
10
+ name: "viva_webhook_event_message_id_uniq",
11
+ properties: ["message_id"],
12
+ },
13
+ ],
14
+ indexes: [
15
+ {
16
+ // Partial unique on (transaction_id, event_type_id) WHERE transaction_id IS NOT NULL.
17
+ // Cannot express partial indexes via EntitySchema — defined as raw expression.
18
+ name: "viva_webhook_event_txn_type_uniq",
19
+ expression: "CREATE UNIQUE INDEX IF NOT EXISTS viva_webhook_event_txn_type_uniq " +
20
+ "ON viva_webhook_event (transaction_id, event_type_id) WHERE transaction_id IS NOT NULL",
21
+ },
22
+ {
23
+ name: "viva_webhook_event_type_received_idx",
24
+ properties: ["event_type_id", "received_at"],
25
+ },
26
+ ],
27
+ properties: {
28
+ viva_webhook_event_id: {
29
+ type: "string",
30
+ columnType: "uuid",
31
+ primary: true,
32
+ defaultRaw: "gen_random_uuid()",
33
+ },
34
+ transaction_id: {
35
+ type: "string",
36
+ columnType: "uuid",
37
+ nullable: true,
38
+ },
39
+ event_type_id: {
40
+ type: "number",
41
+ columnType: "int",
42
+ nullable: false,
43
+ },
44
+ message_id: {
45
+ type: "string",
46
+ columnType: "uuid",
47
+ nullable: false,
48
+ },
49
+ viva_merchant_id: {
50
+ type: "string",
51
+ columnType: "uuid",
52
+ nullable: true,
53
+ },
54
+ connected_account_id: {
55
+ type: "string",
56
+ columnType: "uuid",
57
+ nullable: true,
58
+ },
59
+ processed_at: {
60
+ type: "Date",
61
+ columnType: "timestamptz",
62
+ nullable: true,
63
+ },
64
+ raw_payload: {
65
+ type: "json",
66
+ columnType: "jsonb",
67
+ nullable: false,
68
+ },
69
+ received_at: {
70
+ type: "Date",
71
+ columnType: "timestamptz",
72
+ nullable: false,
73
+ defaultRaw: "now()",
74
+ },
75
+ error: {
76
+ type: "string",
77
+ columnType: "text",
78
+ nullable: true,
79
+ },
80
+ retry_count: {
81
+ type: "number",
82
+ columnType: "int",
83
+ nullable: false,
84
+ default: 0,
85
+ },
86
+ },
87
+ });
88
+ //# sourceMappingURL=viva-webhook-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viva-webhook-event.js","sourceRoot":"","sources":["../../src/models/viva-webhook-event.ts"],"names":[],"mappings":";;;AAAA,6DAAkE;AAgCrD,QAAA,sBAAsB,GAAG,IAAI,mBAAY,CAAmB;IACvE,IAAI,EAAE,kBAAkB;IACxB,SAAS,EAAE,oBAAoB;IAC/B,OAAO,EAAE;QACP;YACE,IAAI,EAAE,oCAAoC;YAC1C,UAAU,EAAE,CAAC,YAAY,CAAC;SAC3B;KACF;IACD,OAAO,EAAE;QACP;YACE,sFAAsF;YACtF,+EAA+E;YAC/E,IAAI,EAAE,kCAAkC;YACxC,UAAU,EACR,qEAAqE;gBACrE,wFAAwF;SAC3F;QACD;YACE,IAAI,EAAE,sCAAsC;YAC5C,UAAU,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC;SAC7C;KACF;IACD,UAAU,EAAE;QACV,qBAAqB,EAAE;YACrB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,mBAAmB;SAChC;QACD,cAAc,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,IAAI;SACf;QACD,aAAa,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;SAChB;QACD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,KAAK;SAChB;QACD,gBAAgB,EAAE;YAChB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,IAAI;SACf;QACD,oBAAoB,EAAE;YACpB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,IAAI;SACf;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,IAAI;SACf;QACD,WAAW,EAAE;YACX,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,OAAO;YACnB,QAAQ,EAAE,KAAK;SAChB;QACD,WAAW,EAAE;YACX,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,aAAa;YACzB,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,OAAO;SACpB;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,MAAM;YAClB,QAAQ,EAAE,IAAI;SACf;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,CAAC;SACX;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * config.ts — buildObservability(config) factory for medusa-payment-viva.
3
+ *
4
+ * Builds an ObservabilityContext from plugin config:
5
+ * - logger: StructuredJsonLogger → stdout, wrapped in RedactingLogger
6
+ * - metrics: PromMetricsHook (in-process Prometheus-compatible counters/histograms)
7
+ * - tracer: NoopTracerHook (SaaS wrapper wires a real tracer)
8
+ *
9
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P16 observability)
10
+ */
11
+ import type { ObservabilityContext } from '@sakeetech/viva-payments-core/observability';
12
+ import type { VivaPluginConfig } from '../config.js';
13
+ import { PromMetricsHook } from './prom-metrics.js';
14
+ /**
15
+ * Returns the shared PromMetricsHook instance (created on first call).
16
+ * Exposed so routes can read toExposition() from the same instance.
17
+ */
18
+ export declare function getSharedMetrics(): PromMetricsHook;
19
+ /**
20
+ * Resets the shared metrics instance (for testing).
21
+ */
22
+ export declare function resetSharedMetrics(): void;
23
+ /**
24
+ * Builds an ObservabilityContext for medusa-payment-viva.
25
+ *
26
+ * The returned context uses:
27
+ * - RedactingLogger(StructuredJsonLogger()) for structured JSON output
28
+ * - PromMetricsHook for Prometheus-compatible in-process metrics
29
+ * - NoopTracerHook (SaaS wrapper can override tracer after construction)
30
+ *
31
+ * @param config - resolved VivaPluginConfig (used for future per-tenant context)
32
+ */
33
+ export declare function buildObservability(_config: VivaPluginConfig): ObservabilityContext;
34
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/observability/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAQpD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,eAAe,CAKlD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAMD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,oBAAoB,CAMlF"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /**
3
+ * config.ts — buildObservability(config) factory for medusa-payment-viva.
4
+ *
5
+ * Builds an ObservabilityContext from plugin config:
6
+ * - logger: StructuredJsonLogger → stdout, wrapped in RedactingLogger
7
+ * - metrics: PromMetricsHook (in-process Prometheus-compatible counters/histograms)
8
+ * - tracer: NoopTracerHook (SaaS wrapper wires a real tracer)
9
+ *
10
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P16 observability)
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.getSharedMetrics = getSharedMetrics;
14
+ exports.resetSharedMetrics = resetSharedMetrics;
15
+ exports.buildObservability = buildObservability;
16
+ const observability_1 = require("@sakeetech/viva-payments-core/observability");
17
+ const prom_metrics_js_1 = require("./prom-metrics.js");
18
+ // ---------------------------------------------------------------------------
19
+ // Singleton metrics hook shared across the plugin lifetime
20
+ // ---------------------------------------------------------------------------
21
+ let _sharedMetrics = null;
22
+ /**
23
+ * Returns the shared PromMetricsHook instance (created on first call).
24
+ * Exposed so routes can read toExposition() from the same instance.
25
+ */
26
+ function getSharedMetrics() {
27
+ if (!_sharedMetrics) {
28
+ _sharedMetrics = new prom_metrics_js_1.PromMetricsHook();
29
+ }
30
+ return _sharedMetrics;
31
+ }
32
+ /**
33
+ * Resets the shared metrics instance (for testing).
34
+ */
35
+ function resetSharedMetrics() {
36
+ _sharedMetrics = null;
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // buildObservability
40
+ // ---------------------------------------------------------------------------
41
+ /**
42
+ * Builds an ObservabilityContext for medusa-payment-viva.
43
+ *
44
+ * The returned context uses:
45
+ * - RedactingLogger(StructuredJsonLogger()) for structured JSON output
46
+ * - PromMetricsHook for Prometheus-compatible in-process metrics
47
+ * - NoopTracerHook (SaaS wrapper can override tracer after construction)
48
+ *
49
+ * @param config - resolved VivaPluginConfig (used for future per-tenant context)
50
+ */
51
+ function buildObservability(_config) {
52
+ const logger = new observability_1.RedactingLogger(new observability_1.StructuredJsonLogger());
53
+ const metrics = getSharedMetrics();
54
+ const tracer = new observability_1.NoopTracerHook();
55
+ return { logger, metrics, tracer };
56
+ }
57
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/observability/config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAqBH,4CAKC;AAKD,gDAEC;AAgBD,gDAMC;AArDD,+EAIqD;AAGrD,uDAAoD;AAEpD,8EAA8E;AAC9E,2DAA2D;AAC3D,8EAA8E;AAE9E,IAAI,cAAc,GAA2B,IAAI,CAAC;AAElD;;;GAGG;AACH,SAAgB,gBAAgB;IAC9B,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,IAAI,iCAAe,EAAE,CAAC;IACzC,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB;IAChC,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,SAAgB,kBAAkB,CAAC,OAAyB;IAC1D,MAAM,MAAM,GAAG,IAAI,+BAAe,CAAC,IAAI,oCAAoB,EAAE,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,8BAAc,EAAE,CAAC;IAEpC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * medusa-payment-viva/observability — barrel re-exports.
3
+ *
4
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P16 observability)
5
+ */
6
+ export { PromMetricsHook } from './prom-metrics.js';
7
+ export { buildObservability, getSharedMetrics, resetSharedMetrics } from './config.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ /**
3
+ * medusa-payment-viva/observability — barrel re-exports.
4
+ *
5
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P16 observability)
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.resetSharedMetrics = exports.getSharedMetrics = exports.buildObservability = exports.PromMetricsHook = void 0;
9
+ var prom_metrics_js_1 = require("./prom-metrics.js");
10
+ Object.defineProperty(exports, "PromMetricsHook", { enumerable: true, get: function () { return prom_metrics_js_1.PromMetricsHook; } });
11
+ var config_js_1 = require("./config.js");
12
+ Object.defineProperty(exports, "buildObservability", { enumerable: true, get: function () { return config_js_1.buildObservability; } });
13
+ Object.defineProperty(exports, "getSharedMetrics", { enumerable: true, get: function () { return config_js_1.getSharedMetrics; } });
14
+ Object.defineProperty(exports, "resetSharedMetrics", { enumerable: true, get: function () { return config_js_1.resetSharedMetrics; } });
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,qDAAoD;AAA3C,kHAAA,eAAe,OAAA;AACxB,yCAAuF;AAA9E,+GAAA,kBAAkB,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAAE,+GAAA,kBAAkB,OAAA"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * prom-metrics.ts — Hand-rolled Prometheus-compatible MetricsHook.
3
+ *
4
+ * Does NOT depend on prom-client. Stores counters and histograms in-process
5
+ * and exports them via toExposition() in Prometheus text format (v0.0.4).
6
+ *
7
+ * Histogram buckets (seconds):
8
+ * [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, +Inf]
9
+ *
10
+ * Metric names emitted:
11
+ * viva_auth_token_refresh_duration_seconds (histogram)
12
+ * viva_api_request_duration_seconds (histogram, endpoint + status labels)
13
+ * viva_webhook_received_total (counter, event_type_id + result)
14
+ * viva_webhook_processing_lag_seconds (histogram)
15
+ * viva_tenant_resolution_failures_total (counter)
16
+ * viva_webhook_lattice_reject_total (counter, reason)
17
+ * viva_webhook_ordercode_mismatch_total (counter, event_type_id)
18
+ * viva_tenant_resolution_retry_resolved_total (counter)
19
+ * viva_tenant_resolution_abandoned_total (counter)
20
+ *
21
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P16 observability)
22
+ */
23
+ import type { MetricLabels, MetricsHook } from '@sakeetech/viva-payments-core/observability';
24
+ export declare class PromMetricsHook implements MetricsHook {
25
+ /** metric_name -> labelHash -> value */
26
+ private readonly _counters;
27
+ /** metric_name -> HistogramState */
28
+ private readonly _histograms;
29
+ counter(name: string, labels?: MetricLabels, value?: number): void;
30
+ histogram(name: string, valueSeconds: number, labels?: MetricLabels): void;
31
+ timeAsync<T>(name: string, fn: () => Promise<T>, labels?: MetricLabels): Promise<T>;
32
+ /**
33
+ * Returns Prometheus text format (v0.0.4) for scraping.
34
+ * Includes # HELP and # TYPE lines for known metrics.
35
+ */
36
+ toExposition(): string;
37
+ /** `${name}\x00${hash}` -> labels object */
38
+ private readonly _counterLabels;
39
+ private readonly _histogramLabels;
40
+ }
41
+ //# sourceMappingURL=prom-metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prom-metrics.d.ts","sourceRoot":"","sources":["../../src/observability/prom-metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,6CAA6C,CAAC;AA4F7F,qBAAa,eAAgB,YAAW,WAAW;IACjD,wCAAwC;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0C;IAEpE,oCAAoC;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IAMjE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,EAAE,KAAK,SAAI,GAAG,IAAI;IAY7D,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI;IAqCpE,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC;IAkBzF;;;OAGG;IACH,YAAY,IAAI,MAAM;IA4DtB,4CAA4C;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmC;IAClE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmC;CACrE"}
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ /**
3
+ * prom-metrics.ts — Hand-rolled Prometheus-compatible MetricsHook.
4
+ *
5
+ * Does NOT depend on prom-client. Stores counters and histograms in-process
6
+ * and exports them via toExposition() in Prometheus text format (v0.0.4).
7
+ *
8
+ * Histogram buckets (seconds):
9
+ * [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, +Inf]
10
+ *
11
+ * Metric names emitted:
12
+ * viva_auth_token_refresh_duration_seconds (histogram)
13
+ * viva_api_request_duration_seconds (histogram, endpoint + status labels)
14
+ * viva_webhook_received_total (counter, event_type_id + result)
15
+ * viva_webhook_processing_lag_seconds (histogram)
16
+ * viva_tenant_resolution_failures_total (counter)
17
+ * viva_webhook_lattice_reject_total (counter, reason)
18
+ * viva_webhook_ordercode_mismatch_total (counter, event_type_id)
19
+ * viva_tenant_resolution_retry_resolved_total (counter)
20
+ * viva_tenant_resolution_abandoned_total (counter)
21
+ *
22
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P16 observability)
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.PromMetricsHook = void 0;
26
+ const METRIC_META = {
27
+ viva_auth_token_refresh_duration_seconds: {
28
+ help: 'Duration of Viva OAuth2 token refresh requests in seconds.',
29
+ type: 'histogram',
30
+ },
31
+ viva_api_request_duration_seconds: {
32
+ help: 'Duration of outbound Viva ISV API requests in seconds.',
33
+ type: 'histogram',
34
+ },
35
+ viva_webhook_received_total: {
36
+ help: 'Total number of Viva webhook events received, by event_type_id and result.',
37
+ type: 'counter',
38
+ },
39
+ viva_webhook_processing_lag_seconds: {
40
+ help: 'Lag in seconds between webhook Created timestamp and processing time.',
41
+ type: 'histogram',
42
+ },
43
+ viva_tenant_resolution_failures_total: {
44
+ help: 'Total number of failed tenant resolution attempts.',
45
+ type: 'counter',
46
+ },
47
+ viva_webhook_lattice_reject_total: {
48
+ help: 'Total number of webhook events rejected by the status lattice.',
49
+ type: 'counter',
50
+ },
51
+ viva_webhook_ordercode_mismatch_total: {
52
+ help: 'Total number of webhook events rejected because envelope.OrderCode did not match live.orderCode from retrieveTransaction (potential spoof attempt). See docs/TODO-CSO.md Finding 1.',
53
+ type: 'counter',
54
+ },
55
+ viva_tenant_resolution_retry_resolved_total: {
56
+ help: 'Total number of tenant resolutions that succeeded on retry.',
57
+ type: 'counter',
58
+ },
59
+ viva_tenant_resolution_abandoned_total: {
60
+ help: 'Total number of tenant resolutions abandoned after exhausting retries.',
61
+ type: 'counter',
62
+ },
63
+ };
64
+ // ---------------------------------------------------------------------------
65
+ // Default histogram buckets (seconds)
66
+ // ---------------------------------------------------------------------------
67
+ const DEFAULT_BUCKETS = [
68
+ 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10,
69
+ ];
70
+ // ---------------------------------------------------------------------------
71
+ // Label hash helpers
72
+ // ---------------------------------------------------------------------------
73
+ function hashLabels(labels) {
74
+ if (!labels || Object.keys(labels).length === 0)
75
+ return '';
76
+ const sorted = Object.keys(labels).sort();
77
+ return sorted.map((k) => `${k}=${String(labels[k])}`).join(',');
78
+ }
79
+ function labelsToPromString(labels) {
80
+ if (!labels || Object.keys(labels).length === 0)
81
+ return '';
82
+ const sorted = Object.keys(labels).sort();
83
+ const parts = sorted.map((k) => `${k}="${String(labels[k])}"`);
84
+ return `{${parts.join(',')}}`;
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // PromMetricsHook
88
+ // ---------------------------------------------------------------------------
89
+ class PromMetricsHook {
90
+ /** metric_name -> labelHash -> value */
91
+ _counters = new Map();
92
+ /** metric_name -> HistogramState */
93
+ _histograms = new Map();
94
+ // ---------------------------------------------------------------------------
95
+ // MetricsHook implementation
96
+ // ---------------------------------------------------------------------------
97
+ counter(name, labels, value = 1) {
98
+ let byLabel = this._counters.get(name);
99
+ if (!byLabel) {
100
+ byLabel = new Map();
101
+ this._counters.set(name, byLabel);
102
+ }
103
+ const hash = hashLabels(labels);
104
+ byLabel.set(hash, (byLabel.get(hash) ?? 0) + value);
105
+ // Store labels for later serialization
106
+ this._counterLabels.set(`${name}\x00${hash}`, labels ?? {});
107
+ }
108
+ histogram(name, valueSeconds, labels) {
109
+ let state = this._histograms.get(name);
110
+ if (!state) {
111
+ state = {
112
+ buckets: DEFAULT_BUCKETS,
113
+ counts: new Map(),
114
+ sum: new Map(),
115
+ count: new Map(),
116
+ };
117
+ this._histograms.set(name, state);
118
+ }
119
+ const hash = hashLabels(labels);
120
+ // Store labels for later serialization
121
+ this._histogramLabels.set(`${name}\x00${hash}`, labels ?? {});
122
+ // Initialize bucket array if needed
123
+ if (!state.counts.has(hash)) {
124
+ // +1 for the +Inf bucket
125
+ state.counts.set(hash, new Array(DEFAULT_BUCKETS.length + 1).fill(0));
126
+ }
127
+ const bucketCounts = state.counts.get(hash);
128
+ // Increment all buckets where le >= value
129
+ for (let i = 0; i < DEFAULT_BUCKETS.length; i++) {
130
+ if (valueSeconds <= DEFAULT_BUCKETS[i]) {
131
+ bucketCounts[i] = (bucketCounts[i] ?? 0) + 1;
132
+ }
133
+ }
134
+ // +Inf bucket always incremented
135
+ bucketCounts[DEFAULT_BUCKETS.length] = (bucketCounts[DEFAULT_BUCKETS.length] ?? 0) + 1;
136
+ state.sum.set(hash, (state.sum.get(hash) ?? 0) + valueSeconds);
137
+ state.count.set(hash, (state.count.get(hash) ?? 0) + 1);
138
+ }
139
+ async timeAsync(name, fn, labels) {
140
+ const start = process.hrtime.bigint();
141
+ try {
142
+ const result = await fn();
143
+ const durationSec = Number(process.hrtime.bigint() - start) / 1e9;
144
+ this.histogram(name, durationSec, labels);
145
+ return result;
146
+ }
147
+ catch (err) {
148
+ const durationSec = Number(process.hrtime.bigint() - start) / 1e9;
149
+ this.histogram(name, durationSec, { ...labels, status: 'error' });
150
+ throw err;
151
+ }
152
+ }
153
+ // ---------------------------------------------------------------------------
154
+ // Prometheus text format exposition
155
+ // ---------------------------------------------------------------------------
156
+ /**
157
+ * Returns Prometheus text format (v0.0.4) for scraping.
158
+ * Includes # HELP and # TYPE lines for known metrics.
159
+ */
160
+ toExposition() {
161
+ const lines = [];
162
+ // Counters
163
+ for (const [name, byLabel] of this._counters) {
164
+ const meta = METRIC_META[name];
165
+ if (meta) {
166
+ lines.push(`# HELP ${name} ${meta.help}`);
167
+ lines.push(`# TYPE ${name} counter`);
168
+ }
169
+ else {
170
+ lines.push(`# TYPE ${name} counter`);
171
+ }
172
+ for (const [hash, value] of byLabel) {
173
+ const labels = this._counterLabels.get(`${name}\x00${hash}`) ?? {};
174
+ const labelStr = labelsToPromString(labels);
175
+ lines.push(`${name}${labelStr} ${value}`);
176
+ }
177
+ lines.push('');
178
+ }
179
+ // Histograms
180
+ for (const [name, state] of this._histograms) {
181
+ const meta = METRIC_META[name];
182
+ if (meta) {
183
+ lines.push(`# HELP ${name} ${meta.help}`);
184
+ lines.push(`# TYPE ${name} histogram`);
185
+ }
186
+ else {
187
+ lines.push(`# TYPE ${name} histogram`);
188
+ }
189
+ for (const [hash, bucketCounts] of state.counts) {
190
+ const labels = this._histogramLabels.get(`${name}\x00${hash}`) ?? {};
191
+ // Emit per-bucket lines
192
+ for (let i = 0; i < DEFAULT_BUCKETS.length; i++) {
193
+ const le = DEFAULT_BUCKETS[i];
194
+ const leStr = le.toString();
195
+ const bucketLabels = { ...labels, le: leStr };
196
+ const labelStr = labelsToPromString(bucketLabels);
197
+ lines.push(`${name}_bucket${labelStr} ${bucketCounts[i] ?? 0}`);
198
+ }
199
+ // +Inf bucket
200
+ const infLabels = { ...labels, le: '+Inf' };
201
+ lines.push(`${name}_bucket${labelsToPromString(infLabels)} ${bucketCounts[DEFAULT_BUCKETS.length] ?? 0}`);
202
+ // sum and count
203
+ const labelStr = labelsToPromString(labels);
204
+ lines.push(`${name}_sum${labelStr} ${state.sum.get(hash) ?? 0}`);
205
+ lines.push(`${name}_count${labelStr} ${state.count.get(hash) ?? 0}`);
206
+ }
207
+ lines.push('');
208
+ }
209
+ return lines.join('\n');
210
+ }
211
+ // ---------------------------------------------------------------------------
212
+ // Internal label stores (for serialization)
213
+ // ---------------------------------------------------------------------------
214
+ /** `${name}\x00${hash}` -> labels object */
215
+ _counterLabels = new Map();
216
+ _histogramLabels = new Map();
217
+ }
218
+ exports.PromMetricsHook = PromMetricsHook;
219
+ //# sourceMappingURL=prom-metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prom-metrics.js","sourceRoot":"","sources":["../../src/observability/prom-metrics.ts"],"names":[],"mappings":"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"}