@mapled/cli 0.4.0 → 0.5.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/doctor.js CHANGED
@@ -360,6 +360,15 @@ export function checkWebhook(webhook) {
360
360
  if (last.status === "pending") {
361
361
  return { key: "webhook", label, status: "warning", detail: `The last delivery to ${host} is still pending.` };
362
362
  }
363
+ if (last.error === "blocked") {
364
+ // Mapled resolved the host to a private address and never connected
365
+ return {
366
+ key: "webhook",
367
+ label,
368
+ status: "failed",
369
+ detail: `${host} resolves to a private address, which Mapled can't reach. Point the webhook at the public deployment.`,
370
+ };
371
+ }
363
372
  const reason = last.responseStatus ? `responded ${last.responseStatus}` : (last.error ?? "failed");
364
373
  return {
365
374
  key: "webhook",
package/dist/manifest.js CHANGED
@@ -84,6 +84,7 @@ export const FIELD_TYPE_LABEL = {
84
84
  group: "group",
85
85
  json: "JSON",
86
86
  location: "location",
87
+ computed: "computed",
87
88
  };
88
89
  export function typeLabel(type) {
89
90
  return FIELD_TYPE_LABEL[type] ?? type;
@@ -241,8 +242,12 @@ export function indexSchema(schema) {
241
242
  const index = new Map();
242
243
  for (const c of schema.collections) {
243
244
  const fields = new Map();
244
- for (const f of c.fields)
245
- fields.set(f.key, { displayName: f.displayName, type: f.type });
245
+ // a computed field (§14.9) binds as a field of its result type
246
+ const COMPUTED_AS = { number: "number", text: "short_text", boolean: "boolean", date: "date", datetime: "datetime" };
247
+ for (const f of c.fields) {
248
+ const type = f.type === "computed" && f.computed ? (COMPUTED_AS[f.computed.resultType] ?? f.type) : f.type;
249
+ fields.set(f.key, { displayName: f.displayName, type });
250
+ }
246
251
  index.set(c.key, { displayName: c.displayName, kind: c.kind, fields });
247
252
  }
248
253
  return index;
package/dist/pin.js CHANGED
@@ -104,6 +104,9 @@ function describeType(f, names) {
104
104
  if (f.type === "group" && "group" in f && f.group) {
105
105
  return `group of ${f.group.fields.length} field${f.group.fields.length === 1 ? "" : "s"}${f.group.repeatable ? ", repeatable" : ""}`;
106
106
  }
107
+ if (f.type === "computed" && "computed" in f && f.computed) {
108
+ return `computed (${f.computed.resultType === "datetime" ? "date and time" : f.computed.resultType})`;
109
+ }
107
110
  return typeLabel(f.type);
108
111
  }
109
112
  function diffCommon(before, after, names, push) {
@@ -186,6 +189,14 @@ export function diffSchema(before, after) {
186
189
  push("changed", `on delete ${bf.relation.onDelete ?? "default"} → ${af.relation.onDelete ?? "default"}`, "safe");
187
190
  }
188
191
  }
192
+ if (bf.type === "computed" && af.type === "computed" && bf.computed && af.computed) {
193
+ if (bf.computed.resultType !== af.computed.resultType) {
194
+ push("changed", `${describeType(bf, names)} → ${describeType(af, names)}`, "breaking");
195
+ }
196
+ else if (bf.computed.expression !== af.computed.expression) {
197
+ push("changed", "formula changed", "safe");
198
+ }
199
+ }
189
200
  if (bf.type === "group" && af.type === "group" && bf.group && af.group) {
190
201
  if (bf.group.repeatable !== af.group.repeatable) {
191
202
  push("changed", bf.group.repeatable ? "repeatable → single item" : "single item → repeatable", "breaking");
package/dist/schema.d.ts CHANGED
@@ -31,6 +31,12 @@ export type SchemaField = {
31
31
  /** Rules and default (§33) — kept in the schema pin, not read by the generator. */
32
32
  validation?: unknown;
33
33
  defaultValue?: unknown;
34
+ /** Computed fields (§14.9): the formula and what it produces — the
35
+ site reads the value as a field of the result type. */
36
+ computed?: {
37
+ expression: string;
38
+ resultType: string;
39
+ } | null;
34
40
  };
35
41
  export type SchemaCollection = {
36
42
  key: string;
package/dist/schema.js CHANGED
@@ -29,6 +29,8 @@ export function schemaHash(schema) {
29
29
  })),
30
30
  }
31
31
  : null,
32
+ // present only for computed fields, so schemas without formulas hash as before
33
+ ...(f.type === "computed" && f.computed ? { computed: { expression: f.computed.expression, resultType: f.computed.resultType } } : {}),
32
34
  })),
33
35
  }));
34
36
  return createHash("sha256").update(JSON.stringify(projection)).digest("hex").slice(0, 12);
package/dist/types.js CHANGED
@@ -94,6 +94,19 @@ function scalarType(type, options) {
94
94
  return { type: "unknown", note: type };
95
95
  }
96
96
  }
97
+ /** The field type a computed field is delivered as (§14.9). */
98
+ const COMPUTED_AS = {
99
+ number: "number",
100
+ text: "short_text",
101
+ boolean: "boolean",
102
+ date: "date",
103
+ datetime: "datetime",
104
+ };
105
+ /** What the site receives for a computed field: its result type, read-only. */
106
+ function computedType(resultType) {
107
+ const base = scalarType(COMPUTED_AS[resultType] ?? "", null);
108
+ return { type: base.type, note: `computed, ${base.note}` };
109
+ }
97
110
  function fieldLine(key, displayName, required, rendered) {
98
111
  const doc = ` /** ${comment(displayName)} — ${rendered.note} */`;
99
112
  const line = required ? ` ${prop(key)}: ${rendered.type};` : ` ${prop(key)}?: ${rendered.type} | null;`;
@@ -128,6 +141,9 @@ function renderField(field, owner, names, extras) {
128
141
  note,
129
142
  });
130
143
  }
144
+ if (field.type === "computed" && field.computed) {
145
+ return fieldLine(field.key, field.displayName, false, computedType(field.computed.resultType));
146
+ }
131
147
  return fieldLine(field.key, field.displayName, field.required, scalarType(field.type, field.options));
132
148
  }
133
149
  /** Unique type names: the singular PascalCase of the key; the raw
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mapled/cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Mapled CLI — sign in, link a project, generate TypeScript types for its content and check the site's integration.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://mapled.io",