@cmssy/codemod 7.0.1 → 8.0.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 +83 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -162,9 +162,62 @@ function transform2(source) {
162
162
  return { code, changed };
163
163
  }
164
164
 
165
+ // src/v8.ts
166
+ var HAND_TYPED_CONTENT = /content\s*:\s*(Record<string,\s*unknown>|\{[^}]*\}|[A-Z]\w*(Content|Props))/;
167
+ function stripTypeArguments(source) {
168
+ const marker = "defineBlock<";
169
+ let code = source;
170
+ let changed = false;
171
+ for (let start = code.indexOf(marker); start !== -1; ) {
172
+ const open = start + marker.length - 1;
173
+ let depth = 0;
174
+ let end = -1;
175
+ for (let i = open; i < code.length; i++) {
176
+ const char = code[i];
177
+ if (char === "<") depth++;
178
+ else if (char === ">") {
179
+ depth--;
180
+ if (depth === 0) {
181
+ end = i;
182
+ break;
183
+ }
184
+ } else if (char === "(" || char === ";" || char === "\n") {
185
+ break;
186
+ }
187
+ }
188
+ if (end === -1) {
189
+ start = code.indexOf(marker, start + marker.length);
190
+ continue;
191
+ }
192
+ code = code.slice(0, open) + code.slice(end + 1);
193
+ changed = true;
194
+ start = code.indexOf(marker);
195
+ }
196
+ return { code, changed };
197
+ }
198
+ function transform3(source) {
199
+ const { code, changed } = stripTypeArguments(source);
200
+ const notes = [];
201
+ const usesBlockProps = /\bBlockProps\s*</.test(code);
202
+ if (/\bdefineBlock\s*[<(]/.test(code) && !usesBlockProps) {
203
+ notes.push(
204
+ "declares a block - type its component as BlockProps<typeof props>"
205
+ );
206
+ } else if (HAND_TYPED_CONTENT.test(code) && !usesBlockProps) {
207
+ notes.push(
208
+ "types a block's content by hand - derive it from the schema instead"
209
+ );
210
+ }
211
+ return notes.length > 0 ? { code, changed, notes } : { code, changed };
212
+ }
213
+
165
214
  // src/index.ts
166
- var TRANSFORMS = { v5: transform, v7: transform2 };
167
- var PREVIOUS_MAJOR = { v5: "4.x", v7: "6.x" };
215
+ var TRANSFORMS = { v5: transform, v7: transform2, v8: transform3 };
216
+ var PREVIOUS_MAJOR = {
217
+ v5: "4.x",
218
+ v7: "6.x",
219
+ v8: "7.x"
220
+ };
168
221
  var SKIP = /* @__PURE__ */ new Set(["node_modules", "dist", "build", "out", "coverage"]);
169
222
  var EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs"];
170
223
  function skipDirectory(name) {
@@ -186,9 +239,9 @@ async function sourceFiles(dir) {
186
239
  async function main() {
187
240
  const args = process.argv.slice(2);
188
241
  const version = args[0];
189
- const transform3 = TRANSFORMS[version];
190
- if (!transform3) {
191
- console.error("usage: cmssy-codemod v5|v7 [path] [--dry]");
242
+ const transform4 = TRANSFORMS[version];
243
+ if (!transform4) {
244
+ console.error("usage: cmssy-codemod v5|v7|v8 [path] [--dry]");
192
245
  process.exitCode = 1;
193
246
  return;
194
247
  }
@@ -198,26 +251,44 @@ async function main() {
198
251
  );
199
252
  const files = await sourceFiles(target);
200
253
  const touched = [];
254
+ const manual = [];
201
255
  let needsCore = false;
202
256
  for (const file of files) {
203
257
  const source = await readFile(file, "utf8");
204
- const { code, changed } = transform3(source);
258
+ const { code, changed, notes } = transform4(source);
259
+ if (notes && notes.length > 0) manual.push({ file, notes });
205
260
  if (!changed) continue;
206
261
  touched.push(file);
207
262
  if (code.includes('from "@cmssy/core"')) needsCore = true;
208
263
  if (!dry) await writeFile(file, code);
209
264
  }
210
- if (touched.length === 0) {
265
+ const report = (file) => file.slice(target.length + 1);
266
+ if (touched.length === 0 && manual.length === 0) {
211
267
  console.log(
212
268
  `cmssy: nothing to migrate - no ${PREVIOUS_MAJOR[version]} imports found.`
213
269
  );
214
270
  return;
215
271
  }
216
- console.log(
217
- `cmssy: ${dry ? "would rewrite" : "rewrote"} ${touched.length} file(s):`
218
- );
219
- for (const file of touched) {
220
- console.log(` ${file.slice(target.length + 1)}`);
272
+ if (touched.length > 0) {
273
+ console.log(
274
+ `cmssy: ${dry ? "would rewrite" : "rewrote"} ${touched.length} file(s):`
275
+ );
276
+ for (const file of touched) console.log(` ${report(file)}`);
277
+ }
278
+ if (manual.length > 0) {
279
+ console.log(
280
+ `
281
+ cmssy: ${manual.length} file(s) need a human - a block's content must be
282
+ derived from its schema, and only you know which fields it means to read:
283
+ `
284
+ );
285
+ for (const { file, notes } of manual) {
286
+ console.log(` ${report(file)}
287
+ ${notes.join("\n ")}`);
288
+ }
289
+ console.log(
290
+ "\n https://github.com/cmssy-io/cmssy-sdk/blob/main/docs/migrations/v7-to-v8.md"
291
+ );
221
292
  }
222
293
  if (needsCore && !await dependsOnCore(target)) {
223
294
  console.log(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmssy/codemod",
3
- "version": "7.0.1",
3
+ "version": "8.0.0",
4
4
  "description": "Rewrites cmssy imports across major versions, so a breaking release costs minutes instead of an afternoon.",
5
5
  "keywords": [
6
6
  "cmssy",