@sidebase/base-config 0.3.3 → 0.3.4

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
@@ -176,7 +176,7 @@ TypeScript config file) in your devDependencies; `sync` adds both.
176
176
  | `trpcGuard` | `false` | Ban `publicProcedure` in `server/trpc/routers/**` |
177
177
  | `prismaImportGuard` | `false` | Ban `~~/prisma/` client imports outside server code |
178
178
  | `typeDefStyle` | `"interface"` | Prefer `interface` or `type` |
179
- | `autoImportPaths` | `["utils/", "composables/", "~~/shared/types/"]` | Paths Nuxt auto-imports, so direct imports are banned |
179
+ | `autoImportPaths` | `["utils/", "composables/", "~~/shared/types/"]` | Paths Nuxt auto-imports, so direct imports are banned in app code. The defaults cover `app/utils`, `shared/utils`, `app/composables` and `shared/types` under every Nuxt alias. Files in the root (or `layers/*`) `server/` and `shared/` dirs and relative imports are never matched |
180
180
  | `autoImportTypeOnly` | `[]` | Of those, paths where `import type` stays allowed |
181
181
  | `ignoresTypeAware` | config files | Files excluded from type-aware linting |
182
182
  | `testFilePattern` | `*.test`, `*.spec`, `*.stories` | Files where the `process.env` and auto-import bans are off |
@@ -12,7 +12,12 @@ interface CreateSidebaseEslintOptions {
12
12
  prismaImportGuard?: boolean;
13
13
  /** `ts/consistent-type-definitions`. Default `"interface"`. */
14
14
  typeDefStyle?: "interface" | "type";
15
- /** Paths banned from direct import (Nuxt auto-import). Default `["utils/", "composables/", "~~/shared/types/"]`. */
15
+ /**
16
+ * Paths banned from direct import (Nuxt auto-import). Default `["utils/", "composables/", "~~/shared/types/"]`.
17
+ * The defaults expand to the Nuxt 4 app-side dirs (`app/` and `shared/` utils) under every
18
+ * default alias. Paths starting with `~`, `@`, `#`, `/`, `./` or `../` are used as-is.
19
+ * Not applied to files in the root (or `layers/*`) `server/` and `shared/` dirs.
20
+ */
16
21
  autoImportPaths?: string[];
17
22
  /**
18
23
  * Subset of {@link autoImportPaths} where `import type { ... }` is still allowed
@@ -12,7 +12,12 @@ interface CreateSidebaseEslintOptions {
12
12
  prismaImportGuard?: boolean;
13
13
  /** `ts/consistent-type-definitions`. Default `"interface"`. */
14
14
  typeDefStyle?: "interface" | "type";
15
- /** Paths banned from direct import (Nuxt auto-import). Default `["utils/", "composables/", "~~/shared/types/"]`. */
15
+ /**
16
+ * Paths banned from direct import (Nuxt auto-import). Default `["utils/", "composables/", "~~/shared/types/"]`.
17
+ * The defaults expand to the Nuxt 4 app-side dirs (`app/` and `shared/` utils) under every
18
+ * default alias. Paths starting with `~`, `@`, `#`, `/`, `./` or `../` are used as-is.
19
+ * Not applied to files in the root (or `layers/*`) `server/` and `shared/` dirs.
20
+ */
16
21
  autoImportPaths?: string[];
17
22
  /**
18
23
  * Subset of {@link autoImportPaths} where `import type { ... }` is still allowed
@@ -35,6 +35,8 @@ const TRPC_ROUTERS_GLOB = "**/server/trpc/routers/**/*.{ts,js}";
35
35
  const ZOD_DEPRECATED_METHODS = ["extend", "merge", "passthrough"];
36
36
  const APP_FILES = ["**/*.{ts,vue}"];
37
37
  const APP_IGNORES = ["**/*.d.ts"];
38
+ const SHARED_FILES = ["shared/**/*.{ts,vue}", "layers/*/shared/**/*.{ts,vue}"];
39
+ const SERVER_FILES = ["server/**/*.{ts,vue}", "layers/*/server/**/*.{ts,vue}"];
38
40
  const PROCESS_ENV_PROPERTY = {
39
41
  object: "process",
40
42
  property: "env",
@@ -71,12 +73,26 @@ function zodImportStyleBans(options) {
71
73
  { selector: `ExportNamedDeclaration[source.value=${ZOD_SOURCE}][exportKind!='type'] ExportSpecifier[local.name='z'][exportKind!='type']`, message: ZOD_IMPORT_STYLE_MESSAGE }
72
74
  ];
73
75
  }
76
+ const NUXT_AUTO_IMPORT_GLOBS = /* @__PURE__ */ new Map([
77
+ ["utils", [
78
+ "~/utils/**",
79
+ "@/utils/**",
80
+ "~~/app/utils/**",
81
+ "@@/app/utils/**",
82
+ "~~/shared/utils/**",
83
+ "@@/shared/utils/**",
84
+ "#shared/utils/**"
85
+ ]],
86
+ ["composables", ["~/composables/**", "@/composables/**", "~~/app/composables/**", "@@/app/composables/**"]],
87
+ ["~~/shared/types", ["~~/shared/types/**", "@@/shared/types/**", "#shared/types/**"]]
88
+ ]);
89
+ function escapeGlob(glob) {
90
+ return glob.replace(/^#/, "\\#");
91
+ }
74
92
  function anchoredGlobs(rawPath) {
75
93
  const path = rawPath.replace(/\/+$/, "");
76
- if (/^(?:[~@#/]|\.{1,2}\/)/.test(path)) {
77
- return [`${path}/**`];
78
- }
79
- return [`~/${path}/**`, `~~/${path}/**`, `@/${path}/**`];
94
+ const [first, ...rest] = NUXT_AUTO_IMPORT_GLOBS.get(path) ?? (/^(?:[~@#/]|\.{1,2}\/)/.test(path) ? [`${path}/**`] : [`~/${path}/**`, `~~/${path}/**`, `@/${path}/**`]);
95
+ return [escapeGlob(first), ...rest.map(escapeGlob)];
80
96
  }
81
97
  function importRestrictions(options) {
82
98
  const paths = [
@@ -150,18 +166,27 @@ function buildEslintLayers(options) {
150
166
  }
151
167
  });
152
168
  const { paths, patterns } = importRestrictions(options);
153
- const appRules = {
154
- "no-restricted-properties": ["error", PROCESS_ENV_PROPERTY]
155
- };
156
- if (paths.length > 0 || patterns.length > 0) {
157
- appRules["ts/no-restricted-imports"] = ["error", { paths, patterns }];
169
+ const prismaPatterns = options.prismaImportGuard ? [{
170
+ group: ["~~/prisma/*", "~~/prisma/**"],
171
+ message: "Do not import the Prisma client on the app side. Use a server-only module."
172
+ }] : [];
173
+ const scopes = [
174
+ ["sidebase/restricted-app", APP_FILES, [...patterns, ...prismaPatterns]],
175
+ ["sidebase/restricted-shared", SHARED_FILES, prismaPatterns],
176
+ // Server code legitimately imports the Prisma client.
177
+ ["sidebase/restricted-server", SERVER_FILES, []]
178
+ ];
179
+ for (const [name, files, scopePatterns] of scopes) {
180
+ configs.push({
181
+ name,
182
+ files,
183
+ ignores: APP_IGNORES,
184
+ rules: {
185
+ "no-restricted-properties": ["error", PROCESS_ENV_PROPERTY],
186
+ "ts/no-restricted-imports": ["error", scopePatterns.length > 0 ? { paths, patterns: scopePatterns } : { paths }]
187
+ }
188
+ });
158
189
  }
159
- configs.push({
160
- name: "sidebase/restricted-app",
161
- files: APP_FILES,
162
- ignores: APP_IGNORES,
163
- rules: appRules
164
- });
165
190
  const zodSyntax = [...zodImportStyleBans(options), ...zodMethodBans(options)];
166
191
  if (zodSyntax.length > 0) {
167
192
  configs.push({
@@ -180,18 +205,6 @@ function buildEslintLayers(options) {
180
205
  rules: { "no-restricted-syntax": ["error", ...zodSyntax, PUBLIC_PROCEDURE_SELECTOR] }
181
206
  });
182
207
  }
183
- if (options.prismaImportGuard) {
184
- const prismaPattern = {
185
- group: ["~~/prisma/*", "~~/prisma/**"],
186
- message: "Do not import the Prisma client on the app side. Use a server-only module."
187
- };
188
- configs.push({
189
- name: "sidebase/prisma-import-guard",
190
- files: APP_FILES,
191
- ignores: [...APP_IGNORES, "**/server/**"],
192
- rules: { "ts/no-restricted-imports": ["error", { paths, patterns: [...patterns, prismaPattern] }] }
193
- });
194
- }
195
208
  if (options.testFilePattern.length > 0) {
196
209
  configs.push({
197
210
  name: "sidebase/test-overrides",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sidebase/base-config",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Shared @sidebase base configuration for Nuxt repos: ESLint / Prisma / tsconfig factories on npm, plus the streamctl file-sync preset payload",
5
5
  "keywords": [
6
6
  "sidebase",