@hyperscale0/udl 1.0.342 → 1.0.347

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 (50) hide show
  1. package/README.md +3 -2
  2. package/dist/canonical.d.ts +15 -3
  3. package/dist/canonical.d.ts.map +1 -1
  4. package/dist/canonical.js +77 -12
  5. package/dist/canonical.js.map +1 -1
  6. package/dist/diagnostics.d.ts +1 -1
  7. package/dist/diagnostics.d.ts.map +1 -1
  8. package/dist/diagnostics.js +2 -0
  9. package/dist/diagnostics.js.map +1 -1
  10. package/dist/formats.d.ts +27 -0
  11. package/dist/formats.d.ts.map +1 -0
  12. package/dist/formats.js +31 -0
  13. package/dist/formats.js.map +1 -0
  14. package/dist/index.d.ts +4 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +4 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/object-contract.d.ts +4 -0
  19. package/dist/object-contract.d.ts.map +1 -1
  20. package/dist/object-contract.js.map +1 -1
  21. package/dist/object-semantics-schema.d.ts +276 -92
  22. package/dist/object-semantics-schema.d.ts.map +1 -1
  23. package/dist/schema.d.ts +6481 -115
  24. package/dist/schema.d.ts.map +1 -1
  25. package/dist/schema.js +58 -10
  26. package/dist/schema.js.map +1 -1
  27. package/dist/serialize.d.ts +5 -0
  28. package/dist/serialize.d.ts.map +1 -0
  29. package/dist/serialize.js +14 -0
  30. package/dist/serialize.js.map +1 -0
  31. package/dist/validation.d.ts +19 -0
  32. package/dist/validation.d.ts.map +1 -1
  33. package/dist/validation.js +49 -7
  34. package/dist/validation.js.map +1 -1
  35. package/package.json +3 -2
  36. package/spec/cars.udl.json +1 -1
  37. package/spec/udl.schema.json +529 -489
  38. package/src/canonical.ts +84 -14
  39. package/src/diagnostics.ts +6 -0
  40. package/src/formats.ts +56 -0
  41. package/src/index.ts +9 -1
  42. package/src/object-contract.ts +4 -1
  43. package/src/schema.ts +71 -11
  44. package/src/serialize.ts +14 -0
  45. package/src/validation.ts +65 -10
  46. package/dist/json.d.ts +0 -2
  47. package/dist/json.d.ts.map +0 -1
  48. package/dist/json.js +0 -30
  49. package/dist/json.js.map +0 -1
  50. package/src/json.ts +0 -34
package/src/canonical.ts CHANGED
@@ -1,18 +1,88 @@
1
- import { assertValidUdl } from "./validation.js";
2
- import { writeJson } from "./json.js";
1
+ import { hash } from "fast-sha256";
3
2
 
4
- export function serializeUdl(value: unknown): string {
5
- const document = assertValidUdl(value);
6
- return `${writeJson(document, 0)}\n`;
3
+ /**
4
+ * Canonical JSON, the one encoder behind every hashed value in Arc. Keys sort
5
+ * by UTF-16 code unit and scalars encode as `JSON.stringify` writes them. Only
6
+ * plain data encodes: non-finite numbers, `bigint`, functions, symbols,
7
+ * `undefined`, missing array items, non-plain objects and cycles throw.
8
+ */
9
+ export function canonicalJson(value: unknown): string {
10
+ return write(value, "$", new WeakSet<object>());
7
11
  }
8
12
 
9
- /** SHA-256 over the canonical UTF-8 bytes, encoded as lowercase hexadecimal. */
10
- export async function canonicalDigest(value: unknown): Promise<string> {
11
- const digest = await globalThis.crypto.subtle.digest(
12
- "SHA-256",
13
- new TextEncoder().encode(serializeUdl(value)),
14
- );
15
- return [...new Uint8Array(digest)]
16
- .map((byte) => byte.toString(16).padStart(2, "0"))
17
- .join("");
13
+ /**
14
+ * The UDL document layout: canonical JSON with a two-space indent. Every
15
+ * stored `documentDigest` hashes these bytes.
16
+ */
17
+ export function writeJson(value: unknown): string {
18
+ return write(value, "$", new WeakSet<object>(), "");
19
+ }
20
+
21
+ function write(
22
+ value: unknown,
23
+ path: string,
24
+ ancestors: WeakSet<object>,
25
+ indent?: string,
26
+ ): string {
27
+ if (value === null) return "null";
28
+ switch (typeof value) {
29
+ case "boolean":
30
+ case "string":
31
+ return JSON.stringify(value);
32
+ case "number":
33
+ if (!Number.isFinite(value)) refuse("non finite numbers", path);
34
+ return JSON.stringify(value);
35
+ case "object":
36
+ break;
37
+ default:
38
+ refuse(typeof value, path);
39
+ }
40
+ const array = Array.isArray(value);
41
+ if (!array) {
42
+ const prototype = Object.getPrototypeOf(value);
43
+ if (prototype !== Object.prototype && prototype !== null)
44
+ refuse("objects other than plain ones", path);
45
+ if (Object.getOwnPropertySymbols(value).length > 0)
46
+ refuse("symbol keys", path);
47
+ }
48
+ if (ancestors.has(value)) refuse("cycles", path);
49
+ ancestors.add(value);
50
+ try {
51
+ const inner = indent === undefined ? undefined : `${indent} `;
52
+ const items: string[] = [];
53
+ if (array) {
54
+ for (let index = 0; index < value.length; index += 1) {
55
+ if (!Object.hasOwn(value, index))
56
+ refuse("missing array items", `${path}[${index}]`);
57
+ items.push(write(value[index], `${path}[${index}]`, ancestors, inner));
58
+ }
59
+ } else {
60
+ const record = value as Record<string, unknown>;
61
+ for (const key of Object.keys(record).sort())
62
+ items.push(
63
+ `${JSON.stringify(key)}:${inner === undefined ? "" : " "}${write(record[key], `${path}.${key}`, ancestors, inner)}`,
64
+ );
65
+ }
66
+ const [open, close] = array ? ["[", "]"] : ["{", "}"];
67
+ if (inner === undefined || items.length === 0)
68
+ return `${open}${items.join(",")}${close}`;
69
+ return `${open}\n${inner}${items.join(`,\n${inner}`)}\n${indent}${close}`;
70
+ } finally {
71
+ ancestors.delete(value);
72
+ }
73
+ }
74
+
75
+ function refuse(what: string, path: string): never {
76
+ throw new TypeError(`canonical JSON does not support ${what} at ${path}`);
77
+ }
78
+
79
+ /** SHA-256 over canonical JSON, encoded as lowercase hexadecimal. */
80
+ export function digest(value: unknown): string {
81
+ return sha256(canonicalJson(value));
82
+ }
83
+
84
+ export function sha256(text: string): string {
85
+ return Array.from(hash(new TextEncoder().encode(text)), (byte) =>
86
+ byte.toString(16).padStart(2, "0"),
87
+ ).join("");
18
88
  }
@@ -11,6 +11,8 @@ export type UdlIssueCode =
11
11
  | "party_kind_mismatch"
12
12
  | "staff_role_unknown"
13
13
  | "product_party_invalid"
14
+ | "udl_format_unknown"
15
+ | "udl_format_not_current"
14
16
  | "UDL1003"
15
17
  | "UDL1004"
16
18
  | "UDL2001"
@@ -53,6 +55,10 @@ const fixes: Record<UdlIssueCode, string> = {
53
55
  staff_role_unknown: "Use a registered staff permission role.",
54
56
  product_party_invalid:
55
57
  "Bind a business participant in the same tenant and environment.",
58
+ udl_format_unknown:
59
+ "Run the document on an engine that ships a reader for its format.",
60
+ udl_format_not_current:
61
+ "Recompile the HSX program, which emits the current UDL format.",
56
62
 
57
63
  UDL1003: "Use the UDL 1 typed grammar.",
58
64
  UDL1004: "Reduce the declared structure or expansion.",
package/src/formats.ts ADDED
@@ -0,0 +1,56 @@
1
+ import type * as z from "zod";
2
+ import {
3
+ UDL_FORMAT_VERSION,
4
+ udlDocumentSchema,
5
+ udlFormat1DocumentSchema,
6
+ type UdlAnyFamily,
7
+ } from "./schema.js";
8
+
9
+ /**
10
+ * How this engine reads one UDL format. A Build is bytecode and keeps the
11
+ * format it compiled to. The current format parses straight into the engine's
12
+ * document; an older one parses with its own schema, then `upgrade`, a pure
13
+ * and deterministic step, turns it into the next format.
14
+ */
15
+ export interface UdlFormatReader {
16
+ readonly schema: z.ZodType;
17
+ readonly upgrade?: (document: unknown) => unknown;
18
+ }
19
+
20
+ /**
21
+ * One reader per format a stored Build uses, keyed by `document.udl`. A format
22
+ * bump adds its schema here and gives the previous format an upgrade step. A
23
+ * new Build admits only `UDL_FORMAT_VERSION` (`validateNewBuildUdl`).
24
+ */
25
+ export const udlFormatReaders = new Map<number, UdlFormatReader>([
26
+ [1, { schema: udlFormat1DocumentSchema }],
27
+ [UDL_FORMAT_VERSION, { schema: udlDocumentSchema }],
28
+ ]);
29
+
30
+ /**
31
+ * Whether two families name the same std declaration. Two format 2 families
32
+ * compare digests. When either is format 1, module and export path decide,
33
+ * which is what a stored revision decided: every stored revision is 1.
34
+ */
35
+ export function sameFamily(
36
+ a: UdlAnyFamily | undefined,
37
+ b: UdlAnyFamily,
38
+ ): boolean {
39
+ return (
40
+ a !== undefined &&
41
+ a.module === b.module &&
42
+ a.exportPath === b.exportPath &&
43
+ (!("digest" in a) || !("digest" in b) || a.digest === b.digest)
44
+ );
45
+ }
46
+
47
+ /** The format a stored document declares, when this engine can read it. */
48
+ export function readableUdlFormat(document: unknown): number | undefined {
49
+ const format =
50
+ document !== null && typeof document === "object"
51
+ ? (document as { udl?: unknown }).udl
52
+ : undefined;
53
+ return typeof format === "number" && udlFormatReaders.has(format)
54
+ ? format
55
+ : undefined;
56
+ }
package/src/index.ts CHANGED
@@ -1,8 +1,16 @@
1
1
  export * from "./schema.js";
2
2
  export { sarCurrency, sarMinorUnitExponent, currencySchema } from "./money.js";
3
- export { serializeUdl, canonicalDigest } from "./canonical.js";
3
+ export { serializeUdl, documentDigest } from "./serialize.js";
4
+ export { canonicalJson, digest } from "./canonical.js";
5
+ export {
6
+ udlFormatReaders,
7
+ readableUdlFormat,
8
+ sameFamily,
9
+ type UdlFormatReader,
10
+ } from "./formats.js";
4
11
  export {
5
12
  validateUdl,
13
+ validateNewBuildUdl,
6
14
  RESERVED_OBJECT_NAMES,
7
15
  assertValidUdl,
8
16
  resolveField,
@@ -29,7 +29,10 @@ export interface ObjectKindDiscovery {
29
29
  title: string;
30
30
  instrument: string;
31
31
  parentAttachment: string | null;
32
- block: { key: string; recordPath: string; headerDigest: string } | null;
32
+ block:
33
+ | { key: string; recordPath: string; digest: string }
34
+ | { key: string; recordPath: string; headerDigest: string }
35
+ | null;
33
36
  }[];
34
37
  productBuildId: string;
35
38
  digest: string;
package/src/schema.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as z from "zod";
2
2
  import { currencySchema } from "./money.js";
3
3
  import { reportDefinitionSchema } from "./reporting.js";
4
- import { writeJson } from "./json.js";
4
+ import { canonicalJson } from "./canonical.js";
5
5
 
6
- export const UDL_FORMAT_VERSION = 1 as const;
6
+ export const UDL_FORMAT_VERSION = 2 as const;
7
7
  /** Counts the root and every nested invocation, including selected and ranged children. */
8
8
  export const MAX_ACTION_EXPANSION = 8192;
9
9
  const name = z
@@ -33,12 +33,23 @@ export const udlPartySchema = z.strictObject({
33
33
  role: name.optional(),
34
34
  });
35
35
 
36
+ /** Format 2 names a std declaration by the digest of its normal form. */
36
37
  export const udlFamilySchema = z.strictObject({
38
+ module: name,
39
+ exportPath: path,
40
+ digest: z.string().regex(/^[a-f0-9]{64}$/),
41
+ });
42
+
43
+ /** Format 1 named it by a hand-written revision. Stored Builds keep it. */
44
+ export const udlFormat1FamilySchema = z.strictObject({
37
45
  module: name,
38
46
  exportPath: path,
39
47
  revision: integer.positive(),
40
48
  });
41
49
 
50
+ // One tree serves both formats; each document schema checks its families.
51
+ const family = z.union([udlFamilySchema, udlFormat1FamilySchema]);
52
+
42
53
  const fieldBase = {
43
54
  name,
44
55
  label: text.optional(),
@@ -51,7 +62,7 @@ const referenceField = z.strictObject({
51
62
  ...fieldBase,
52
63
  type: z.literal("ref"),
53
64
  targetKind: z.enum(["instrument", "object"]),
54
- targetFamily: udlFamilySchema.optional(),
65
+ targetFamily: family.optional(),
55
66
  target: z.union([name, z.array(name).min(1).max(16)]),
56
67
  });
57
68
 
@@ -60,7 +71,7 @@ const listField = z.strictObject({
60
71
  type: z.literal("list"),
61
72
  item: z.enum(["money", "date", "text", "integer", "ref"]),
62
73
  targetKind: z.enum(["instrument", "object"]).optional(),
63
- targetFamily: udlFamilySchema.optional(),
74
+ targetFamily: family.optional(),
64
75
  target: name.optional(),
65
76
  maxItems: integer.min(1).max(366),
66
77
  });
@@ -254,7 +265,7 @@ export const udlObjectKindSchema = z.strictObject({
254
265
  const values = z.array(value).min(1).max(256);
255
266
 
256
267
  const selection = z.strictObject({
257
- family: udlFamilySchema.optional(),
268
+ family: family.optional(),
258
269
  instrument: z.union([instrumentId, z.array(instrumentId).min(1).max(16)]),
259
270
  reference: name,
260
271
  anchor: path,
@@ -551,7 +562,7 @@ export const udlInstrumentSchema = z.strictObject({
551
562
  scope: z.literal("product").optional(),
552
563
  reports: z.array(reportDefinitionSchema).max(16).optional(),
553
564
  revisioned: z.literal(true).optional(),
554
- family: udlFamilySchema.optional(),
565
+ family: family.optional(),
555
566
  id: instrumentId,
556
567
  subject: objectKindId.optional(),
557
568
  // The authored instrument an attachment instantiates, when its scoped id
@@ -570,8 +581,7 @@ export const udlInstrumentSchema = z.strictObject({
570
581
  .max(16)
571
582
  .optional(),
572
583
  });
573
- export const udlDocumentSchema = z.strictObject({
574
- udl: z.literal(UDL_FORMAT_VERSION),
584
+ const documentShape = {
575
585
  version: integer.positive(),
576
586
  product: name,
577
587
  title: text,
@@ -579,10 +589,60 @@ export const udlDocumentSchema = z.strictObject({
579
589
  parties: z.record(name, udlPartySchema),
580
590
  objects: z.array(udlObjectKindSchema).max(256),
581
591
  instruments: z.array(udlInstrumentSchema).max(256),
582
- });
592
+ };
593
+
594
+ /** Every family a document names: instruments, reference fields, selections. */
595
+ function families(instruments: unknown[]): [PropertyKey[], object][] {
596
+ const found: [PropertyKey[], object][] = [];
597
+ const visit = (value: unknown, path: PropertyKey[]): void => {
598
+ if (!value || typeof value !== "object") return;
599
+ for (const [key, child] of Object.entries(value)) {
600
+ // An evidence `family` is a name, not a std family.
601
+ if (
602
+ (key === "family" || key === "targetFamily") &&
603
+ child &&
604
+ typeof child === "object"
605
+ )
606
+ found.push([[...path, key], child]);
607
+ else if (key !== "examples")
608
+ visit(child, [...path, Array.isArray(value) ? Number(key) : key]);
609
+ }
610
+ };
611
+ visit(instruments, ["instruments"]);
612
+ return found;
613
+ }
614
+
615
+ const familiesIn =
616
+ (key: "digest" | "revision") =>
617
+ (document: { instruments: unknown[] }, context: z.RefinementCtx) => {
618
+ for (const [path, item] of families(document.instruments))
619
+ if (!(key in item))
620
+ context.addIssue({
621
+ code: "custom",
622
+ path,
623
+ message: `a format ${key === "digest" ? 2 : 1} family names its ${key}`,
624
+ });
625
+ };
626
+
627
+ export const udlDocumentSchema = z
628
+ .strictObject({ udl: z.literal(UDL_FORMAT_VERSION), ...documentShape })
629
+ .superRefine(familiesIn("digest"));
630
+
631
+ /** The format 1 reader: families carry the revision they were stored with. */
632
+ export const udlFormat1DocumentSchema = z
633
+ .strictObject({ udl: z.literal(1), ...documentShape })
634
+ .superRefine(familiesIn("revision"));
635
+
636
+ /** Any document a stored Build may hold, in the format it compiled to. */
637
+ export const udlStoredDocumentSchema = z.discriminatedUnion("udl", [
638
+ udlDocumentSchema,
639
+ udlFormat1DocumentSchema,
640
+ ]);
583
641
 
584
642
  export type UdlFamily = z.infer<typeof udlFamilySchema>;
585
- export type UdlDocument = z.infer<typeof udlDocumentSchema>;
643
+ export type UdlFormat1Family = z.infer<typeof udlFormat1FamilySchema>;
644
+ export type UdlAnyFamily = UdlFamily | UdlFormat1Family;
645
+ export type UdlDocument = z.infer<typeof udlStoredDocumentSchema>;
586
646
  export type UdlInstrument = z.infer<typeof udlInstrumentSchema>;
587
647
  export type UdlField = z.infer<typeof udlFieldSchema>;
588
648
  export type UdlValue = z.infer<typeof udlValueSchema>;
@@ -606,7 +666,7 @@ export function sameObjectField(
606
666
  right: UdlObjectField,
607
667
  ): boolean {
608
668
  const signature = (field: UdlObjectField) =>
609
- writeJson(
669
+ canonicalJson(
610
670
  Object.fromEntries(
611
671
  Object.entries(field).filter(
612
672
  ([key, value]) =>
@@ -0,0 +1,14 @@
1
+ import { readUdl, UdlError } from "./validation.js";
2
+ import { sha256, writeJson } from "./canonical.js";
3
+
4
+ /** The stored bytes of a UDL document: its own format's layout, with a trailing newline. */
5
+ export function serializeUdl(value: unknown): string {
6
+ const read = readUdl(value);
7
+ if (!read.ok) throw new UdlError(read.issues);
8
+ return `${writeJson(read.stored)}\n`;
9
+ }
10
+
11
+ /** SHA-256 over the stored document bytes, the `documentDigest` every Build carries. */
12
+ export function documentDigest(value: unknown): string {
13
+ return sha256(serializeUdl(value));
14
+ }
package/src/validation.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import {
2
- udlDocumentSchema,
2
+ UDL_FORMAT_VERSION,
3
3
  subjectPartyRoles,
4
4
  sameObjectField,
5
5
  type UdlDocument,
6
- type UdlFamily,
7
6
  type UdlField,
8
7
  type UdlInstrument,
9
8
  type UdlValue,
@@ -16,6 +15,7 @@ import {
16
15
  type UdlObjectKind,
17
16
  } from "./schema.js";
18
17
  import { issue, type UdlIssue } from "./diagnostics.js";
18
+ import { readableUdlFormat, sameFamily, udlFormatReaders } from "./formats.js";
19
19
  import { validateReportDefinition } from "./reporting-validation.js";
20
20
  import { analyzeInstrumentFinance } from "./finance.js";
21
21
  import { UDL_LIMITS } from "./limits.js";
@@ -140,11 +140,6 @@ function bounded(value: unknown): boolean {
140
140
 
141
141
  const overlap = (a: string | string[], b: string | string[]) =>
142
142
  targetIds(a).some((id) => targetIds(b).includes(id));
143
- const sameFamily = (actual: UdlFamily | undefined, expected: UdlFamily) =>
144
- actual !== undefined &&
145
- actual.module === expected.module &&
146
- actual.exportPath === expected.exportPath &&
147
- actual.revision === expected.revision;
148
143
 
149
144
  /** Union paths retain only fields with compatible types on every member. */
150
145
  function commonField(
@@ -449,6 +444,44 @@ function resolvePath(
449
444
  }
450
445
 
451
446
  export function validateUdl(value: unknown): UdlValidationResult {
447
+ const read = readUdl(value);
448
+ return read.ok ? { ok: true, value: read.document } : read;
449
+ }
450
+
451
+ /**
452
+ * Admit a document for a new Build. A new Build is the current format; the
453
+ * older formats in `udlFormatReaders` are readable only as stored Builds,
454
+ * through `validateUdl`.
455
+ */
456
+ export function validateNewBuildUdl(value: unknown): UdlValidationResult {
457
+ const format =
458
+ value !== null && typeof value === "object"
459
+ ? (value as { udl?: unknown }).udl
460
+ : undefined;
461
+ if (format !== UDL_FORMAT_VERSION)
462
+ return {
463
+ ok: false,
464
+ issues: [
465
+ issue(
466
+ "udl_format_not_current",
467
+ "$.udl",
468
+ `a new Build is UDL format ${UDL_FORMAT_VERSION}; this document is format ${String(format)}`,
469
+ ),
470
+ ],
471
+ };
472
+ return validateUdl(value);
473
+ }
474
+
475
+ /**
476
+ * Read a document in the format it declares, then run the upgrade chain to
477
+ * the current format. `stored` is the parsed document in its own format, the
478
+ * one its digests cover; `document` is what the engine runs.
479
+ */
480
+ export function readUdl(
481
+ value: unknown,
482
+ ):
483
+ | { ok: true; stored: unknown; document: UdlDocument }
484
+ | { ok: false; issues: UdlIssue[] } {
452
485
  if (!bounded(value))
453
486
  return {
454
487
  ok: false,
@@ -460,7 +493,29 @@ export function validateUdl(value: unknown): UdlValidationResult {
460
493
  ),
461
494
  ],
462
495
  };
463
- const parsed = udlDocumentSchema.safeParse(value);
496
+ let format = readableUdlFormat(value);
497
+ if (format === undefined)
498
+ return {
499
+ ok: false,
500
+ issues: [
501
+ issue(
502
+ "udl_format_unknown",
503
+ "$.udl",
504
+ `UDL format ${String((value as { udl?: unknown }).udl)} has no reader in this engine`,
505
+ ),
506
+ ],
507
+ };
508
+ let reader = udlFormatReaders.get(format)!;
509
+ let parsed = reader.schema.safeParse(value);
510
+ const stored = parsed.data;
511
+ while (parsed.success && reader.upgrade) {
512
+ const next = reader.upgrade(parsed.data);
513
+ format = readableUdlFormat(next);
514
+ if (format === undefined)
515
+ throw new Error("a UDL upgrade step produced a format with no reader");
516
+ reader = udlFormatReaders.get(format)!;
517
+ parsed = reader.schema.safeParse(next);
518
+ }
464
519
  if (!parsed.success)
465
520
  return {
466
521
  ok: false,
@@ -475,7 +530,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
475
530
  ),
476
531
  ),
477
532
  };
478
- const document = parsed.data;
533
+ const document = parsed.data as UdlDocument;
479
534
  const issues: UdlIssue[] = [];
480
535
  const add = (
481
536
  path: string,
@@ -1765,7 +1820,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
1765
1820
  visited.add(key);
1766
1821
  };
1767
1822
  for (const key of calls.keys()) visit(key);
1768
- return issues.length ? { ok: false, issues } : { ok: true, value: document };
1823
+ return issues.length ? { ok: false, issues } : { ok: true, stored, document };
1769
1824
  }
1770
1825
  export function assertValidUdl(value: unknown): UdlDocument {
1771
1826
  const result = validateUdl(value);
package/dist/json.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare function writeJson(value: unknown, depth?: number): string;
2
- //# sourceMappingURL=json.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAEA,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,MAAM,CA2B3D"}
package/dist/json.js DELETED
@@ -1,30 +0,0 @@
1
- const INDENT = " ";
2
- export function writeJson(value, depth = 0) {
3
- if (value === null || typeof value !== "object") {
4
- const encoded = JSON.stringify(value);
5
- if (encoded === undefined) {
6
- throw new TypeError("UDL canonical JSON received a non-JSON value");
7
- }
8
- return encoded;
9
- }
10
- const indent = INDENT.repeat(depth);
11
- const childIndent = INDENT.repeat(depth + 1);
12
- if (Array.isArray(value)) {
13
- if (value.length === 0)
14
- return "[]";
15
- return `[\n${value
16
- .map((item) => `${childIndent}${writeJson(item, depth + 1)}`)
17
- .join(",\n")}\n${indent}]`;
18
- }
19
- const record = value;
20
- const keys = Object.keys(record).sort(compareCodeUnits);
21
- if (keys.length === 0)
22
- return "{}";
23
- return `{\n${keys
24
- .map((key) => `${childIndent}${JSON.stringify(key)}: ${writeJson(record[key], depth + 1)}`)
25
- .join(",\n")}\n${indent}}`;
26
- }
27
- function compareCodeUnits(left, right) {
28
- return left < right ? -1 : left > right ? 1 : 0;
29
- }
30
- //# sourceMappingURL=json.js.map
package/dist/json.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,IAAI,CAAC;AAEpB,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,KAAK,GAAG,CAAC;IACjD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,OAAO,MAAM,KAAK;aACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,WAAW,GAAG,SAAS,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;aAC5D,IAAI,CAAC,KAAK,CAAC,KAAK,MAAM,GAAG,CAAC;IAC/B,CAAC;IAED,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACxD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,MAAM,IAAI;SACd,GAAG,CACF,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,CAC/E;SACA,IAAI,CAAC,KAAK,CAAC,KAAK,MAAM,GAAG,CAAC;AAC/B,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,KAAa;IACnD,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC"}
package/src/json.ts DELETED
@@ -1,34 +0,0 @@
1
- const INDENT = " ";
2
-
3
- export function writeJson(value: unknown, depth = 0): string {
4
- if (value === null || typeof value !== "object") {
5
- const encoded = JSON.stringify(value);
6
- if (encoded === undefined) {
7
- throw new TypeError("UDL canonical JSON received a non-JSON value");
8
- }
9
- return encoded;
10
- }
11
-
12
- const indent = INDENT.repeat(depth);
13
- const childIndent = INDENT.repeat(depth + 1);
14
- if (Array.isArray(value)) {
15
- if (value.length === 0) return "[]";
16
- return `[\n${value
17
- .map((item) => `${childIndent}${writeJson(item, depth + 1)}`)
18
- .join(",\n")}\n${indent}]`;
19
- }
20
-
21
- const record = value as Record<string, unknown>;
22
- const keys = Object.keys(record).sort(compareCodeUnits);
23
- if (keys.length === 0) return "{}";
24
- return `{\n${keys
25
- .map(
26
- (key) =>
27
- `${childIndent}${JSON.stringify(key)}: ${writeJson(record[key], depth + 1)}`,
28
- )
29
- .join(",\n")}\n${indent}}`;
30
- }
31
-
32
- function compareCodeUnits(left: string, right: string): number {
33
- return left < right ? -1 : left > right ? 1 : 0;
34
- }