@cmssy/cli 10.6.0 → 10.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.
Files changed (2) hide show
  1. package/dist/index.js +36 -6
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1007,7 +1007,7 @@ async function runLink(options, deps) {
1007
1007
 
1008
1008
  // src/types-command.ts
1009
1009
  import { mkdirSync as mkdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
1010
- import { dirname as dirname3, join as join6 } from "path";
1010
+ import { dirname as dirname3, relative, resolve as resolvePath } from "path";
1011
1011
  import { DEFAULT_CMSSY_API_URL } from "@cmssy/core";
1012
1012
 
1013
1013
  // src/model-types.ts
@@ -1244,6 +1244,22 @@ async function request(deps, endpoint, query, variables) {
1244
1244
  if (!body.data) throw new CliError("the delivery API returned no data");
1245
1245
  return body.data;
1246
1246
  }
1247
+ function describeDrift(previous, next) {
1248
+ const declared = (source, pattern) => new Set([...source.matchAll(pattern)].map((match) => match[1] ?? ""));
1249
+ const body = (source) => source.split("/** Every model in the")[0] ?? source;
1250
+ const models = /export interface (\w+)Data/g;
1251
+ const fields = /^\s{2}(\w+)\??:/gm;
1252
+ const lines = [];
1253
+ const report = (label, before, after) => {
1254
+ const added = [...after].filter((name) => !before.has(name));
1255
+ const removed = [...before].filter((name) => !after.has(name));
1256
+ if (added.length) lines.push(`+ ${label}: ${added.join(", ")}`);
1257
+ if (removed.length) lines.push(`- ${label}: ${removed.join(", ")}`);
1258
+ };
1259
+ report("models", declared(previous, models), declared(next, models));
1260
+ report("fields", declared(body(previous), fields), declared(body(next), fields));
1261
+ return lines.length ? lines : ["the generated output differs"];
1262
+ }
1247
1263
  function resolve3(value, fromEnv, variable) {
1248
1264
  const resolved = value?.trim() || fromEnv?.trim();
1249
1265
  if (!resolved) {
@@ -1280,7 +1296,10 @@ async function runTypes(options, deps) {
1280
1296
  );
1281
1297
  return 0;
1282
1298
  }
1283
- const outPath = join6(deps.cwd, options.out?.trim() || DEFAULT_OUT);
1299
+ const requested = options.out?.trim() || DEFAULT_OUT;
1300
+ const outPath = resolvePath(deps.cwd, requested);
1301
+ const inside = relative(deps.cwd, outPath);
1302
+ const shown = inside && !inside.startsWith("..") ? inside : outPath;
1284
1303
  const source = generateModelTypes(models, { workspace });
1285
1304
  let previous = null;
1286
1305
  try {
@@ -1289,9 +1308,19 @@ async function runTypes(options, deps) {
1289
1308
  previous = null;
1290
1309
  }
1291
1310
  if (previous === source) {
1292
- deps.log(`cmssy: ${options.out ?? DEFAULT_OUT} is up to date`);
1311
+ deps.log(`cmssy: ${shown} is up to date`);
1293
1312
  return 0;
1294
1313
  }
1314
+ if (options.check) {
1315
+ deps.log(
1316
+ previous === null ? `cmssy: ${shown} is missing - run \`cmssy types\` and commit it` : `cmssy: ${shown} is out of date with the "${workspace}" workspace`
1317
+ );
1318
+ if (previous !== null) {
1319
+ for (const line of describeDrift(previous, source)) deps.log(` ${line}`);
1320
+ }
1321
+ deps.log(" run `cmssy types` and commit the result");
1322
+ return 1;
1323
+ }
1295
1324
  mkdirSync3(dirname3(outPath), { recursive: true });
1296
1325
  writeFileSync4(outPath, source);
1297
1326
  const fieldCount = models.reduce(
@@ -1299,7 +1328,7 @@ async function runTypes(options, deps) {
1299
1328
  0
1300
1329
  );
1301
1330
  deps.log(
1302
- `cmssy: wrote ${options.out ?? DEFAULT_OUT} - ${models.length} model${models.length === 1 ? "" : "s"}, ${fieldCount} field${fieldCount === 1 ? "" : "s"}`
1331
+ `cmssy: wrote ${shown} - ${models.length} model${models.length === 1 ? "" : "s"}, ${fieldCount} field${fieldCount === 1 ? "" : "s"}`
1303
1332
  );
1304
1333
  deps.log(
1305
1334
  ` ${models.map((model) => model.slug).join(", ")}`
@@ -1321,7 +1350,7 @@ var USAGE = [
1321
1350
  " cmssy init [--dir <path>] [--force]",
1322
1351
  " cmssy add block <name> [--dir <path>]",
1323
1352
  " cmssy link [--token <cs_...>] [--workspace <slug>] [--preview-url <url>]",
1324
- " cmssy types [--out <path>] [--org <slug>] [--workspace <slug>]"
1353
+ " cmssy types [--out <path>] [--check] [--org <slug>] [--workspace <slug>]"
1325
1354
  ].join("\n");
1326
1355
  function flagValue(args, name) {
1327
1356
  const index = args.findIndex((arg) => arg === name);
@@ -1384,7 +1413,8 @@ async function main() {
1384
1413
  {
1385
1414
  out: flagValue(args, "--out"),
1386
1415
  org: flagValue(args, "--org"),
1387
- workspace: flagValue(args, "--workspace")
1416
+ workspace: flagValue(args, "--workspace"),
1417
+ check: hasFlag(args, "--check")
1388
1418
  },
1389
1419
  {
1390
1420
  cwd: process.cwd(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/cli",
3
- "version": "10.6.0",
3
+ "version": "10.7.0",
4
4
  "description": "The cmssy CLI: `cmssy init` wires cmssy into an existing Next.js, Astro or React Router app; `cmssy link` connects it to a workspace and verifies the editor wiring.",
5
5
  "keywords": [
6
6
  "cmssy",
@@ -27,7 +27,7 @@
27
27
  "assets"
28
28
  ],
29
29
  "dependencies": {
30
- "@cmssy/core": "10.6.0"
30
+ "@cmssy/core": "10.7.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^20.0.0",