@griddo/ax 12.2.3-rc.1 → 12.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.
@@ -100,10 +100,14 @@ describe("webpack.config.js — wp5 patterns", () => {
100
100
  expect(webpackConfig).toContain("namedExport: true");
101
101
  });
102
102
 
103
- test("CSS modules use exportLocalsConvention dashesOnly (not camelCaseOnly)", () => {
104
- // camelCaseOnly converts @keyframes _in export var in (reserved word!)
105
- // dashesOnly only converts hyphens, keeping _in as _in (valid identifier)
106
- expect(webpackConfig).toContain('exportLocalsConvention: "dashesOnly"');
103
+ test("CSS modules use exportLocalsConvention asIs (webpack 4 class names)", () => {
104
+ // asIs keeps the names as written in the CSS, so client projects keep
105
+ // reading `styles["heading-sm"]` exactly like they did under webpack 4.
106
+ // css-loader derives `useExportsAs` from this value (its own option is not
107
+ // user-settable) and emits `export { _1 as "heading-sm" }`, so hyphenated
108
+ // classes are valid named exports. The convention to avoid is camelCaseOnly:
109
+ // it turns @keyframes _in into `export var in` (reserved word).
110
+ expect(webpackConfig).toContain('exportLocalsConvention: "asIs"');
107
111
  });
108
112
 
109
113
  test("postcss-loader uses postcssOptions (not ident + plugins fn)", () => {
@@ -370,8 +374,10 @@ describe("package.json — wp5 dependencies", () => {
370
374
  expect(allDeps["react-dev-utils"]).toMatch(/^\^?12/);
371
375
  });
372
376
 
373
- test("css-loader is ^6.x", () => {
374
- expect(allDeps["css-loader"]).toMatch(/^\^?6/);
377
+ test("css-loader is ^6.11.x (asIs + namedExport needs useExportsAs)", () => {
378
+ // Earlier 6.x rejected `exportLocalsConvention: "asIs"` alongside
379
+ // `namedExport: true`, so the floor is not just ^6.
380
+ expect(allDeps["css-loader"]).toMatch(/^\^?6\.(1[1-9]|[2-9]\d)/);
375
381
  });
376
382
 
377
383
  test("babel-loader is ^9.x", () => {
@@ -470,10 +470,13 @@ module.exports = function (webpackEnv) {
470
470
  // only sees locals as named exports when `namedExport` is on.
471
471
  // griddo-components relies on `import * as styles` heavily.
472
472
  namedExport: true,
473
- // `dashesOnly` converts only hyphenated names (foo-bar -> fooBar) so
474
- // `composes: heading-sm` works, while leaving JS-reserved names such as
475
- // `@keyframes _in` untouched (camelCaseOnly would break those).
476
- exportLocalsConvention: "dashesOnly",
473
+ // `asIs` keeps the webpack 4 class names, so `styles["heading-sm"]`
474
+ // keeps working in client projects. css-loader derives
475
+ // `useExportsAs` from this value and emits
476
+ // `export { _1 as "heading-sm" }` instead of the invalid
477
+ // `export var heading-sm`. camelCaseOnly is what we must avoid:
478
+ // it would turn `@keyframes _in` into `export var in` (reserved word).
479
+ exportLocalsConvention: "asIs",
477
480
  getLocalIdent: getCSSModuleLocalIdent,
478
481
  },
479
482
  }),
@@ -507,7 +510,7 @@ module.exports = function (webpackEnv) {
507
510
  sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
508
511
  modules: {
509
512
  namedExport: true,
510
- exportLocalsConvention: "dashesOnly",
513
+ exportLocalsConvention: "asIs",
511
514
  getLocalIdent: getCSSModuleLocalIdent,
512
515
  },
513
516
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "12.2.3-rc.1",
4
+ "version": "12.3.0",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Diego M. Béjar <diego.bejar@secuoyas.com>",
@@ -77,7 +77,7 @@
77
77
  "case-sensitive-paths-webpack-plugin": "2.4.0",
78
78
  "compress.js": "1.2.2",
79
79
  "connected-react-router": "6.9.3",
80
- "css-loader": "^6.8.0",
80
+ "css-loader": "^6.11.0",
81
81
  "css-minimizer-webpack-plugin": "^5.0.0",
82
82
  "date-fns": "2.30.0",
83
83
  "dotenv": "6.2.0",
@@ -213,5 +213,5 @@
213
213
  "publishConfig": {
214
214
  "access": "public"
215
215
  },
216
- "gitHead": "f328137a3b2bb2527d7d849e0ca9a2adec6f03cb"
216
+ "gitHead": "3702a3da08742efbc21a68aaae6c4617bde86e11"
217
217
  }
@@ -0,0 +1,67 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+
6
+ // GAINUP: la trazabilidad spec↔test es parte del contrato del paquete.
7
+ // El tooling GAINUP no vive en el repo: se instala aparte, en ~/.claude/gainup, y el repo
8
+ // solo lleva los artefactos (specs, config). Por eso este guardián se SALTA cuando el
9
+ // validador no está instalado: un clon sin el tooling no debe comerse rojos de una capa
10
+ // que no puede operar. Con el tooling presente corre igual que siempre.
11
+ // Corremos en --strict, como cx y render: errores (link-rot, UC active sin test,
12
+ // trace roto) y avisos (AC sin test, UC sin indexar en el README) ponen la suite
13
+ // en rojo. Sin --strict la red de este paquete sería más fina que la de sus
14
+ // vecinos sin que se viera.
15
+ const PKG_ROOT = join(__dirname, "..", ".."); // src/__tests__ -> griddo-ax
16
+ const TRACE = join(homedir(), ".claude", "gainup", "scripts", "gainup-trace.mjs");
17
+
18
+ // GAINUP se instala como plugin de Claude Code, y su ruta de instalación es versionada
19
+ // (…/plugins/cache/<marketplace>/gainup/<versión>/): el alias de arriba lo mantiene el hook
20
+ // SessionStart del plugin, porque este arnés corre desde `yarn` y no tiene ${CLAUDE_PLUGIN_ROOT}.
21
+ //
22
+ // «Sin instalar» es un estado legítimo y el guardián se salta. «Instalado pero sin resolver»
23
+ // no lo es: sería un verde por no haber validado nada — el verde falso contra el que está
24
+ // montada esta capa. Ese caso revienta nombrando el motivo en vez de saltarse en silencio.
25
+ const PLUGINS_DB = join(homedir(), ".claude", "plugins", "installed_plugins.json");
26
+ function gainupPluginInstalled(): boolean {
27
+ try {
28
+ const db = JSON.parse(readFileSync(PLUGINS_DB, "utf8")) as { plugins?: Record<string, unknown> };
29
+ return Object.keys(db.plugins ?? {}).some((key) => key.startsWith("gainup@"));
30
+ } catch {
31
+ return false; // sin fichero o ilegible: no hay plugin del que hablar
32
+ }
33
+ }
34
+
35
+ if (gainupPluginInstalled() && !existsSync(TRACE)) {
36
+ throw new Error(
37
+ `GAINUP consta instalado como plugin pero el validador no está en ${TRACE}. ` +
38
+ "Sin él este guardián se saltaría y la suite daría verde sin haber validado nada. " +
39
+ "Abre una sesión de Claude Code (el hook del plugin recrea el alias) o enlázalo a mano.",
40
+ );
41
+ }
42
+
43
+ // El validador deduce la raíz del monorepo subiendo desde el cwd; Jest corre desde el
44
+ // directorio del paquete, así que se la pasamos explícita.
45
+ const ENV = { ...process.env, GAINUP_REPO_ROOT: join(PKG_ROOT, "..", "..") };
46
+
47
+ // Jest no tiene `describe.skipIf` (es de Vitest): el ternario es su equivalente.
48
+ const describeIfInstalled = existsSync(TRACE) ? describe : describe.skip;
49
+
50
+ describeIfInstalled("GAINUP traceability", () => {
51
+ it("sin link-rot, UC sin test ni avisos (--strict)", () => {
52
+ let output = "";
53
+ let ok = true;
54
+ try {
55
+ output = execFileSync(process.execPath, [TRACE, "griddo-ax", "--strict"], {
56
+ encoding: "utf8",
57
+ env: ENV,
58
+ });
59
+ } catch (error) {
60
+ ok = false;
61
+ const e = error as { stdout?: string; stderr?: string };
62
+ output = `${e.stdout ?? ""}${e.stderr ?? ""}`;
63
+ }
64
+ if (!ok) console.error(output);
65
+ expect(ok).toBe(true);
66
+ });
67
+ });
@@ -1,23 +0,0 @@
1
- import { execFileSync } from "node:child_process";
2
- import { join } from "node:path";
3
-
4
- const PKG_ROOT = join(__dirname, "..", ".."); // src/__tests__ -> griddo-ax
5
- const TRACE = join(PKG_ROOT, "..", "..", "scripts", "aiup-trace.mjs");
6
-
7
- describe("Griddo-AIUP traceability", () => {
8
- it("sin link-rot, traza rota ni UC active sin test", () => {
9
- let output = "";
10
- let ok = true;
11
- try {
12
- output = execFileSync(process.execPath, [TRACE, "griddo-ax"], {
13
- encoding: "utf8",
14
- });
15
- } catch (error) {
16
- ok = false;
17
- const e = error as { stdout?: string; stderr?: string };
18
- output = `${e.stdout ?? ""}${e.stderr ?? ""}`;
19
- }
20
- if (!ok) console.error(output);
21
- expect(ok).toBe(true);
22
- });
23
- });