@everysk/apps-devkit 0.3.0-beta-20261019175049 → 0.3.0-beta-20261021134122

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/README.md CHANGED
@@ -54,15 +54,17 @@ export default defineAppTestConfig();
54
54
 
55
55
  ```js
56
56
  // eslint.config.js
57
- import { everyskConfig } from "@everysk/apps-devkit/eslint";
57
+ import { defineAppLintConfig } from "@everysk/apps-devkit/eslint";
58
58
 
59
- export default everyskConfig({ tsconfigRootDir: import.meta.dirname });
59
+ export default defineAppLintConfig({ tsconfigRootDir: import.meta.dirname });
60
60
  ```
61
61
 
62
62
  `tsconfigRootDir` is the app's own directory, which only its config can name. In a repository of
63
63
  several apps, linting them in one run (an editor does, and so does `eslint` from the root) fails
64
64
  with "No tsconfigRootDir was set, and multiple candidate TSConfigRootDirs are present" without it.
65
- `everyskConfig(extra)` still works, and so does `everyskConfig({ tsconfigRootDir, extra })`.
65
+ The app's own blocks go in `extra`: `defineAppLintConfig({ tsconfigRootDir, extra: [{ files, rules }] })`,
66
+ or the array alone, `defineAppLintConfig([...])`. Any other key throws: a block passed without its
67
+ array used to be read as options and its rules dropped in silence.
66
68
 
67
69
  ```jsonc
68
70
  // tsconfig.app.json
@@ -82,7 +84,7 @@ with "No tsconfigRootDir was set, and multiple candidate TSConfigRootDirs are pr
82
84
  |---|---|
83
85
  | `/vite` | `defineAppConfig`, plus on their own: the dev proxy, the `/file/` route plugin, the token source they share, and the two config plugins |
84
86
  | `/vitest` | `defineAppTestConfig` |
85
- | `/eslint` | `everyskConfig` |
87
+ | `/eslint` | `defineAppLintConfig` |
86
88
  | `/prettier` | the Prettier config as JSON |
87
89
  | `/tsconfig`, `/tsconfig/node`, `/tsconfig/vitest` | the TypeScript bases |
88
90
 
@@ -1,5 +1,5 @@
1
1
  import { defineConfig } from "eslint/config";
2
- export type EveryskConfigOptions = {
2
+ export type AppLintConfigOptions = {
3
3
  /**
4
4
  * The app's directory, `import.meta.dirname` in its `eslint.config.js`. An editor lints a
5
5
  * repository of several apps in one ESLint process, where typescript-eslint refuses to pick
@@ -10,13 +10,13 @@ export type EveryskConfigOptions = {
10
10
  extra?: ReturnType<typeof defineConfig>;
11
11
  };
12
12
  /**
13
- * everyskConfig
13
+ * defineAppLintConfig
14
14
  *
15
15
  * The ESLint configuration every Everysk app shares, so an app's `eslint.config.js` is:
16
16
  *
17
17
  * ```js
18
- * import { everyskConfig } from "@everysk/apps-devkit/eslint";
19
- * export default everyskConfig({ tsconfigRootDir: import.meta.dirname });
18
+ * import { defineAppLintConfig } from "@everysk/apps-devkit/eslint";
19
+ * export default defineAppLintConfig({ tsconfigRootDir: import.meta.dirname });
20
20
  * ```
21
21
  *
22
22
  * It encodes the conventions that lint can actually check: no MUI barrel imports, and no
@@ -25,5 +25,5 @@ export type EveryskConfigOptions = {
25
25
  *
26
26
  * Takes the options, or the app's own blocks alone, as it did before there were options.
27
27
  */
28
- export declare const everyskConfig: (optionsOrExtra?: EveryskConfigOptions | ReturnType<typeof defineConfig>) => import("eslint/config").ConfigObject[];
28
+ export declare const defineAppLintConfig: (optionsOrExtra?: AppLintConfigOptions | ReturnType<typeof defineConfig>) => import("eslint/config").ConfigObject[];
29
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAC;AAmB5D,MAAM,MAAM,oBAAoB,GAAG;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wFAAwF;IACxF,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa,GACtB,iBAAgB,oBAAoB,GAAG,UAAU,CAAC,OAAO,YAAY,CAAM,2CAuD9E,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAC;AAmB5D,MAAM,MAAM,oBAAoB,GAAG;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wFAAwF;IACxF,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;CAC3C,CAAC;AA+BF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB,GAC5B,iBAAgB,oBAAoB,GAAG,UAAU,CAAC,OAAO,YAAY,CAAM,2CAyD9E,CAAC"}
@@ -17,14 +17,36 @@ const noBarrelPaths = [
17
17
  ];
18
18
  // Data-layer rule: pages and components reach data only through entity hooks.
19
19
  const dataLayerMessage = "Data access only via entity hooks (@everysk/apps-sdk/<entity> or @/hooks/...). Pages and components must not call axios or an api module directly.";
20
+ const OPTION_KEYS = [
21
+ "tsconfigRootDir",
22
+ "extra",
23
+ ];
24
+ /**
25
+ * Throws on a key that is not an option, and on an `extra` that is not an array. A block passed
26
+ * without its array (`{ files, rules }`) used to be read as options with neither option set,
27
+ * which dropped the app's rules in silence, and as `extra` it threw "extra is not iterable";
28
+ * `eslint.config.js` is JavaScript, so the options type never got to catch either.
29
+ */
30
+ const assertOptions = (options) => {
31
+ if (options.extra !== undefined && !Array.isArray(options.extra)) {
32
+ throw new Error("defineAppLintConfig: extra must be an array of blocks: extra: [{ files, rules }].");
33
+ }
34
+ const unknown = Object.keys(options).filter((key) => !OPTION_KEYS.includes(key));
35
+ if (unknown.length === 0)
36
+ return;
37
+ throw new Error(`defineAppLintConfig: ${unknown.map((key) => `"${key}"`).join(", ")} ` +
38
+ `${unknown.length === 1 ? "is not an option" : "are not options"}. ` +
39
+ `The options are ${OPTION_KEYS.join(" and ")}; ` +
40
+ "the app's own blocks go in extra: [{ files, rules }].");
41
+ };
20
42
  /**
21
- * everyskConfig
43
+ * defineAppLintConfig
22
44
  *
23
45
  * The ESLint configuration every Everysk app shares, so an app's `eslint.config.js` is:
24
46
  *
25
47
  * ```js
26
- * import { everyskConfig } from "@everysk/apps-devkit/eslint";
27
- * export default everyskConfig({ tsconfigRootDir: import.meta.dirname });
48
+ * import { defineAppLintConfig } from "@everysk/apps-devkit/eslint";
49
+ * export default defineAppLintConfig({ tsconfigRootDir: import.meta.dirname });
28
50
  * ```
29
51
  *
30
52
  * It encodes the conventions that lint can actually check: no MUI barrel imports, and no
@@ -33,7 +55,9 @@ const dataLayerMessage = "Data access only via entity hooks (@everysk/apps-sdk/<
33
55
  *
34
56
  * Takes the options, or the app's own blocks alone, as it did before there were options.
35
57
  */
36
- export const everyskConfig = (optionsOrExtra = {}) => {
58
+ export const defineAppLintConfig = (optionsOrExtra = {}) => {
59
+ if (!Array.isArray(optionsOrExtra))
60
+ assertOptions(optionsOrExtra);
37
61
  const { tsconfigRootDir, extra = [] } = Array.isArray(optionsOrExtra)
38
62
  ? { extra: optionsOrExtra }
39
63
  : optionsOrExtra;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,UAAU,MAAM,2BAA2B,CAAC;AACnD,OAAO,YAAY,MAAM,6BAA6B,CAAC;AACvD,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE5D,mFAAmF;AACnF,MAAM,aAAa,GAAG;IAClB;QACI,IAAI,EAAE,eAAe;QACrB,OAAO,EACH,qGAAqG;KAC5G;IACD;QACI,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,gFAAgF;KAC5F;CACJ,CAAC;AAEF,8EAA8E;AAC9E,MAAM,gBAAgB,GAClB,oJAAoJ,CAAC;AAazJ;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CACzB,iBAAyE,EAAE,EAC7E,EAAE;IACA,MAAM,EAAE,eAAe,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;QACjE,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE;QAC3B,CAAC,CAAC,cAAc,CAAC;IAErB,OAAO,YAAY,CAAC;QAChB,aAAa,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACnC;YACI,KAAK,EAAE,CAAC,eAAe,CAAC;YACxB,OAAO,EAAE;gBACL,EAAE,CAAC,OAAO,CAAC,WAAW;gBACtB,QAAQ,CAAC,OAAO,CAAC,WAAW;gBAC5B,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC;gBAC7C,YAAY,CAAC,OAAO,CAAC,IAAI;aAC5B;YACD,eAAe,EAAE;gBACb,WAAW,EAAE,IAAI;gBACjB,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrE;YACD,KAAK,EAAE;gBACH,0CAA0C,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;aAClF;SACJ;QACD;YACI,kFAAkF;YAClF,qCAAqC;YACrC,KAAK,EAAE,CAAC,yBAAyB,EAAE,8BAA8B,CAAC;YAClE,KAAK,EAAE;gBACH,0CAA0C,EAAE;oBACxC,OAAO;oBACP;wBACI,KAAK,EAAE;4BACH,GAAG,aAAa;4BAChB,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE;4BAC5C,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE;yBAC/C;wBACD,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;qBAChE;iBACJ;aACJ;SACJ;QACD;YACI,gFAAgF;YAChF,+EAA+E;YAC/E,sCAAsC;YACtC,KAAK,EAAE,CAAC,+BAA+B,EAAE,wBAAwB,CAAC;YAClE,KAAK,EAAE;gBACH,0CAA0C,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;gBAC/E,sCAAsC,EAAE,KAAK;aAChD;SACJ;QACD,GAAG,KAAK;KACX,CAAC,CAAC;AACP,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/eslint/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everysk/apps-devkit",
3
- "version": "0.3.0-beta-20261019175049",
3
+ "version": "0.3.0-beta-20261021134122",
4
4
  "description": "Build-time presets for Everysk client applications: Vite, ESLint, Vitest, TypeScript and Prettier.",
5
5
  "keywords": [
6
6
  "everysk",
@@ -22,7 +22,7 @@ const noBarrelPaths = [
22
22
  const dataLayerMessage =
23
23
  "Data access only via entity hooks (@everysk/apps-sdk/<entity> or @/hooks/...). Pages and components must not call axios or an api module directly.";
24
24
 
25
- export type EveryskConfigOptions = {
25
+ export type AppLintConfigOptions = {
26
26
  /**
27
27
  * The app's directory, `import.meta.dirname` in its `eslint.config.js`. An editor lints a
28
28
  * repository of several apps in one ESLint process, where typescript-eslint refuses to pick
@@ -33,14 +33,43 @@ export type EveryskConfigOptions = {
33
33
  extra?: ReturnType<typeof defineConfig>;
34
34
  };
35
35
 
36
+ const OPTION_KEYS: readonly string[] = [
37
+ "tsconfigRootDir",
38
+ "extra",
39
+ ] satisfies (keyof AppLintConfigOptions)[];
40
+
41
+ /**
42
+ * Throws on a key that is not an option, and on an `extra` that is not an array. A block passed
43
+ * without its array (`{ files, rules }`) used to be read as options with neither option set,
44
+ * which dropped the app's rules in silence, and as `extra` it threw "extra is not iterable";
45
+ * `eslint.config.js` is JavaScript, so the options type never got to catch either.
46
+ */
47
+ const assertOptions = (options: AppLintConfigOptions) => {
48
+ if (options.extra !== undefined && !Array.isArray(options.extra)) {
49
+ throw new Error(
50
+ "defineAppLintConfig: extra must be an array of blocks: extra: [{ files, rules }].",
51
+ );
52
+ }
53
+
54
+ const unknown = Object.keys(options).filter((key) => !OPTION_KEYS.includes(key));
55
+ if (unknown.length === 0) return;
56
+
57
+ throw new Error(
58
+ `defineAppLintConfig: ${unknown.map((key) => `"${key}"`).join(", ")} ` +
59
+ `${unknown.length === 1 ? "is not an option" : "are not options"}. ` +
60
+ `The options are ${OPTION_KEYS.join(" and ")}; ` +
61
+ "the app's own blocks go in extra: [{ files, rules }].",
62
+ );
63
+ };
64
+
36
65
  /**
37
- * everyskConfig
66
+ * defineAppLintConfig
38
67
  *
39
68
  * The ESLint configuration every Everysk app shares, so an app's `eslint.config.js` is:
40
69
  *
41
70
  * ```js
42
- * import { everyskConfig } from "@everysk/apps-devkit/eslint";
43
- * export default everyskConfig({ tsconfigRootDir: import.meta.dirname });
71
+ * import { defineAppLintConfig } from "@everysk/apps-devkit/eslint";
72
+ * export default defineAppLintConfig({ tsconfigRootDir: import.meta.dirname });
44
73
  * ```
45
74
  *
46
75
  * It encodes the conventions that lint can actually check: no MUI barrel imports, and no
@@ -49,9 +78,11 @@ export type EveryskConfigOptions = {
49
78
  *
50
79
  * Takes the options, or the app's own blocks alone, as it did before there were options.
51
80
  */
52
- export const everyskConfig = (
53
- optionsOrExtra: EveryskConfigOptions | ReturnType<typeof defineConfig> = {},
81
+ export const defineAppLintConfig = (
82
+ optionsOrExtra: AppLintConfigOptions | ReturnType<typeof defineConfig> = {},
54
83
  ) => {
84
+ if (!Array.isArray(optionsOrExtra)) assertOptions(optionsOrExtra);
85
+
55
86
  const { tsconfigRootDir, extra = [] } = Array.isArray(optionsOrExtra)
56
87
  ? { extra: optionsOrExtra }
57
88
  : optionsOrExtra;