@acid-cat/catalog 0.10.1 → 0.11.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.
Files changed (2) hide show
  1. package/dist/index.js +22 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -56,22 +56,25 @@ var Catalog = class {
56
56
  }
57
57
  for (const [name, schema] of this.#types) {
58
58
  if (!TYPE_NAME.test(name)) problems.push(`the type name ${name} is malformed`);
59
+ if (!isJsonObject(schema)) problems.push(`the type ${name} is not a JSON object`);
59
60
  problems.push(...this.#referenceProblems(schema).map((problem) => `the type ${name} ${problem}`));
60
61
  }
61
62
  for (const [id, capability] of this.#capabilities) {
62
- problems.push(...this.#entryProblems(id, capability));
63
63
  const schemas = [
64
- capability.input,
65
- capability.output,
66
- capability.state,
67
- ...Object.values(capability.failures ?? {})
64
+ ["input", capability.input],
65
+ ["output", capability.output],
66
+ ["state", capability.state],
67
+ ...Object.entries(capability.failures ?? {}).map(([tag, schema]) => [`failure ${tag}`, schema])
68
68
  ];
69
- for (const schema of schemas) if (schema !== void 0) problems.push(...this.#referenceProblems(schema).map((problem) => `${id} ${problem}`));
69
+ problems.push(...schemaProblems(id, schemas));
70
+ problems.push(...this.#entryProblems(id, capability));
71
+ for (const [, schema] of schemas) if (schema !== void 0) problems.push(...this.#referenceProblems(schema).map((problem) => `${id} ${problem}`));
70
72
  }
71
73
  for (const [id, event] of this.#events) {
72
74
  if (this.#capabilities.has(id)) problems.push(`${id} is both a capability and an event`);
75
+ problems.push(...schemaProblems(id, [["input", event.input], ["payload", event.payload]]));
73
76
  problems.push(...this.#entryProblems(id, event));
74
- if (event.payload !== void 0 && this.#resolve(event.payload).type !== "object") problems.push(`${id} payload does not describe an object`);
77
+ if (isJsonObject(event.payload) && this.#resolve(event.payload).type !== "object") problems.push(`${id} payload does not describe an object`);
75
78
  for (const schema of [event.input, event.payload]) if (schema !== void 0) problems.push(...this.#referenceProblems(schema).map((problem) => `${id} ${problem}`));
76
79
  }
77
80
  return problems;
@@ -84,7 +87,7 @@ var Catalog = class {
84
87
  const audience = entry.audience ?? [];
85
88
  if (new Set(audience).size !== audience.length) problems.push(`${id} repeats a target in its audience`);
86
89
  for (const target of audience) if (!this.#targets.has(target)) problems.push(`${id} names the undeclared target ${target}`);
87
- if (entry.input !== void 0 && this.#resolve(entry.input).type !== "object") problems.push(`${id} input does not describe an object`);
90
+ if (isJsonObject(entry.input) && this.#resolve(entry.input).type !== "object") problems.push(`${id} input does not describe an object`);
88
91
  return problems;
89
92
  }
90
93
  /** The catalog as a JSON value. Throws when the catalog breaks a rule. */
@@ -124,7 +127,8 @@ var Catalog = class {
124
127
  }
125
128
  #resolve(schema) {
126
129
  const name = typeof schema.$ref === "string" ? REFERENCE.exec(schema.$ref)?.[1] : void 0;
127
- return name === void 0 ? schema : this.#types.get(name) ?? schema;
130
+ const resolved = name === void 0 ? schema : this.#types.get(name) ?? schema;
131
+ return isJsonObject(resolved) ? resolved : {};
128
132
  }
129
133
  #referenceProblems(schema) {
130
134
  const problems = [];
@@ -137,11 +141,20 @@ var Catalog = class {
137
141
  return problems;
138
142
  }
139
143
  };
144
+ /**
145
+ * The schemas of a capability or an event that are not JSON objects. The types of this library allow only objects,
146
+ * but a JavaScript caller can still give a boolean schema such as `true`.
147
+ */
148
+ function schemaProblems(id, schemas) {
149
+ return schemas.filter(([, schema]) => schema !== void 0 && !isJsonObject(schema)).map(([member]) => `${id} ${member} is not a JSON object`);
150
+ }
140
151
  function compact(value) {
141
152
  return Object.fromEntries(Object.entries(value).filter(([, member]) => member !== void 0));
142
153
  }
143
154
  /** Tell if a value is an object that is not `null`. Each of its members is read as `unknown`. */
144
155
  const isRecord = (value) => value !== null && typeof value === "object";
156
+ /** Tell if a value is a JSON object: an object that is not `null` and not an array. */
157
+ const isJsonObject = (value) => isRecord(value) && !Array.isArray(value);
145
158
  function visit(value, onObject) {
146
159
  if (Array.isArray(value)) value.forEach((item) => visit(item, onObject));
147
160
  else if (isRecord(value)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acid-cat/catalog",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "Write an AcidCat catalog in TypeScript and render it in canonical form.",
5
5
  "keywords": [
6
6
  "acidcat",