@nubbin/core 0.1.1 → 0.3.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/dist/index.js CHANGED
@@ -1,38 +1,94 @@
1
1
  // src/NubbinIssueCode.ts
2
2
  var NubbinIssueCode = {
3
3
  // Registration — a block, catalog or registry the developer wrote cannot be used as written.
4
+ /** `defineBlock` was given a `version` that is not an integer of 1 or more. */
4
5
  BlockVersion: "block-version",
6
+ /** `defineBlock` was given a slot whose `min` is above its `max`, which no composition satisfies. */
5
7
  SlotBounds: "slot-bounds",
8
+ /** `createRegistry` found a slot's `allow` naming a block no registered block answers to. */
6
9
  SlotAllowUnknown: "slot-allow-unknown",
10
+ /** `createRegistry` was given two blocks claiming one name — the identity every node resolves through. */
7
11
  DuplicateBlockName: "duplicate-block-name",
12
+ /** `defineCatalog` found an entry's `defaults` do not satisfy that entry's own schema. */
8
13
  InvalidDefaults: "invalid-defaults",
14
+ /** `defineCatalog` found `ui.fields` naming a path the schema does not define. Check the spelling against the schema. */
9
15
  HintPathUnresolvable: "hint-path-unresolvable",
16
+ /**
17
+ * `defineCatalog` found a `data` hint with no single target: a path through `[]`, which names
18
+ * every member of an array, or two hints whose paths nest and would write one value twice.
19
+ */
10
20
  HintNotAddressable: "hint-not-addressable",
11
21
  // Schema — what the consumer brought does not answer the one door core reads a schema through.
22
+ /**
23
+ * A schema exposes no `~standard.validate`, or answers with a promise. Validation is
24
+ * synchronous at registration and at compile, so an async validator is refused rather than
25
+ * awaited.
26
+ */
12
27
  NotStandardSchema: "not-standard-schema",
28
+ /**
29
+ * A schema exposes no Standard JSON Schema converter, which field introspection needs — the
30
+ * studio reads a block's fields through it.
31
+ */
13
32
  NoJsonSchema: "no-json-schema",
14
33
  // Structure — the document's graph cannot become a tree.
34
+ /** The document's `roots` is empty, so it names no entry element and there is no tree to build. */
15
35
  NoRoots: "no-roots",
36
+ /**
37
+ * A node names a block neither the registry nor the catalog holds. Register the block, or
38
+ * correct the node's `block`.
39
+ */
16
40
  UnknownBlock: "unknown-block",
41
+ /** A slot or a `roots` entry references an id that `elements` does not hold. */
17
42
  DanglingChild: "dangling-child",
43
+ /** A node reaches back to one of its own ancestors, so the graph cannot flatten into a tree. */
18
44
  Cycle: "cycle",
45
+ /** No slot reaches the node from any root, so it would be dropped silently on compile. */
19
46
  Unreachable: "unreachable",
47
+ /** A slot the block never declared, or a child the slot's `allow` list rejects. */
20
48
  SlotNotAllowed: "slot-not-allowed",
49
+ /** A slot holds fewer children than its `min`. An omitted slot holds zero. */
21
50
  SlotMin: "slot-min",
51
+ /** A slot holds more children than its `max`. */
22
52
  SlotMax: "slot-max",
23
53
  // Props — the values a node carries, judged against the block's schema.
54
+ /**
55
+ * A node's props failed its schema, or parsed to something other than an object. `path` names
56
+ * the offending field.
57
+ */
24
58
  InvalidProps: "invalid-props",
59
+ /**
60
+ * A key the author wrote and the schema did not keep — almost always a typo, `heading` where
61
+ * the schema says `headline`. **Returned in `CompileResult.issues`, never thrown:** the
62
+ * artifact is valid and publishable without that key.
63
+ */
25
64
  UnknownProp: "unknown-prop",
26
65
  // Document operations — the caller named something the document does not hold.
66
+ /** `setNodeProp`, `addNode`, `removeNode` or `moveNode` named a node id no element backs. */
27
67
  NoSuchNode: "no-such-node",
68
+ /**
69
+ * `addNode` was given an id the document already uses. Reusing one would replace a node and
70
+ * redirect every slot that named it.
71
+ */
28
72
  DuplicateNodeId: "duplicate-node-id",
73
+ /**
74
+ * A prop path with no single target: an empty segment, an `[]`, or a descent into an array.
75
+ * Raised by `setAtPath` and by `setNodeProp`.
76
+ */
29
77
  PathNotAddressable: "path-not-addressable",
78
+ /**
79
+ * A route no request could match — no leading slash, a trailing slash, an empty or malformed
80
+ * segment, or a `*` that is not the last one. Raised by `compile` and by `parseMatchKind`.
81
+ */
30
82
  InvalidRoute: "invalid-route",
31
83
  // Render — the artifact and the registry serving it disagree.
84
+ /** `@nubbin/react`: the block registry has no importer for a block the artifact names. */
32
85
  BlockNotLoaded: "block-not-loaded",
86
+ /** `@nubbin/react`: a node declares holes and the render was given no `resolveHole`. */
33
87
  NoHoleResolver: "no-hole-resolver",
88
+ /** `@nubbin/react`: a block returned a Fragment, a composite, or several roots where one host element is required. */
34
89
  NotOneHostElement: "not-one-host-element",
35
90
  // Store — a write the store cannot honour.
91
+ /** A publish names a hash the store does not hold. Write the artifact before pointing a route at it. */
36
92
  ArtifactNotStored: "artifact-not-stored"
37
93
  };
38
94
 
@@ -57,7 +113,17 @@ var NubbinError = class extends Error {
57
113
  * Every refusal but `compile`'s carries exactly one issue; read `issues` for the rest.
58
114
  */
59
115
  code;
116
+ /**
117
+ * Every cause, in the order they were found, and never empty. This is what a log, a tracker or
118
+ * an editing surface serializes — each issue carries its own `code`, `at` and `path`.
119
+ */
60
120
  issues;
121
+ /**
122
+ * @param issues - The causes, first one first. `code` is taken from `issues[0]` and `message`
123
+ * is a summary of all of them.
124
+ * @throws {Error} A plain `Error`, not a `NubbinError`, when `issues` is empty — a refusal
125
+ * with no cause names nothing.
126
+ */
61
127
  constructor(issues) {
62
128
  const first = issues[0];
63
129
  if (first === void 0) {
@@ -128,6 +194,15 @@ function fieldNodeAt(path, node, optional) {
128
194
  if (kind === "enum" && Array.isArray(node.enum)) {
129
195
  return { path, kind, optional, members: node.enum.map(String) };
130
196
  }
197
+ if (kind === "string" && typeof node.maxLength === "number") {
198
+ return { path, kind, optional, maxLength: node.maxLength };
199
+ }
200
+ if (kind === "array") {
201
+ const field = { path, kind, optional };
202
+ if (typeof node.minItems === "number") field.minItems = node.minItems;
203
+ if (typeof node.maxItems === "number") field.maxItems = node.maxItems;
204
+ return field;
205
+ }
131
206
  return { path, kind, optional };
132
207
  }
133
208
 
@@ -175,6 +250,19 @@ function walkJsonSchema(node, basePath) {
175
250
 
176
251
  // src/adapters/zodAdapter.ts
177
252
  var zodAdapter = {
253
+ /**
254
+ * Every addressable path in a schema, as the field tree an editing surface renders.
255
+ *
256
+ * @param schema - The schema to read. It must expose the Standard JSON Schema converter —
257
+ * `~standard.jsonSchema` — which the spec has carried since 1.1.
258
+ * @returns One `FieldNode` per path, parent before child: dotted for object properties, `path[]`
259
+ * for an array's row shape, and a union's branch fields under the union's own path. The root
260
+ * has no entry. A path two union branches share is reported once, keeping the first kind seen.
261
+ * @throws {NubbinError} `no-json-schema` when the schema exposes no converter.
262
+ * @throws The converter's own error when the schema holds a type JSON Schema cannot represent —
263
+ * `z.date()`, for one. It is asked to throw rather than degrade, so an unrepresentable field
264
+ * fails at registration instead of arriving in the studio as a string field.
265
+ */
178
266
  describe(schema) {
179
267
  const fields = walkJsonSchema(projectJsonSchema(schema), "");
180
268
  const seen = /* @__PURE__ */ new Set();
@@ -795,7 +883,7 @@ function validateStructure(version, registry) {
795
883
  }
796
884
 
797
885
  // src/version.constants.ts
798
- var NUBBIN_VERSION = "0.1.1";
886
+ var NUBBIN_VERSION = "0.3.0";
799
887
 
800
888
  // src/compile.ts
801
889
  function compile(version, catalog, registry, route) {
@@ -965,6 +1053,22 @@ function formatCompatibilityReport(report) {
965
1053
  return [summary, ...report.incompatible.map(formatRouteIncompatibility)].join("\n");
966
1054
  }
967
1055
 
1056
+ // src/richText.constants.ts
1057
+ var RICH_TEXT_MARKS = ["strong", "em", "code"];
1058
+ var RICH_TEXT_BLOCK_KINDS = ["paragraph", "listItem"];
1059
+ var RICH_TEXT_SPAN_KEYS = ["text", "marks", "href"];
1060
+ var RICH_TEXT_BLOCK_KEYS = ["kind", "spans"];
1061
+
1062
+ // src/isRichTextBlockKind.ts
1063
+ function isRichTextBlockKind(value) {
1064
+ return RICH_TEXT_BLOCK_KINDS.some((kind) => kind === value);
1065
+ }
1066
+
1067
+ // src/isRichTextMark.ts
1068
+ function isRichTextMark(value) {
1069
+ return RICH_TEXT_MARKS.some((mark) => mark === value);
1070
+ }
1071
+
968
1072
  // src/withoutSlotChildren.ts
969
1073
  function withoutSlotChildren(node, removed) {
970
1074
  const entries = Object.entries(node.slots ?? {});
@@ -1038,17 +1142,6 @@ function defineStandardSchema(issuesOf, jsonSchemaOf) {
1038
1142
  };
1039
1143
  }
1040
1144
 
1041
- // src/richText.constants.ts
1042
- var RICH_TEXT_MARKS = ["strong", "em", "code"];
1043
- var RICH_TEXT_BLOCK_KINDS = ["paragraph", "listItem"];
1044
- var RICH_TEXT_SPAN_KEYS = ["text", "marks", "href"];
1045
- var RICH_TEXT_BLOCK_KEYS = ["kind", "spans"];
1046
-
1047
- // src/isRichTextBlockKind.ts
1048
- function isRichTextBlockKind(value) {
1049
- return RICH_TEXT_BLOCK_KINDS.some((kind) => kind === value);
1050
- }
1051
-
1052
1145
  // src/nestedSchemaIssues.ts
1053
1146
  function nestedSchemaIssues(schema, value, prefix) {
1054
1147
  const result = standardValidate(schema, value);
@@ -1059,11 +1152,6 @@ function nestedSchemaIssues(schema, value, prefix) {
1059
1152
  }));
1060
1153
  }
1061
1154
 
1062
- // src/isRichTextMark.ts
1063
- function isRichTextMark(value) {
1064
- return RICH_TEXT_MARKS.some((mark) => mark === value);
1065
- }
1066
-
1067
1155
  // src/richTextMarkIssues.ts
1068
1156
  function richTextMarkIssues(marks) {
1069
1157
  if (marks === void 0) return [];
@@ -1194,6 +1282,8 @@ function setNodeProp(version, nodeId, path, value) {
1194
1282
  export {
1195
1283
  NubbinError,
1196
1284
  NubbinIssueCode,
1285
+ RICH_TEXT_BLOCK_KINDS,
1286
+ RICH_TEXT_MARKS,
1197
1287
  addNode,
1198
1288
  checkCompatibility,
1199
1289
  checkRollback,
@@ -1202,6 +1292,8 @@ export {
1202
1292
  defineBlock,
1203
1293
  defineCatalog,
1204
1294
  formatCompatibilityReport,
1295
+ isRichTextBlockKind,
1296
+ isRichTextMark,
1205
1297
  moveNode,
1206
1298
  parseMatchKind,
1207
1299
  refuse,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nubbin/core",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "The Nubbin contract: define blocks, split catalog from registry, and compile a page document into an immutable artifact.",
5
5
  "keywords": [
6
6
  "nubbin",