@hyperscale0/hsx 1.0.0-rc.1 → 1.0.123
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 +5 -239
- package/LICENSE.md +356 -0
- package/NOTICE.md +8 -0
- package/README.md +45 -43
- package/bin/hsx.ts +0 -5
- package/dist/bin/hsx.d.ts +0 -4
- package/dist/bin/hsx.d.ts.map +1 -1
- package/dist/bin/hsx.js +0 -4
- package/dist/bin/hsx.js.map +1 -1
- package/dist/src/ast.d.ts +113 -302
- package/dist/src/ast.d.ts.map +1 -1
- package/dist/src/ast.js +7 -47
- package/dist/src/ast.js.map +1 -1
- package/dist/src/attachment-economics.d.ts +5 -0
- package/dist/src/attachment-economics.d.ts.map +1 -0
- package/dist/src/attachment-economics.js +55 -0
- package/dist/src/attachment-economics.js.map +1 -0
- package/dist/src/binding-contract.d.ts +22 -0
- package/dist/src/binding-contract.d.ts.map +1 -0
- package/dist/src/binding-contract.js +74 -0
- package/dist/src/binding-contract.js.map +1 -0
- package/dist/src/cli.d.ts +4 -17
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +92 -259
- package/dist/src/cli.js.map +1 -1
- package/dist/src/compile.d.ts +34 -68
- package/dist/src/compile.d.ts.map +1 -1
- package/dist/src/compile.js +2949 -118
- package/dist/src/compile.js.map +1 -1
- package/dist/src/cost.d.ts +8 -75
- package/dist/src/cost.d.ts.map +1 -1
- package/dist/src/cost.js +54 -364
- package/dist/src/cost.js.map +1 -1
- package/dist/src/diagnostics.d.ts +14 -9
- package/dist/src/diagnostics.d.ts.map +1 -1
- package/dist/src/diagnostics.js +39 -416
- package/dist/src/diagnostics.js.map +1 -1
- package/dist/src/examples-bundle.d.ts +3 -0
- package/dist/src/examples-bundle.d.ts.map +1 -0
- package/dist/src/examples-bundle.js +18 -0
- package/dist/src/examples-bundle.js.map +1 -0
- package/dist/src/examples.d.ts +10 -0
- package/dist/src/examples.d.ts.map +1 -0
- package/dist/src/examples.js +2 -0
- package/dist/src/examples.js.map +1 -0
- package/dist/src/format.d.ts +8 -7
- package/dist/src/format.d.ts.map +1 -1
- package/dist/src/format.js +9 -175
- package/dist/src/format.js.map +1 -1
- package/dist/src/header-source.d.ts +3 -0
- package/dist/src/header-source.d.ts.map +1 -0
- package/dist/src/header-source.js +41 -0
- package/dist/src/header-source.js.map +1 -0
- package/dist/src/headers.d.ts +64 -0
- package/dist/src/headers.d.ts.map +1 -0
- package/dist/src/headers.js +167 -0
- package/dist/src/headers.js.map +1 -0
- package/dist/src/index.d.ts +8 -11
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/keywords.d.ts +56 -0
- package/dist/src/keywords.d.ts.map +1 -0
- package/dist/src/keywords.js +133 -0
- package/dist/src/keywords.js.map +1 -0
- package/dist/src/language.d.ts +26 -0
- package/dist/src/language.d.ts.map +1 -0
- package/dist/src/language.js +440 -0
- package/dist/src/language.js.map +1 -0
- package/dist/src/lex.d.ts +13 -28
- package/dist/src/lex.d.ts.map +1 -1
- package/dist/src/lex.js +119 -145
- package/dist/src/lex.js.map +1 -1
- package/dist/src/parse.d.ts +4 -17
- package/dist/src/parse.d.ts.map +1 -1
- package/dist/src/parse.js +484 -1036
- package/dist/src/parse.js.map +1 -1
- package/dist/src/std-bundle.d.ts +2 -0
- package/dist/src/std-bundle.d.ts.map +1 -0
- package/dist/src/std-bundle.js +15 -0
- package/dist/src/std-bundle.js.map +1 -0
- package/dist/src/std-library.d.ts +5 -0
- package/dist/src/std-library.d.ts.map +1 -0
- package/dist/src/std-library.js +5 -0
- package/dist/src/std-library.js.map +1 -0
- package/dist/src/tunables.d.ts +7 -0
- package/dist/src/tunables.d.ts.map +1 -0
- package/dist/src/tunables.js +27 -0
- package/dist/src/tunables.js.map +1 -0
- package/docs/README.md +528 -23
- package/docs/assets/brand/hsx-horizontal-white.svg +1 -0
- package/docs/assets/brand/hsx-horizontal.svg +1 -0
- package/docs/assets/brand/hsx-stacked-white.svg +1 -0
- package/docs/assets/brand/hsx-stacked.svg +1 -0
- package/docs/assets/brand/manifest.json +30 -0
- package/docs/assets/hsx.svg +11 -0
- package/examples/cards.hsx +34 -0
- package/examples/collections.hsx +37 -0
- package/examples/cost-table.json +633 -385
- package/examples/escrow.hsx +24 -0
- package/examples/financing.hsx +32 -0
- package/examples/insurance.hsx +30 -0
- package/examples/lending.hsx +57 -0
- package/examples/library.hsx +15 -0
- package/examples/marketplace.hsx +32 -0
- package/examples/money.hsx +19 -0
- package/examples/rental-deposit.hsx +60 -0
- package/examples/repair-approval.hsx +44 -0
- package/examples/reporting.hsx +28 -0
- package/examples/savings.hsx +21 -0
- package/examples/serviced.hsx +25 -0
- package/examples/wallet.hsx +24 -0
- package/package.json +27 -17
- package/src/ast.ts +84 -411
- package/src/attachment-economics.ts +103 -0
- package/src/binding-contract.ts +104 -0
- package/src/cli.ts +98 -309
- package/src/compile.ts +4063 -212
- package/src/cost.ts +71 -574
- package/src/diagnostics.ts +57 -437
- package/src/examples-bundle.ts +19 -0
- package/src/examples.ts +9 -0
- package/src/format.ts +12 -256
- package/src/header-source.ts +54 -0
- package/src/headers.ts +195 -0
- package/src/index.ts +16 -29
- package/src/keywords.ts +134 -0
- package/src/language.ts +629 -0
- package/src/lex.ts +131 -192
- package/src/parse.ts +489 -1195
- package/src/std-bundle.ts +15 -0
- package/src/std-library.ts +7 -0
- package/src/tunables.ts +36 -0
- package/std/cards.hsx +85 -0
- package/std/collections.hsx +90 -0
- package/std/escrow.hsx +73 -0
- package/std/financing.hsx +683 -0
- package/std/insurance.hsx +89 -0
- package/std/lending.hsx +138 -0
- package/std/marketplace.hsx +123 -0
- package/std/money.hsx +173 -0
- package/std/reporting.hsx +753 -0
- package/std/savings.hsx +68 -0
- package/std/wallet.hsx +57 -0
- package/LICENSE +0 -661
- package/LICENSING.md +0 -52
- package/TRADEMARKS.md +0 -35
- package/dist/src/emit.d.ts +0 -35
- package/dist/src/emit.d.ts.map +0 -1
- package/dist/src/emit.js +0 -359
- package/dist/src/emit.js.map +0 -1
- package/dist/src/entry-overrides.d.ts +0 -58
- package/dist/src/entry-overrides.d.ts.map +0 -1
- package/dist/src/entry-overrides.js +0 -284
- package/dist/src/entry-overrides.js.map +0 -1
- package/dist/src/ir.d.ts +0 -66
- package/dist/src/ir.d.ts.map +0 -1
- package/dist/src/ir.js +0 -15
- package/dist/src/ir.js.map +0 -1
- package/dist/src/limits.d.ts +0 -21
- package/dist/src/limits.d.ts.map +0 -1
- package/dist/src/limits.js +0 -21
- package/dist/src/limits.js.map +0 -1
- package/dist/src/modules.d.ts +0 -36
- package/dist/src/modules.d.ts.map +0 -1
- package/dist/src/modules.js +0 -372
- package/dist/src/modules.js.map +0 -1
- package/dist/src/typecheck.d.ts +0 -8
- package/dist/src/typecheck.d.ts.map +0 -1
- package/dist/src/typecheck.js +0 -2958
- package/dist/src/typecheck.js.map +0 -1
- package/dist/src/version.d.ts +0 -5
- package/dist/src/version.d.ts.map +0 -1
- package/dist/src/version.js +0 -5
- package/dist/src/version.js.map +0 -1
- package/docs/guide/01-first-program.md +0 -24
- package/docs/guide/02-money.md +0 -25
- package/docs/guide/03-instruments.md +0 -22
- package/docs/guide/04-lifecycles.md +0 -25
- package/docs/guide/05-fees-and-splits.md +0 -45
- package/docs/guide/06-schedules.md +0 -22
- package/docs/guide/07-composition.md +0 -46
- package/docs/guide/08-writing-a-module.md +0 -26
- package/docs/guide/09-cost.md +0 -24
- package/docs/guide/10-diagnostics.md +0 -27
- package/docs/llms-full.txt +0 -1738
- package/docs/llms.txt +0 -45
- package/docs/reference/cli.md +0 -33
- package/docs/reference/diagnostics.md +0 -619
- package/docs/reference/grammar.md +0 -39
- package/docs/reference/std/advance.md +0 -35
- package/docs/reference/std/cancellable_booking.md +0 -35
- package/docs/reference/std/captured_payment.md +0 -43
- package/docs/reference/std/conditional_disbursement.md +0 -33
- package/docs/reference/std/credit_facility.md +0 -35
- package/docs/reference/std/held_payment.md +0 -64
- package/docs/reference/std/instant_transfer.md +0 -30
- package/docs/reference/std/metered.md +0 -27
- package/docs/reference/std/pooled_split.md +0 -26
- package/docs/reference/std/premium_forward.md +0 -39
- package/docs/reference/std/reconciled_payout.md +0 -33
- package/docs/reference/std/recurring_collection.md +0 -25
- package/docs/reference/std/rotating_pool.md +0 -42
- package/docs/reference/std/scheduled.md +0 -51
- package/docs/reference/std/security_deposit.md +0 -46
- package/docs/reference/std/settlement_batch.md +0 -42
- package/docs/reference/std/swap.md +0 -46
- package/docs/reference/std/threshold_pool.md +0 -47
- package/docs/reference/std/weighted_distribution.md +0 -39
- package/docs/reference/types.md +0 -20
- package/docs/reference/udl-output.md +0 -14
- package/docs/sessions/2026-09-02-two-instruments.hsx +0 -21
- package/docs/sessions/2026-09-02-two-instruments.md +0 -41
- package/examples/01-first-program/README.md +0 -45
- package/examples/01-first-program/tip-jar.hsx +0 -17
- package/examples/02-imports-and-archetypes/README.md +0 -99
- package/examples/02-imports-and-archetypes/photo-booth.hsx +0 -37
- package/examples/03-diagnostics/README.md +0 -68
- package/examples/03-diagnostics/corner-shop-fixed.hsx +0 -22
- package/examples/03-diagnostics/corner-shop.hsx +0 -19
- package/examples/04-complete-product/README.md +0 -87
- package/examples/04-complete-product/study-hall.hsx +0 -67
- package/examples/05-watch-club/README.md +0 -9
- package/examples/05-watch-club/watch-club.hsx +0 -124
- package/examples/README.md +0 -18
- package/examples/advance/README.md +0 -3
- package/examples/advance/advance.hsx +0 -13
- package/examples/advance/advance.udl +0 -339
- package/examples/cancellable_booking/README.md +0 -3
- package/examples/cancellable_booking/cancellable_booking.hsx +0 -14
- package/examples/cancellable_booking/cancellable_booking.udl +0 -391
- package/examples/captured_payment/README.md +0 -3
- package/examples/captured_payment/captured_payment.hsx +0 -21
- package/examples/captured_payment/captured_payment.udl +0 -677
- package/examples/conditional_disbursement/README.md +0 -3
- package/examples/conditional_disbursement/conditional_disbursement.hsx +0 -17
- package/examples/conditional_disbursement/conditional_disbursement.udl +0 -412
- package/examples/credit_facility/README.md +0 -3
- package/examples/credit_facility/credit_facility.hsx +0 -27
- package/examples/credit_facility/credit_facility.udl +0 -1373
- package/examples/held_payment/README.md +0 -3
- package/examples/held_payment/held_payment.hsx +0 -13
- package/examples/held_payment/held_payment.udl +0 -507
- package/examples/instant_transfer/README.md +0 -3
- package/examples/instant_transfer/instant_transfer.hsx +0 -16
- package/examples/instant_transfer/instant_transfer.udl +0 -364
- package/examples/metered/README.md +0 -3
- package/examples/metered/metered.hsx +0 -13
- package/examples/metered/metered.udl +0 -247
- package/examples/pooled_split/README.md +0 -3
- package/examples/pooled_split/pooled_split.hsx +0 -15
- package/examples/pooled_split/pooled_split.udl +0 -425
- package/examples/premium_forward/README.md +0 -3
- package/examples/premium_forward/premium_forward.hsx +0 -19
- package/examples/premium_forward/premium_forward.udl +0 -594
- package/examples/reconciled_payout/README.md +0 -3
- package/examples/reconciled_payout/reconciled_payout.hsx +0 -13
- package/examples/reconciled_payout/reconciled_payout.udl +0 -303
- package/examples/recurring_collection/README.md +0 -3
- package/examples/recurring_collection/recurring_collection.hsx +0 -21
- package/examples/recurring_collection/recurring_collection.udl +0 -1130
- package/examples/rotating_pool/README.md +0 -3
- package/examples/rotating_pool/rotating_pool.hsx +0 -18
- package/examples/rotating_pool/rotating_pool.udl +0 -4352
- package/examples/scheduled/README.md +0 -3
- package/examples/scheduled/scheduled.hsx +0 -12
- package/examples/scheduled/scheduled.udl +0 -335
- package/examples/security_deposit/README.md +0 -3
- package/examples/security_deposit/security_deposit.hsx +0 -21
- package/examples/security_deposit/security_deposit.udl +0 -293
- package/examples/settlement_batch/README.md +0 -3
- package/examples/settlement_batch/settlement_batch.hsx +0 -19
- package/examples/settlement_batch/settlement_batch.udl +0 -753
- package/examples/swap/README.md +0 -3
- package/examples/swap/swap.hsx +0 -19
- package/examples/swap/swap.udl +0 -876
- package/examples/threshold_pool/README.md +0 -3
- package/examples/threshold_pool/threshold_pool.hsx +0 -16
- package/examples/threshold_pool/threshold_pool.udl +0 -667
- package/examples/weighted_distribution/README.md +0 -3
- package/examples/weighted_distribution/weighted_distribution.hsx +0 -20
- package/examples/weighted_distribution/weighted_distribution.udl +0 -337
- package/skills/hsx/SKILL.md +0 -483
- package/src/emit.ts +0 -447
- package/src/entry-overrides.ts +0 -428
- package/src/ir.ts +0 -99
- package/src/limits.ts +0 -20
- package/src/modules.ts +0 -444
- package/src/typecheck.ts +0 -3876
- package/src/version.ts +0 -5
- package/std/SEMANTICS.md +0 -130
- package/std/settlements/advance.hsx +0 -177
- package/std/settlements/cancellable_booking.hsx +0 -87
- package/std/settlements/captured_payment.hsx +0 -144
- package/std/settlements/conditional_disbursement.hsx +0 -185
- package/std/settlements/credit_facility.hsx +0 -167
- package/std/settlements/held_payment.hsx +0 -578
- package/std/settlements/index.hsx +0 -3
- package/std/settlements/instant_transfer.hsx +0 -190
- package/std/settlements/metered.hsx +0 -67
- package/std/settlements/pooled_split.hsx +0 -68
- package/std/settlements/premium_forward.hsx +0 -257
- package/std/settlements/reconciled_payout.hsx +0 -77
- package/std/settlements/recurring_collection.hsx +0 -27
- package/std/settlements/rotating_pool.hsx +0 -252
- package/std/settlements/scheduled.hsx +0 -641
- package/std/settlements/security_deposit.hsx +0 -166
- package/std/settlements/settlement_batch.hsx +0 -122
- package/std/settlements/swap.hsx +0 -1114
- package/std/settlements/threshold_pool.hsx +0 -221
- package/std/settlements/weighted_distribution.hsx +0 -141
package/dist/src/ast.js
CHANGED
|
@@ -1,48 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*/
|
|
9
|
-
/** Convert a byte offset to a 1-indexed line/column position. */
|
|
10
|
-
export function lineColAt(source, offset) {
|
|
11
|
-
let line = 1;
|
|
12
|
-
let lineStart = 0;
|
|
13
|
-
const clamped = Math.max(0, Math.min(offset, source.length));
|
|
14
|
-
for (let index = 0; index < clamped; index += 1) {
|
|
15
|
-
if (source.charCodeAt(index) === 10) {
|
|
16
|
-
line += 1;
|
|
17
|
-
lineStart = index + 1;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return { column: clamped - lineStart + 1, line };
|
|
21
|
-
}
|
|
22
|
-
/** Scan a source once for the offset every line starts at. */
|
|
23
|
-
export function lineIndex(source) {
|
|
24
|
-
const starts = [0];
|
|
25
|
-
for (let index = 0; index < source.length; index += 1) {
|
|
26
|
-
if (source.charCodeAt(index) === 10)
|
|
27
|
-
starts.push(index + 1);
|
|
28
|
-
}
|
|
29
|
-
return { length: source.length, starts };
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Resolve one offset against a prebuilt index. Returns exactly what
|
|
33
|
-
* `lineColAt` returns for the same source and offset.
|
|
34
|
-
*/
|
|
35
|
-
export function lineColIn(index, offset) {
|
|
36
|
-
const clamped = Math.max(0, Math.min(offset, index.length));
|
|
37
|
-
let low = 0;
|
|
38
|
-
let high = index.starts.length - 1;
|
|
39
|
-
while (low < high) {
|
|
40
|
-
const middle = Math.floor((low + high + 1) / 2);
|
|
41
|
-
if (index.starts[middle] <= clamped)
|
|
42
|
-
low = middle;
|
|
43
|
-
else
|
|
44
|
-
high = middle - 1;
|
|
45
|
-
}
|
|
46
|
-
return { column: clamped - index.starts[low] + 1, line: low + 1 };
|
|
47
|
-
}
|
|
1
|
+
export const lineColAt = (source, offset) => {
|
|
2
|
+
const before = source.slice(0, offset);
|
|
3
|
+
return {
|
|
4
|
+
line: before.split("\n").length,
|
|
5
|
+
column: offset - before.lastIndexOf("\n"),
|
|
6
|
+
};
|
|
7
|
+
};
|
|
48
8
|
//# sourceMappingURL=ast.js.map
|
package/dist/src/ast.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":"AAuFA,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,MAAc,EAAE,EAAE;IAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM;QAC/B,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;KAC1C,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type AttachmentPartyBinding, type UdlDocument, type UdlInstrument } from "@hyperscale0/udl";
|
|
2
|
+
import type { Entry, Expr } from "./ast.ts";
|
|
3
|
+
/** An attachment specializes its own instrument; imported definitions stay generic. */
|
|
4
|
+
export declare function applyAttachmentEconomics(document: UdlDocument, instrument: UdlInstrument, parties: Record<string, AttachmentPartyBinding>, declarations: Entry[], data: (expression: Expr) => unknown): void;
|
|
5
|
+
//# sourceMappingURL=attachment-economics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-economics.d.ts","sourceRoot":"","sources":["../../src/attachment-economics.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,sBAAsB,EAE3B,KAAK,WAAW,EAChB,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAG5C,uFAAuF;AACvF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,WAAW,EACrB,UAAU,EAAE,aAAa,EACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC/C,YAAY,EAAE,KAAK,EAAE,EACrB,IAAI,EAAE,CAAC,UAAU,EAAE,IAAI,KAAK,OAAO,GAClC,IAAI,CAoFN"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { subjectPartyRoles, udlMoveSchema, } from "@hyperscale0/udl";
|
|
2
|
+
import { fail } from "./diagnostics.js";
|
|
3
|
+
/** An attachment specializes its own instrument; imported definitions stay generic. */
|
|
4
|
+
export function applyAttachmentEconomics(document, instrument, parties, declarations, data) {
|
|
5
|
+
const selected = new Set();
|
|
6
|
+
for (const declaration of declarations) {
|
|
7
|
+
const selector = declaration.key.slice("economics ".length);
|
|
8
|
+
const [actionName, moveKey, extra] = selector.split(".");
|
|
9
|
+
const action = Object.hasOwn(instrument.actions, actionName)
|
|
10
|
+
? instrument.actions[actionName]
|
|
11
|
+
: undefined;
|
|
12
|
+
if (!action)
|
|
13
|
+
fail(declaration, `unknown economics action ${actionName}`, `choose ${instrument.actionOrder.join(", ")}, before its public alias`);
|
|
14
|
+
const move = moveKey
|
|
15
|
+
? action.moves.find((move) => move.key === moveKey)
|
|
16
|
+
: action.moves.length === 1
|
|
17
|
+
? action.moves[0]
|
|
18
|
+
: undefined;
|
|
19
|
+
if (!move || extra)
|
|
20
|
+
fail(declaration, `economics ${selector} must select one money move`, action.moves.length
|
|
21
|
+
? `choose ${action.moves.map((move) => `${actionName}.${move.key}`).join(", ")}`
|
|
22
|
+
: "choose an action that transfers or reserves money");
|
|
23
|
+
if (move.operation === "internal_transfer.void")
|
|
24
|
+
fail(declaration, `economics ${selector} cannot classify a void`, "declare the purpose on the reservation or its posting");
|
|
25
|
+
if (selected.has(move))
|
|
26
|
+
fail(declaration, `repeated economics for ${selector}`, "declare each money move's purpose once");
|
|
27
|
+
selected.add(move);
|
|
28
|
+
const parsed = udlMoveSchema.safeParse({
|
|
29
|
+
...move,
|
|
30
|
+
economics: data(declaration.value),
|
|
31
|
+
});
|
|
32
|
+
if (!parsed.success || !parsed.data.economics)
|
|
33
|
+
fail(declaration, `invalid economics for ${selector}`, "declare purpose and sourceParty using the move economics fields");
|
|
34
|
+
const economics = parsed.data.economics;
|
|
35
|
+
if (move.economics &&
|
|
36
|
+
(move.economics.purpose !== economics.purpose ||
|
|
37
|
+
move.economics.sourceParty !== economics.sourceParty ||
|
|
38
|
+
move.economics.reversalOf !== economics.reversalOf))
|
|
39
|
+
fail(declaration, `economics ${selector} conflicts with the instrument's declared purpose`, "keep the instrument's economics or choose an unclassified move");
|
|
40
|
+
const source = economics.sourceParty;
|
|
41
|
+
const role = subjectPartyRoles.includes(source);
|
|
42
|
+
if (!role && document.parties[source]?.kind !== "business")
|
|
43
|
+
fail(declaration, `unknown economic source party ${source}`, "bind sourceParty to owner, actor, operator or a declared business");
|
|
44
|
+
if (!Object.values(parties).some((binding) => "role" in binding ? binding.role === source : binding.party === source)) {
|
|
45
|
+
let key = "economicSource";
|
|
46
|
+
for (let index = 2; Object.hasOwn(parties, key); index++)
|
|
47
|
+
key = `economicSource${index}`;
|
|
48
|
+
parties[key] = role
|
|
49
|
+
? { role: source }
|
|
50
|
+
: { party: source };
|
|
51
|
+
}
|
|
52
|
+
move.economics = economics;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=attachment-economics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-economics.js","sourceRoot":"","sources":["../../src/attachment-economics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Entry, InstrumentDecl } from "./ast.ts";
|
|
2
|
+
export declare class BindingContractError extends Error {
|
|
3
|
+
readonly entry: Entry;
|
|
4
|
+
constructor(entry: Entry, message: string);
|
|
5
|
+
}
|
|
6
|
+
/** Conditional requirements are header data, independent of module names. */
|
|
7
|
+
export declare function bindingDependencies(decl: InstrumentDecl): {
|
|
8
|
+
binding: string;
|
|
9
|
+
when: string;
|
|
10
|
+
is: string;
|
|
11
|
+
message: string;
|
|
12
|
+
fix: string;
|
|
13
|
+
span: import("./ast.ts").Span;
|
|
14
|
+
}[];
|
|
15
|
+
/** A header explains why a typed parameter cannot encode a proposed policy. */
|
|
16
|
+
export declare function parameterDiagnostics(decl: InstrumentDecl): {
|
|
17
|
+
parameter: string;
|
|
18
|
+
accepts: string;
|
|
19
|
+
percentage: string;
|
|
20
|
+
fix: string;
|
|
21
|
+
}[];
|
|
22
|
+
//# sourceMappingURL=binding-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-contract.d.ts","sourceRoot":"","sources":["../../src/binding-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAC;AAE5D,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,QAAQ,CAAC,KAAK,EAAE,KAAK;IADvB,YACW,KAAK,EAAE,KAAK,EACrB,OAAO,EAAE,MAAM,EAGhB;CACF;AAkDD,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc;;;;;;;IA8BvD;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc;;;;;IAUxD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export class BindingContractError extends Error {
|
|
2
|
+
entry;
|
|
3
|
+
constructor(entry, message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.entry = entry;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
function rows(value) {
|
|
9
|
+
if (value.kind === "block")
|
|
10
|
+
return value.entries;
|
|
11
|
+
throw new BindingContractError({ key: "contract", value, span: value.span }, "Binding contract needs a block.");
|
|
12
|
+
}
|
|
13
|
+
function properties(entry, allowed) {
|
|
14
|
+
const result = new Map();
|
|
15
|
+
for (const slot of rows(entry.value)) {
|
|
16
|
+
if (!allowed.includes(slot.key) ||
|
|
17
|
+
result.has(slot.key) ||
|
|
18
|
+
(slot.value.kind !== "text" && slot.value.kind !== "name"))
|
|
19
|
+
throw new BindingContractError(slot, "Invalid binding contract property.");
|
|
20
|
+
result.set(slot.key, slot.value.value);
|
|
21
|
+
}
|
|
22
|
+
if (allowed.some((key) => !result.get(key)))
|
|
23
|
+
throw new BindingContractError(entry, `Binding contract needs ${allowed.join(", ")}.`);
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
function contractEntries(decl, name) {
|
|
27
|
+
const blocks = decl.body.entries.filter((entry) => entry.key === name);
|
|
28
|
+
if (blocks.length > 1)
|
|
29
|
+
throw new BindingContractError(blocks[1], `Duplicate ${name}.`);
|
|
30
|
+
const entries = blocks[0] ? rows(blocks[0].value) : [];
|
|
31
|
+
const seen = new Set();
|
|
32
|
+
for (const entry of entries) {
|
|
33
|
+
if (seen.has(entry.key) ||
|
|
34
|
+
!decl.parameters.some((parameter) => parameter.key === entry.key))
|
|
35
|
+
throw new BindingContractError(entry, "Binding contract must name each declared tunable once.");
|
|
36
|
+
seen.add(entry.key);
|
|
37
|
+
}
|
|
38
|
+
return entries;
|
|
39
|
+
}
|
|
40
|
+
/** Conditional requirements are header data, independent of module names. */
|
|
41
|
+
export function bindingDependencies(decl) {
|
|
42
|
+
return contractEntries(decl, "dependencies").map((entry) => {
|
|
43
|
+
const values = properties(entry, ["selector", "is", "message", "fix"]);
|
|
44
|
+
const selector = decl.parameters.find((parameter) => parameter.key === values.get("selector"));
|
|
45
|
+
const type = selector?.value.kind === "default"
|
|
46
|
+
? selector.value.type
|
|
47
|
+
: selector?.value;
|
|
48
|
+
if (type?.kind !== "call" ||
|
|
49
|
+
type.name !== "enum" ||
|
|
50
|
+
!type.args.some((arg) => arg.kind === "name" && arg.value === values.get("is")))
|
|
51
|
+
throw new BindingContractError(entry, "Dependency must select a declared enum choice.");
|
|
52
|
+
return {
|
|
53
|
+
binding: entry.key,
|
|
54
|
+
when: values.get("selector"),
|
|
55
|
+
is: values.get("is"),
|
|
56
|
+
message: values.get("message"),
|
|
57
|
+
fix: values.get("fix"),
|
|
58
|
+
span: entry.span,
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/** A header explains why a typed parameter cannot encode a proposed policy. */
|
|
63
|
+
export function parameterDiagnostics(decl) {
|
|
64
|
+
return contractEntries(decl, "parameterDiagnostics").map((entry) => {
|
|
65
|
+
const values = properties(entry, ["accepts", "percentage", "fix"]);
|
|
66
|
+
return {
|
|
67
|
+
parameter: entry.key,
|
|
68
|
+
accepts: values.get("accepts"),
|
|
69
|
+
percentage: values.get("percentage"),
|
|
70
|
+
fix: values.get("fix"),
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=binding-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-contract.js","sourceRoot":"","sources":["../../src/binding-contract.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli.d.ts
CHANGED
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The `hsx` command line over the one compiler entry point and catalog.
|
|
3
|
-
*
|
|
4
|
-
* `check` prints diagnostics and says nothing else; `build` writes the
|
|
5
|
-
* compiled artifacts as JSON. Neither reads the environment, neither touches
|
|
6
|
-
* a network, and neither writes outside the path the caller names.
|
|
7
|
-
*
|
|
8
|
-
* Everything here is a pure function of `argv` plus the injected `Io`, so the
|
|
9
|
-
* spec drives the real code paths with an in-memory filesystem instead of
|
|
10
|
-
* asserting on a subprocess's scrollback.
|
|
11
|
-
*/
|
|
12
|
-
/** Filesystem and streams, injected so the CLI stays testable. */
|
|
13
1
|
export interface Io {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
out(line: string): void;
|
|
3
|
+
err(line: string): void;
|
|
4
|
+
readFile(path: string): Promise<string>;
|
|
5
|
+
writeFile(path: string, text: string): Promise<void>;
|
|
18
6
|
}
|
|
19
|
-
export declare const USAGE_TEXT = "hsx 1.0.0-rc.1, the HSX compiler\n\nUsage:\n hsx check <file.hsx> [--strict]\n hsx build <file.hsx> [--out <file.json>] [--strict]\n hsx cost <file.hsx> [--json] [--out <file.json>] [--strict]\n hsx explain <HSX####>\n hsx format <file.hsx>\n hsx --version\n hsx --help\n\nCommands:\n check Compile and report diagnostics. Prints nothing when the program is clean.\n build Compile and write canonical UDL and its Business Frame as JSON.\n cost Compile and print the version-pinned cost manifest as a table or JSON.\n explain Print one diagnostic title, fix, and source example.\n format Print the source in the one canonical HSX style.\n\nOptions:\n --json Print the cost manifest as JSON instead of a table.\n --out <file> Write build or cost JSON to this path instead of stdout.\n --strict Treat warning-severity diagnostics as failures.\n\nExit codes:\n 0 the program compiled (verdict valid, or warning without --strict)\n 1 the program was refused (verdict invalid, or warning with --strict)\n 2 the command line or the input file could not be used";
|
|
20
7
|
export declare function runCli(argv: readonly string[], io: Io): Promise<number>;
|
|
21
8
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/src/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,EAAE;IACjB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtD;AACD,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAiF7E"}
|
package/dist/src/cli.js
CHANGED
|
@@ -1,273 +1,106 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* `check` prints diagnostics and says nothing else; `build` writes the
|
|
5
|
-
* compiled artifacts as JSON. Neither reads the environment, neither touches
|
|
6
|
-
* a network, and neither writes outside the path the caller names.
|
|
7
|
-
*
|
|
8
|
-
* Everything here is a pure function of `argv` plus the injected `Io`, so the
|
|
9
|
-
* spec drives the real code paths with an in-memory filesystem instead of
|
|
10
|
-
* asserting on a subprocess's scrollback.
|
|
11
|
-
*/
|
|
12
|
-
import { fileURLToPath } from "node:url";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { headerManifest } from "./headers.js";
|
|
13
4
|
import { compile } from "./compile.js";
|
|
14
|
-
import { hsxDiagnostics } from "./diagnostics.js";
|
|
15
5
|
import { format } from "./format.js";
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export const USAGE_TEXT = `hsx ${HSX_VERSION}, the HSX compiler
|
|
25
|
-
|
|
26
|
-
Usage:
|
|
27
|
-
hsx check <file.hsx> [--strict]
|
|
28
|
-
hsx build <file.hsx> [--out <file.json>] [--strict]
|
|
29
|
-
hsx cost <file.hsx> [--json] [--out <file.json>] [--strict]
|
|
30
|
-
hsx explain <HSX####>
|
|
31
|
-
hsx format <file.hsx>
|
|
32
|
-
hsx --version
|
|
33
|
-
hsx --help
|
|
34
|
-
|
|
35
|
-
Commands:
|
|
36
|
-
check Compile and report diagnostics. Prints nothing when the program is clean.
|
|
37
|
-
build Compile and write canonical UDL and its Business Frame as JSON.
|
|
38
|
-
cost Compile and print the version-pinned cost manifest as a table or JSON.
|
|
39
|
-
explain Print one diagnostic title, fix, and source example.
|
|
40
|
-
format Print the source in the one canonical HSX style.
|
|
41
|
-
|
|
42
|
-
Options:
|
|
43
|
-
--json Print the cost manifest as JSON instead of a table.
|
|
44
|
-
--out <file> Write build or cost JSON to this path instead of stdout.
|
|
45
|
-
--strict Treat warning-severity diagnostics as failures.
|
|
46
|
-
|
|
47
|
-
Exit codes:
|
|
48
|
-
0 the program compiled (verdict valid, or warning without --strict)
|
|
49
|
-
1 the program was refused (verdict invalid, or warning with --strict)
|
|
50
|
-
2 the command line or the input file could not be used`;
|
|
51
|
-
export async function runCli(argv, io) {
|
|
52
|
-
const [command, ...rest] = argv;
|
|
53
|
-
if (command === undefined || command === "--help" || command === "-h") {
|
|
54
|
-
io.out(USAGE_TEXT);
|
|
55
|
-
return command === undefined ? USAGE : OK;
|
|
56
|
-
}
|
|
57
|
-
if (command === "--version" || command === "-v") {
|
|
58
|
-
io.out(`${HSX_VERSION} (UDL version ${HSX_TARGET_UDL_VERSION})`);
|
|
59
|
-
return OK;
|
|
60
|
-
}
|
|
61
|
-
if (command === "explain")
|
|
62
|
-
return explainDiagnostic(rest, io);
|
|
63
|
-
if (command !== "check" &&
|
|
64
|
-
command !== "build" &&
|
|
65
|
-
command !== "cost" &&
|
|
66
|
-
command !== "format") {
|
|
67
|
-
io.err(`hsx: unknown command "${command}"`);
|
|
68
|
-
io.err(USAGE_TEXT);
|
|
69
|
-
return USAGE;
|
|
70
|
-
}
|
|
71
|
-
const parsed = parseOptions(rest, command);
|
|
72
|
-
if ("error" in parsed) {
|
|
73
|
-
io.err(`hsx: ${parsed.error}`);
|
|
74
|
-
return USAGE;
|
|
75
|
-
}
|
|
76
|
-
let source;
|
|
77
|
-
try {
|
|
78
|
-
source = await io.readFile(parsed.file);
|
|
79
|
-
}
|
|
80
|
-
catch (cause) {
|
|
81
|
-
io.err(`hsx: cannot read ${parsed.file}: ${messageOf(cause)}`);
|
|
82
|
-
return USAGE;
|
|
83
|
-
}
|
|
84
|
-
if (command === "format") {
|
|
85
|
-
const result = format(source);
|
|
86
|
-
if (!result.ok) {
|
|
87
|
-
for (const diagnostic of result.diagnostics) {
|
|
88
|
-
io.err(`${parsed.file}:1:1: error [parse] ${diagnostic.message}`);
|
|
89
|
-
}
|
|
90
|
-
return REFUSED;
|
|
6
|
+
import { serializeUdl, UDL_FORMAT_VERSION } from "@hyperscale0/udl";
|
|
7
|
+
const usage = "hsx build|format|cost <file> [--out path]\nhsx check <file>\nhsx headers --json";
|
|
8
|
+
const standardLibrary = {
|
|
9
|
+
source: (header) => {
|
|
10
|
+
for (const base of ["../std/", "../../std/"]) {
|
|
11
|
+
const file = new URL(`${base}${header}.hsx`, import.meta.url);
|
|
12
|
+
if (existsSync(file))
|
|
13
|
+
return readFileSync(file, "utf8");
|
|
91
14
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return USAGE;
|
|
102
|
-
}
|
|
103
|
-
const result = compile(source, { costTable });
|
|
104
|
-
for (const line of diagnosticLines(parsed.file, result))
|
|
105
|
-
io.err(line);
|
|
106
|
-
const refused = result.verdict === "invalid" ||
|
|
107
|
-
(parsed.strict && result.verdict === "warning");
|
|
108
|
-
if (command === "check") {
|
|
109
|
-
return refused ? REFUSED : OK;
|
|
110
|
-
}
|
|
111
|
-
if (!result.artifacts)
|
|
112
|
-
return REFUSED;
|
|
113
|
-
if (command === "cost") {
|
|
114
|
-
const json = `${JSON.stringify(result.artifacts.costManifest, null, 2)}\n`;
|
|
115
|
-
if (parsed.out !== undefined) {
|
|
116
|
-
const writeCode = await writeOutput(parsed.out, json, io);
|
|
117
|
-
return writeCode === OK && refused ? REFUSED : writeCode;
|
|
15
|
+
return undefined;
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
export async function runCli(argv, io) {
|
|
19
|
+
const [command, file, ...options] = argv;
|
|
20
|
+
if (command === "headers") {
|
|
21
|
+
if (file !== "--json" || options.length) {
|
|
22
|
+
io.err("usage: hsx headers --json");
|
|
23
|
+
return 2;
|
|
118
24
|
}
|
|
119
|
-
io.out(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
25
|
+
io.out(JSON.stringify(headerManifest(standardLibrary), null, 2));
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
if (["--help", "help", "-h"].includes(command ?? "")) {
|
|
29
|
+
io.out(usage);
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
if (command === "--version") {
|
|
33
|
+
// src/cli.ts in a checkout, dist/src/cli.js in the published package.
|
|
34
|
+
for (const base of ["../", "../../"]) {
|
|
35
|
+
const manifest = new URL(`${base}package.json`, import.meta.url);
|
|
36
|
+
if (!existsSync(manifest))
|
|
37
|
+
continue;
|
|
38
|
+
const { version } = JSON.parse(readFileSync(manifest, "utf8"));
|
|
39
|
+
io.out(`${version} (UDL ${UDL_FORMAT_VERSION})`);
|
|
40
|
+
return 0;
|
|
134
41
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
42
|
+
io.err("hsx: package.json not found");
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
if (!command ||
|
|
46
|
+
!file ||
|
|
47
|
+
!["build", "check", "format", "cost"].includes(command)) {
|
|
48
|
+
io.err(`usage:\n${usage}`);
|
|
49
|
+
return 2;
|
|
50
|
+
}
|
|
51
|
+
let output;
|
|
52
|
+
for (let i = 0; i < options.length; i++) {
|
|
53
|
+
if (command !== "check" &&
|
|
54
|
+
options[i] === "--out" &&
|
|
55
|
+
options[i + 1] &&
|
|
56
|
+
!options[i + 1].startsWith("--") &&
|
|
57
|
+
output === undefined)
|
|
58
|
+
output = options[++i];
|
|
59
|
+
else {
|
|
60
|
+
io.err(`unknown option ${options[i]}`);
|
|
61
|
+
return 2;
|
|
138
62
|
}
|
|
139
63
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const argument = args[index];
|
|
149
|
-
if (argument === "--strict") {
|
|
150
|
-
if (command === "format") {
|
|
151
|
-
return { error: "hsx format has no style options" };
|
|
152
|
-
}
|
|
153
|
-
strict = true;
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
if (argument === "--json") {
|
|
157
|
-
if (command !== "cost")
|
|
158
|
-
return { error: "--json belongs to hsx cost" };
|
|
159
|
-
json = true;
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
if (argument === "--out") {
|
|
163
|
-
if (command !== "build" && command !== "cost") {
|
|
164
|
-
return { error: "--out belongs to hsx build or hsx cost" };
|
|
165
|
-
}
|
|
166
|
-
const value = args[index + 1];
|
|
167
|
-
if (value === undefined || value.startsWith("--")) {
|
|
168
|
-
return { error: "--out needs a file path" };
|
|
64
|
+
try {
|
|
65
|
+
const source = await io.readFile(file);
|
|
66
|
+
let text;
|
|
67
|
+
if (command === "format") {
|
|
68
|
+
const result = format(source);
|
|
69
|
+
if (!result.ok) {
|
|
70
|
+
result.diagnostics.forEach((d) => io.err(`${file}: ${d.message}`));
|
|
71
|
+
return 1;
|
|
169
72
|
}
|
|
170
|
-
|
|
171
|
-
index += 1;
|
|
172
|
-
continue;
|
|
73
|
+
text = result.formatted;
|
|
173
74
|
}
|
|
174
|
-
|
|
175
|
-
|
|
75
|
+
else {
|
|
76
|
+
const result = compile(source, { standardLibrary });
|
|
77
|
+
for (const d of result.diagnostics)
|
|
78
|
+
io.err(`${d.source && d.source !== "program" ? d.source : file}:${d.line}:${d.column}: ${d.code} ${d.message}. ${d.fix}`);
|
|
79
|
+
if (!result.artifacts || result.verdict !== "valid")
|
|
80
|
+
return 1;
|
|
81
|
+
if (command === "check")
|
|
82
|
+
return 0;
|
|
83
|
+
text =
|
|
84
|
+
command === "cost"
|
|
85
|
+
? JSON.stringify(result.artifacts.costManifest, null, 2) + "\n"
|
|
86
|
+
: serializeUdl(result.artifacts.document);
|
|
176
87
|
}
|
|
177
|
-
if (
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (file === undefined)
|
|
183
|
-
return { error: `hsx ${command} needs a file` };
|
|
184
|
-
return { file, json, ...(out === undefined ? {} : { out }), strict };
|
|
185
|
-
}
|
|
186
|
-
function explainDiagnostic(args, io) {
|
|
187
|
-
if (args.length !== 1 || args[0]?.startsWith("-")) {
|
|
188
|
-
io.err("hsx: explain needs one diagnostic code");
|
|
189
|
-
return USAGE;
|
|
88
|
+
if (output)
|
|
89
|
+
await io.writeFile(output, text);
|
|
90
|
+
else
|
|
91
|
+
io.out(text.trimEnd());
|
|
92
|
+
return 0;
|
|
190
93
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return USAGE;
|
|
94
|
+
catch (error) {
|
|
95
|
+
io.err(error instanceof Error ? error.message : String(error));
|
|
96
|
+
return 2;
|
|
195
97
|
}
|
|
196
|
-
io.out([
|
|
197
|
-
`${diagnostic.code} ${diagnostic.title}`,
|
|
198
|
-
`Stage: ${diagnostic.stage}`,
|
|
199
|
-
`Fix: ${diagnostic.fix}`,
|
|
200
|
-
diagnostic.example === null
|
|
201
|
-
? "Example: unavailable from source alone"
|
|
202
|
-
: `Example:\n${diagnostic.example}`,
|
|
203
|
-
].join("\n"));
|
|
204
|
-
return OK;
|
|
205
|
-
}
|
|
206
|
-
function renderCostTable(manifest) {
|
|
207
|
-
const rows = [
|
|
208
|
-
`costTableVersion\t${manifest.costTableVersion}`,
|
|
209
|
-
"instrument.action\teffect\tunit\tcount\ttotal\tpayer",
|
|
210
|
-
];
|
|
211
|
-
for (const action of manifest.actions) {
|
|
212
|
-
for (const component of action.components) {
|
|
213
|
-
const fixed = BigInt(component.perEventMinor) * BigInt(component.count);
|
|
214
|
-
const unit = [
|
|
215
|
-
`${component.perEventMinor} ${manifest.currency} minor`,
|
|
216
|
-
component.bps > 0 ? `${component.bps} bps` : undefined,
|
|
217
|
-
]
|
|
218
|
-
.filter((part) => part !== undefined)
|
|
219
|
-
.join(" + ");
|
|
220
|
-
const total = component.bps === 0
|
|
221
|
-
? `${fixed} ${manifest.currency} minor`
|
|
222
|
-
: [
|
|
223
|
-
fixed === 0n ? undefined : `${fixed} ${manifest.currency} minor`,
|
|
224
|
-
`amount-dependent (${component.bps} bps)`,
|
|
225
|
-
]
|
|
226
|
-
.filter((part) => part !== undefined)
|
|
227
|
-
.join(" + ");
|
|
228
|
-
rows.push([
|
|
229
|
-
`${action.instrument}.${action.action}`,
|
|
230
|
-
component.signature,
|
|
231
|
-
unit,
|
|
232
|
-
component.count,
|
|
233
|
-
total,
|
|
234
|
-
component.payer,
|
|
235
|
-
].join("\t"));
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
return rows.join("\n");
|
|
239
|
-
}
|
|
240
|
-
async function writeOutput(path, contents, io) {
|
|
241
|
-
try {
|
|
242
|
-
await io.writeFile(path, contents);
|
|
243
|
-
}
|
|
244
|
-
catch (cause) {
|
|
245
|
-
io.err(`hsx: cannot write ${path}: ${messageOf(cause)}`);
|
|
246
|
-
return USAGE;
|
|
247
|
-
}
|
|
248
|
-
return OK;
|
|
249
|
-
}
|
|
250
|
-
async function readDefaultCostTable(io) {
|
|
251
|
-
const candidates = [
|
|
252
|
-
fileURLToPath(new URL("../examples/cost-table.json", import.meta.url)),
|
|
253
|
-
fileURLToPath(new URL("../../examples/cost-table.json", import.meta.url)),
|
|
254
|
-
];
|
|
255
|
-
let lastError;
|
|
256
|
-
for (const path of candidates) {
|
|
257
|
-
try {
|
|
258
|
-
return JSON.parse(await io.readFile(path));
|
|
259
|
-
}
|
|
260
|
-
catch (cause) {
|
|
261
|
-
lastError = cause;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
throw lastError;
|
|
265
|
-
}
|
|
266
|
-
/** `file:line:col: severity [stage] message`, the shape editors already parse. */
|
|
267
|
-
function diagnosticLines(file, result) {
|
|
268
|
-
return result.diagnostics.map((diagnostic) => `${diagnostic.file ?? file}:${diagnostic.line}:${diagnostic.column}: ${diagnostic.severity} [${diagnostic.stage}] ${diagnostic.message}`);
|
|
269
|
-
}
|
|
270
|
-
function messageOf(cause) {
|
|
271
|
-
return cause instanceof Error ? cause.message : String(cause);
|
|
272
98
|
}
|
|
99
|
+
if (import.meta.main)
|
|
100
|
+
process.exitCode = await runCli(process.argv.slice(2), {
|
|
101
|
+
out: (line) => process.stdout.write(line + "\n"),
|
|
102
|
+
err: (line) => process.stderr.write(line + "\n"),
|
|
103
|
+
readFile: (path) => readFile(path, "utf8"),
|
|
104
|
+
writeFile: (path, text) => writeFile(path, text, "utf8"),
|
|
105
|
+
});
|
|
273
106
|
//# sourceMappingURL=cli.js.map
|