@hyperscale0/hsx 5.6.0 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # HSX 5.7.0
2
+
3
+ Follows UDL 4.9.0. Object `entryActions` admits enrolled customers through named
4
+ actor-bound create actions. Product-scoped limits resolve across records with
5
+ matching parties. `programTax` moves use an operator-owned pass-through account.
6
+
7
+ Late charge creation accepts a slice reference for plans with multiple instalments.
8
+ Financing, collections and lending samples expose repayment child actions.
9
+ Aggregate selectors retain their selected instrument family, including child
10
+ records, so shared limits compare the matching contracts across Builds.
11
+
12
+ # HSX 5.6.1
13
+
14
+ Action summaries without authored text use the action title without the instrument id.
15
+
1
16
  # HSX 5.6.0
2
17
 
3
18
  The compiler records the standard block origin of every instrument compiled
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/compile.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAeL,KAAK,WAAW,EAOjB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAIL,KAAK,UAAU,EAKf,KAAK,IAAI,EACV,MAAM,UAAU,CAAC;AAClB,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;CACpC;AACD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,aAAa,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AACD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;CAClE;AACD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,SAAS,CAAC,EAAE;QACV,QAAQ,EAAE,WAAW,CAAC;QACtB,YAAY,EAAE,eAAe,CAAC;QAC9B,SAAS,EAAE,qBAAqB,EAAE,CAAC;KACpC,CAAC;CACH;AAqTD,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,cAAmB,GAC3B,aAAa,CAktGf"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/compile.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAeL,KAAK,WAAW,EAOjB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAIL,KAAK,UAAU,EAKf,KAAK,IAAI,EACV,MAAM,UAAU,CAAC;AAClB,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;CACpC;AACD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,aAAa,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AACD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;CAClE;AACD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,SAAS,CAAC,EAAE;QACV,QAAQ,EAAE,WAAW,CAAC;QACtB,YAAY,EAAE,eAAe,CAAC;QAC9B,SAAS,EAAE,qBAAqB,EAAE,CAAC;KACpC,CAAC;CACH;AAqTD,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,cAAmB,GAC3B,aAAa,CA8yGf"}
@@ -1014,6 +1014,7 @@ export function compile(source, options = {}) {
1014
1014
  "parameterDiagnostics",
1015
1015
  "reports",
1016
1016
  "revisioned",
1017
+ "scope",
1017
1018
  ].includes(key) &&
1018
1019
  !key.startsWith("action "))
1019
1020
  fail(decl, `unknown instrument clause ${key}`, "use fields, lifecycle, actions, invariants, or records");
@@ -1646,7 +1647,7 @@ export function compile(source, options = {}) {
1646
1647
  const a = {
1647
1648
  summary: slots.has("summary")
1648
1649
  ? String(data(slots.get("summary")))
1649
- : `${title(name)} ${id}`,
1650
+ : title(name),
1650
1651
  publicAction: camel(`${name}_${id}`),
1651
1652
  event: `${id}.${name}`,
1652
1653
  actor: "caller",
@@ -2033,9 +2034,38 @@ export function compile(source, options = {}) {
2033
2034
  inst.actions[name] = a;
2034
2035
  inst.actionOrder.push(name);
2035
2036
  }
2036
- for (const key of ["invariants", "reports", "revisioned"])
2037
+ for (const key of [
2038
+ "invariants",
2039
+ "reports",
2040
+ "revisioned",
2041
+ "scope",
2042
+ ])
2037
2043
  if (body.has(key))
2038
2044
  inst[key] = data(body.get(key));
2045
+ let usesTax = false;
2046
+ for (const action of Object.values(inst.actions)) {
2047
+ for (const move of action.moves) {
2048
+ if (!("from" in move))
2049
+ continue;
2050
+ for (const endpoint of ["from", "to"]) {
2051
+ if (move[endpoint] === "party.programTax") {
2052
+ move[endpoint] = "self.programTaxPayable";
2053
+ usesTax = true;
2054
+ }
2055
+ }
2056
+ }
2057
+ }
2058
+ if (usesTax) {
2059
+ if (inst.fields.some((field) => field.name === "programTaxPayable"))
2060
+ fail(decl, "programTaxPayable is reserved for the tax account", "rename the authored field");
2061
+ inst.fields.push({
2062
+ name: "programTaxPayable",
2063
+ type: "account",
2064
+ owner: "programOperator",
2065
+ book: "cash",
2066
+ key: "programTax",
2067
+ });
2068
+ }
2039
2069
  const shape = udlInstrumentSchema.safeParse(inst);
2040
2070
  if (!shape.success) {
2041
2071
  const issue = shape.error.issues[0];
@@ -2111,8 +2141,9 @@ export function compile(source, options = {}) {
2111
2141
  for (const key of body.keys()) {
2112
2142
  if (key !== "fields" &&
2113
2143
  key !== "columns" &&
2144
+ key !== "entryActions" &&
2114
2145
  !key.startsWith("attach ")) {
2115
- fail(decl, `unknown object clause ${key}`, "use fields, columns, or attach");
2146
+ fail(decl, `unknown object clause ${key}`, "use fields, columns, entryActions, or attach");
2116
2147
  }
2117
2148
  }
2118
2149
  const authoredFields = [];
@@ -2271,9 +2302,17 @@ export function compile(source, options = {}) {
2271
2302
  fail(columnsExpr, `The object list selects ${columns.length} columns; this release supports 8. The object may retain all its fields.`, `Remove ${columns.length === 9 ? "one name" : `${columns.length - 8} names`} from \`columns\`, not from \`fields\`.`);
2272
2303
  }
2273
2304
  }
2305
+ const entryExpr = body.get("entryActions");
2306
+ let entryActions;
2307
+ if (entryExpr) {
2308
+ if (entryExpr.kind !== "list" || !entryExpr.items.length)
2309
+ fail(entryExpr, "entryActions needs a nonempty list", "name exposed create actions bound to actor");
2310
+ entryActions = entryExpr.items.map(text);
2311
+ }
2274
2312
  document.objects.push({
2275
2313
  id: decl.name,
2276
2314
  title: decl.title,
2315
+ ...(entryActions ? { entryActions } : {}),
2277
2316
  authoredFields: authoredNames,
2278
2317
  attachments,
2279
2318
  fields: authoredFields,
@@ -2302,6 +2341,25 @@ export function compile(source, options = {}) {
2302
2341
  .sort((a, b) => a.span.start - b.span.start)
2303
2342
  .map((d) => diagnostic(d, "check")),
2304
2343
  };
2344
+ // Resolve selectors after every attachment and child has its family.
2345
+ const retainSelectionFamilies = (value) => {
2346
+ if (!value || typeof value !== "object")
2347
+ return;
2348
+ const record = value;
2349
+ const selection = record.selection;
2350
+ if (selection && !selection.family) {
2351
+ const families = [selection.instrument]
2352
+ .flat()
2353
+ .map((id) => document.instruments.find((item) => item.id === id)?.family);
2354
+ const family = families[0];
2355
+ if (family &&
2356
+ families.every((item) => canonicalJson(item) === canonicalJson(family)))
2357
+ selection.family = family;
2358
+ }
2359
+ for (const child of Object.values(record))
2360
+ retainSelectionFamilies(child);
2361
+ };
2362
+ retainSelectionFamilies(document);
2305
2363
  // Propagate invoked requirements with the conditions on each invocation path.
2306
2364
  let changedInvocations = true;
2307
2365
  let invocationIterations = 0;
@@ -2557,6 +2615,19 @@ export function compile(source, options = {}) {
2557
2615
  if (Object.values(instrument.actions).filter((action) => action.publicAction === decl.name).length > 1)
2558
2616
  fail(decl, `public action ${decl.name} is used more than once on ${parts.join(".")}`, "give each exposed action a distinct public name");
2559
2617
  }
2618
+ for (const kind of document.objects) {
2619
+ for (const name of kind.entryActions ?? []) {
2620
+ const eligible = kind.attachments.some((attachment) => {
2621
+ const create = document.instruments.find((instrument) => instrument.id === attachment.instrument)?.actions.create;
2622
+ return (create?.publicAction === name &&
2623
+ typeof create.actor === "object" &&
2624
+ "party" in create.actor &&
2625
+ create.actor.party === "actor");
2626
+ });
2627
+ if (!eligible)
2628
+ fail(objects.get(kind.id), `entry action ${name} must create an attachment as actor`, "expose its create action and bind its acting party to actor");
2629
+ }
2630
+ }
2560
2631
  const usedParties = new Set();
2561
2632
  const collectParties = (value) => {
2562
2633
  if (typeof value === "string") {