@hyperscale0/adl 1.0.0-beta.1 → 1.0.0-beta.3

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/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html) from 1.0.0.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.0.0-beta.3] - 2026-09-10
10
+
11
+ - Republished without the GitHub Actions publish workflow. No package behavior changes from 1.0.0-beta.2.
12
+
13
+ ## [1.0.0-beta.2] - 2026-09-10
14
+
15
+ - Republished against UDL 2.0.0. No package behavior changes from
16
+ 1.0.0-beta.1.
17
+
9
18
  ## [1.0.0-beta.1] - 2026-08-29
10
19
 
11
20
  - This is the first beta and has no package behavior changes from
package/README.md CHANGED
@@ -1,41 +1,18 @@
1
- # ADL
1
+ ![ADL: Declare how a bank or provider behaves.](docs/assets/adl.svg)
2
2
 
3
- ADL is the Adapter Declaration Language: the public format for declaring how a
4
- bank or provider behaves at the control-plane boundary. Its validator and
5
- conformance suite refuse incomplete interface facts before a generic runtime
6
- can poll, classify, reconcile, or deduplicate provider results.
3
+ # ADL
7
4
 
8
- The three language boundaries stay separate. HSX authors settlement behavior.
9
- UDL defines the canonical product contract. ADL declares how an external
10
- provider performs or confirms work behind that contract.
5
+ ADL is the Adapter Declaration Language: the public format for declaring how a bank or provider behaves at the control-plane boundary. Its validator and conformance suite refuse incomplete interface facts before a generic runtime can poll, classify, reconcile, or deduplicate provider results. The three language boundaries stay separate: HSX authors settlement behavior, UDL defines the canonical product contract, and ADL declares how an external provider performs or confirms work behind that contract.
11
6
 
12
- **Status: alpha.** The surface can still change on a minor version until
13
- 1.0.0.
7
+ **Status: beta.** Current release is 1.0.0-beta.1. Pre-1.0 releases can change on minor versions until 1.0.0.
14
8
 
15
9
  ## Adapter symmetry
16
10
 
17
- Hyperscale's own bank adapters are written against this package and nothing
18
- more. There is no private adapter API and no second interface for first-party
19
- code. When one of our adapters needs a seam ADL lacks, the seam is added here,
20
- in public, or it is not added.
21
-
22
- So the guide below is not a simplified account of how we do it. It is how we
23
- do it.
24
-
25
- ## What an adapter is
11
+ Hyperscale first-party bank adapters are written against this package and nothing more. There is no private adapter API and no second interface for first-party code. When an adapter needs a seam ADL lacks, the seam is added here, in public, or not at all.
26
12
 
27
- A declaration, not a client. A plain object saying what the provider does:
28
- which commands exist, how each response classifies, what the bank's status
29
- tokens mean, when statements can be fetched, which reference comes back on a
30
- debit. The runtime that executes it is generic and ships with the platform.
13
+ An adapter is a declaration, not a client. It is a plain object stating what the provider does: which commands exist, how responses classify, what bank status tokens mean, when statements can be fetched, and which reference returns on a debit. The generic execution runtime ships with the platform. An adapter opens no sockets, holds no credentials, and decides nothing about what a payment means.
31
14
 
32
- Your adapter opens no sockets, holds no credentials, and decides nothing about
33
- what a payment means. It states facts, and the checks in this package prove
34
- those facts are complete enough for a generic runtime to poll, classify,
35
- reconcile, and dedupe without guessing.
36
-
37
- Conformance checks a declaration. It does not contact a provider, verify a
38
- credential, certify regulatory readiness, or make a Product live.
15
+ Conformance checks a declaration. It does not contact a bank, verify a credential, certify regulatory readiness, or make a Product live.
39
16
 
40
17
  ## Install
41
18
 
@@ -43,13 +20,11 @@ credential, certify regulatory readiness, or make a Product live.
43
20
  npm install @hyperscale0/adl
44
21
  ```
45
22
 
46
- Every release before 1.0.0 is an alpha, and `latest` follows the newest one, so
47
- a bare install gets it. Pin an exact version if you need one: until 1.0.0 a
48
- change to the surface ships as a minor bump, not a major.
23
+ Pre-1.0 releases are prerelease versions (alpha and beta). Pin an exact version if needed: until 1.0.0, a change to the surface ships as a minor bump, not a major. The package has no runtime dependencies.
49
24
 
50
- No runtime dependencies, and no proprietary code imported.
25
+ ## Adapter declaration
51
26
 
52
- ## The thirty-second shape
27
+ A provider adapter declaration using verified package exports and the repository example profile:
53
28
 
54
29
  ```ts
55
30
  import {
@@ -57,12 +32,12 @@ import {
57
32
  createProviderAdapterRegistry,
58
33
  type ProviderAdapterVocabulary,
59
34
  } from "@hyperscale0/adl";
35
+ import { meridianProfile } from "./examples/meridian-bank/index.js";
60
36
 
61
37
  interface MyVocabulary extends ProviderAdapterVocabulary {
62
38
  capability: "payout_execution";
63
39
  operation: "payout.submit";
64
40
  resource: "payout";
65
- // ...the rest of your closed unions
66
41
  }
67
42
 
68
43
  const defineAdapters = createProviderAdapterRegistry<MyVocabulary>();
@@ -91,30 +66,18 @@ export const adapters = defineAdapters([
91
66
  config: {
92
67
  credentialRef: { source: "environment", name: "MERIDIAN_CREDENTIALS" },
93
68
  },
94
- profile: myBankProfile,
69
+ profile: meridianProfile,
95
70
  },
96
71
  ]);
97
72
 
98
- for (const adapter of adapters) certifyPartnerBankAdapter(adapter);
73
+ for (const adapter of adapters) {
74
+ certifyPartnerBankAdapter(adapter);
75
+ }
99
76
  ```
100
77
 
101
- `createProviderAdapterRegistry` validates at import and preserves your literal
102
- types. `certifyPartnerBankAdapter` throws with every gap listed at once; an
103
- empty finding list is the certification.
104
-
105
- ## Where to go next
78
+ `createProviderAdapterRegistry` validates at import and preserves literal types. `certifyPartnerBankAdapter` throws with every gap listed at once; an empty finding list is the certification.
106
79
 
107
- - **[docs/authoring-guide.md](docs/authoring-guide.md)**: the whole job, field
108
- by field, with the rule that enforces each one.
109
- - **[examples/meridian-bank](examples/meridian-bank)**: a complete certified
110
- adapter for a bank that does not exist, with fixtures and its own tests.
111
- Copy it.
112
- - **[conformance/cases.json](conformance/cases.json)**: every rule as data:
113
- one broken fact per case, and what each gate says about it.
114
- - **[spec/manifest.schema.json](spec/manifest.schema.json)**: JSON Schema
115
- 2020-12 for one declaration, for authors who are not writing TypeScript.
116
-
117
- ## Running conformance
80
+ Check an adapter declaration with conformance:
118
81
 
119
82
  ```bash
120
83
  bun run conformance -- ./examples/meridian-bank
@@ -126,43 +89,22 @@ ok meridian_bank:bank_credit
126
89
  2 adapter(s) checked, 0 finding(s) reported
127
90
  ```
128
91
 
129
- Exit 1 when anything reports, so it drops straight into CI.
92
+ The command exits 0 on success and 1 when findings are reported.
130
93
 
131
- ## Development
94
+ ## Documentation
132
95
 
133
- ```bash
134
- bun install
135
- bun run check # spec drift, tests, types
136
- bun run build
137
- ```
96
+ - [Authoring guide](docs/authoring-guide.md)
97
+ - [Meridian Bank example](examples/meridian-bank)
98
+ - [Conformance test cases](conformance/cases.json)
99
+ - [Manifest JSON schema](spec/manifest.schema.json)
100
+ - [Contributing](CONTRIBUTING.md)
138
101
 
139
102
  ## Versioning
140
103
 
141
- Semantic versioning from 1.0.0. Until then, alpha releases may change the
142
- surface on a minor version. Two promises hold now:
143
-
144
- - conformance codes are append-only: a released code is never renamed or
145
- removed, so `switch` statements stay exhaustive;
146
- - removing a value from a vocabulary in `src/vocabulary.ts` is a breaking
147
- change and appears in [CHANGELOG.md](CHANGELOG.md).
148
-
149
- ## Contributing
150
-
151
- Issues only. Hyperscale makes the changes to the format and the package; you
152
- propose them in an issue carrying the provider that needs the seam and the
153
- conformance case it would add. [CONTRIBUTING.md](CONTRIBUTING.md) has that
154
- model in full, plus the loop: what earns a new field, how to regenerate the
155
- schema, and the CLA behind a rare accepted pull request. Participation is under
156
- the [Code of Conduct](CODE_OF_CONDUCT.md).
104
+ Semantic versioning from 1.0.0. Until then, prereleases may change the surface on a minor version. Conformance codes are append-only: a released code is never renamed or removed. Removing a value from a vocabulary in `src/vocabulary.ts` is a breaking change documented in [CHANGELOG.md](CHANGELOG.md).
157
105
 
158
- Vulnerabilities go through GitHub private reporting, never a public issue. See
159
- [SECURITY.md](SECURITY.md).
106
+ ## License and security
160
107
 
161
- ## License
108
+ ADL is licensed under AGPL-3.0-only, with a commercial license available from Hyperscale LLC. See [LICENSE](LICENSE), [LICENSING.md](LICENSING.md), and [TRADEMARKS.md](TRADEMARKS.md).
162
109
 
163
- AGPL-3.0-only, with a commercial license available from Hyperscale LLC for
164
- organisations that cannot accept the AGPL. See [LICENSE](LICENSE) for the text
165
- and [LICENSING.md](LICENSING.md) for which one you want and how to ask for the
166
- commercial one. Neither covers the Hyperscale marks;
167
- [TRADEMARKS.md](TRADEMARKS.md) says what that means and carries the rule for
168
- claiming conformance.
110
+ Vulnerability reports go through private disclosure as described in [SECURITY.md](SECURITY.md).
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,yBAAyB,EAG1B,MAAM,YAAY,CAAC;AAGpB;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,kuBAyB9B,CAAC;AAEX,MAAM,MAAM,0BAA0B,GACpC,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/C,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAeD;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,UAAU,SAAS,yBAAyB,EAE5C,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,GACnC,SAAS,6BAA6B,EAAE,CA2B1C;AAED,+EAA+E;AAC/E,wBAAgB,yBAAyB,CACvC,UAAU,SAAS,yBAAyB,EAC5C,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,GAAG,IAAI,CAW5C"}
1
+ {"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,yBAAyB,EAG1B,MAAM,YAAY,CAAC;AAGpB;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,YACtC,8BAA8B,EAC9B,qBAAqB,EACrB,4BAA4B,EAC5B,gCAAgC,EAChC,+BAA+B,EAC/B,wBAAwB,EACxB,oCAAoC,EACpC,6BAA6B,EAC7B,gCAAgC,EAChC,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,EAC7B,yCAAyC,EACzC,yBAAyB,EACzB,0BAA0B,EAC1B,6BAA6B,EAC7B,uBAAuB,EACvB,gCAAgC,EAChC,6BAA6B,EAC7B,2BAA2B,EAC3B,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,CAClB,CAAC;AAEX,MAAM,MAAM,0BAA0B,GACpC,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/C,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAeD;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,UAAU,SAAS,yBAAyB,EAE5C,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,GACnC,SAAS,6BAA6B,EAAE,CA2B1C;AAED,+EAA+E;AAC/E,wBAAgB,yBAAyB,CACvC,UAAU,SAAS,yBAAyB,EAC5C,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,GAAG,IAAI,CAW5C"}
@@ -1 +1 @@
1
- {"version":3,"file":"vocabulary.d.ts","sourceRoot":"","sources":["../src/vocabulary.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vocabulary.d.ts","sourceRoot":"","sources":["../src/vocabulary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1200" height="360" viewBox="0 0 1200 360" role="img" aria-labelledby="title desc">
2
+ <title id="title">ADL</title>
3
+ <desc id="desc">Declare how a bank or provider behaves.</desc>
4
+ <rect width="1200" height="360" fill="#050505"/>
5
+ <path d="M48 48H1152M48 304H1152M944 48V304" fill="none" stroke="#303030"/>
6
+ <rect x="48" y="76" width="10" height="10" fill="#2f7dff"/>
7
+ <g font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">
8
+ <text x="72" y="86" fill="#a3a3a3" font-size="14" letter-spacing="2">HYPERSCALE / DOCUMENTATION</text>
9
+ <text x="44" y="194" fill="#ffffff" font-size="76" letter-spacing="-4">ADL</text>
10
+ <text x="48" y="243" fill="#a3a3a3" font-size="20">Declare how a bank or provider behaves.</text>
11
+ <text x="48" y="334" fill="#a3a3a3" font-size="12" letter-spacing="2">DECLARATION / VALIDATION / CONFORMANCE</text>
12
+ <text x="991" y="279" fill="#a3a3a3" font-size="12">SOURCE → CONTRACT</text>
13
+ </g>
14
+ <g fill="none" stroke="#2f7dff" stroke-width="2">
15
+ <path d="M990 110H1058V178H1126V246H1058V178H990Z"/>
16
+ <path d="M1058 110H1126V178H1058"/>
17
+ </g>
18
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperscale0/adl",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.3",
4
4
  "description": "The Adapter Declaration Language: provider adapter interfaces, registry validation, and the partner-bank conformance suite.",
5
5
  "keywords": [
6
6
  "adl",
@@ -67,13 +67,14 @@
67
67
  "typecheck": "tsc -p tsconfig.json"
68
68
  },
69
69
  "devDependencies": {
70
- "@types/bun": "1.4.0",
71
- "typescript": "6.0.3"
70
+ "bun-types": "1.4.2",
71
+ "typescript": "7.0.2"
72
72
  },
73
73
  "author": "Hyperscale LLC",
74
74
  "contributors": [
75
75
  "Meshael AlBakaawi",
76
76
  "Amir Ayub",
77
77
  "Sara AlBakaawi"
78
- ]
78
+ ],
79
+ "gitHead": "70ddac0ae5599ca61c7951b027befbeb6eea9f96"
79
80
  }
@@ -1,162 +0,0 @@
1
- /**
2
- * The example's own test, and the shape yours should take: conformance is
3
- * the gate, and the fixtures keep the declaration honest against the bytes
4
- * the bank actually sends. A declaration that certifies but cannot read its
5
- * own sandbox capture is not finished.
6
- */
7
-
8
- import { readFileSync } from "node:fs";
9
-
10
- import { partnerBankConformanceFindings } from "@hyperscale0/adl";
11
- import { describe, expect, test } from "bun:test";
12
-
13
- import { meridianAdapters, meridianProfile } from "./index.js";
14
-
15
- interface ExchangeFixture {
16
- readonly kind: "command" | "enquiry";
17
- readonly operation: string;
18
- readonly response: {
19
- readonly httpStatus: number;
20
- readonly body: Record<string, unknown>;
21
- };
22
- }
23
-
24
- interface StatementFixture {
25
- readonly format: string;
26
- readonly entries: readonly {
27
- readonly amount: string;
28
- readonly customerReference: string | null;
29
- readonly narrative: string;
30
- }[];
31
- }
32
-
33
- interface NotificationFixture {
34
- readonly eventKind: string;
35
- readonly payload: Record<string, unknown>;
36
- }
37
-
38
- function fixture<T>(name: string): T {
39
- return JSON.parse(
40
- readFileSync(new URL(`./fixtures/${name}.json`, import.meta.url), "utf8"),
41
- ) as T;
42
- }
43
-
44
- const exchanges = [
45
- fixture<ExchangeFixture>("payout-submit-accepted"),
46
- fixture<ExchangeFixture>("payout-submit-declined"),
47
- fixture<ExchangeFixture>("payout-status-settled"),
48
- fixture<ExchangeFixture>("payout-status-replay"),
49
- ];
50
- const statement = fixture<StatementFixture>("statement-camt053");
51
- const notification = fixture<NotificationFixture>("webhook-payout-settled");
52
-
53
- const [payoutAdapter] = meridianAdapters;
54
- if (!payoutAdapter) throw new Error("payout adapter missing");
55
-
56
- /** The same normalization a runtime uses to match a status token. */
57
- function normalize(token: string): string {
58
- return token.trim().toUpperCase();
59
- }
60
-
61
- const canonicalStateFor = new Map(
62
- Object.entries(meridianProfile.lifecycleVocabulary).map(
63
- ([spelling, state]) => [normalize(spelling), state as string],
64
- ),
65
- );
66
-
67
- describe("meridian bank adapter", () => {
68
- test("every capability certifies with zero findings", () => {
69
- for (const adapter of meridianAdapters) {
70
- expect({
71
- capability: adapter.capability,
72
- findings: partnerBankConformanceFindings(adapter),
73
- }).toEqual({ capability: adapter.capability, findings: [] });
74
- }
75
- });
76
-
77
- test("the lifecycle vocabulary spells every token the bank sends", () => {
78
- for (const exchange of exchanges) {
79
- const token = exchange.response.body["status"];
80
- expect(typeof token).toBe("string");
81
- expect(canonicalStateFor.get(normalize(token as string))).toBeDefined();
82
- }
83
- });
84
-
85
- test("the declared envelope class is how the fixtures actually read", () => {
86
- // http_status_error_body: the HTTP status carries the outcome and a
87
- // failure body is prose. Reading the body of a 2xx for a rejection, or
88
- // treating a 4xx as a lost response, would strand the payment.
89
- expect(payoutAdapter.operationMap["payout.submit"]?.envelope).toBe(
90
- "http_status_error_body",
91
- );
92
- for (const exchange of exchanges) {
93
- if (exchange.kind !== "command") continue;
94
- const state = canonicalStateFor.get(
95
- normalize(exchange.response.body["status"] as string),
96
- );
97
- if (state === "failed") {
98
- expect(exchange.response.httpStatus).toBeGreaterThanOrEqual(400);
99
- expect(typeof exchange.response.body["message"]).toBe("string");
100
- continue;
101
- }
102
- expect(exchange.response.httpStatus).toBeLessThan(400);
103
- }
104
- });
105
-
106
- test("the statement format is declared and has a fetch window", () => {
107
- const formats: readonly string[] = meridianProfile.statementFormats;
108
- expect(formats).toContain(statement.format);
109
- const windows: Record<string, unknown> = meridianProfile.windows.statements;
110
- expect(windows[statement.format]).toBeDefined();
111
- });
112
-
113
- test("the charge narratives recognize the bank's own debits", () => {
114
- const startsWithAny = (narrative: string, prefixes: readonly string[]) =>
115
- prefixes.some((prefix) => normalize(narrative).startsWith(prefix));
116
-
117
- const { charge, vat } = meridianProfile.charges.narratives;
118
- const chargeLines = statement.entries.filter((entry) =>
119
- startsWithAny(entry.narrative, charge),
120
- );
121
- const vatLines = statement.entries.filter((entry) =>
122
- startsWithAny(entry.narrative, vat),
123
- );
124
- expect(chargeLines).toHaveLength(1);
125
- expect(vatLines).toHaveLength(1);
126
- });
127
-
128
- test("an instructed payout is attributable on the statement", () => {
129
- // statementDebitReference says which reference comes back. Every debit
130
- // that is not one of the bank's own charge lines must carry it, or the
131
- // ledger cannot prove the debit was ours.
132
- expect(meridianProfile.statementDebitReference).toBe("customer_reference");
133
- const chargePrefixes = [
134
- ...meridianProfile.charges.narratives.charge,
135
- ...meridianProfile.charges.narratives.vat,
136
- ];
137
- const instructedDebits = statement.entries.filter(
138
- (entry) =>
139
- entry.amount.startsWith("-") &&
140
- !chargePrefixes.some((prefix) =>
141
- normalize(entry.narrative).startsWith(prefix),
142
- ),
143
- );
144
- expect(instructedDebits).not.toHaveLength(0);
145
- for (const debit of instructedDebits) {
146
- expect(typeof debit.customerReference).toBe("string");
147
- }
148
- });
149
-
150
- test("the webhook plan describes the callback the bank sends", () => {
151
- const plan = Object.entries(payoutAdapter.webhookMap).find(
152
- ([eventKind]) => eventKind === notification.eventKind,
153
- )?.[1];
154
- expect(plan).toBeDefined();
155
- if (!plan) return;
156
- for (const field of plan.requiredPayloadFields) {
157
- expect(notification.payload[field]).toBeDefined();
158
- }
159
- expect(notification.payload[plan.resourceIdField]).toBeDefined();
160
- expect(notification.payload[plan.timestampField]).toBeDefined();
161
- });
162
- });