create-absolutejs 0.17.2 → 0.17.3

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/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@ This file is generated by `absolute-changelog` from the entries in
6
6
  `changelog/`. Edit an entry, not this file — and add new ones under
7
7
  `changelog/unreleased/`.
8
8
 
9
+ ## 0.17.3 — 2026-09-22
10
+
11
+ ### Fixed
12
+
13
+ - **Generate correctness-focused lint defaults with typed Drizzle checks and isolated Eden API subapps; consume eslint-plugin-absolute 0.12.0**
14
+
9
15
  ## 0.17.2 — 2026-09-22
10
16
 
11
17
  ### Fixed
package/changelog.json CHANGED
@@ -3,24 +3,34 @@
3
3
  "name": "create-absolutejs",
4
4
  "releases": [
5
5
  {
6
- "version": "0.17.2",
6
+ "changes": [
7
+ {
8
+ "kind": "fixed",
9
+ "summary": "Generate correctness-focused lint defaults with typed Drizzle checks and isolated Eden API subapps; consume eslint-plugin-absolute 0.12.0"
10
+ }
11
+ ],
7
12
  "date": "2026-09-22",
13
+ "version": "0.17.3"
14
+ },
15
+ {
8
16
  "changes": [
9
17
  {
10
18
  "kind": "fixed",
11
19
  "summary": "Use the Elysia 2 error lifecycle verified against a fresh generated project"
12
20
  }
13
- ]
21
+ ],
22
+ "date": "2026-09-22",
23
+ "version": "0.17.2"
14
24
  },
15
25
  {
16
- "version": "0.17.1",
17
- "date": "2026-09-22",
18
26
  "changes": [
19
27
  {
20
28
  "kind": "fixed",
21
29
  "summary": "Generate the Elysia 2 onError lifecycle instead of an unsupported on error hook"
22
30
  }
23
- ]
31
+ ],
32
+ "date": "2026-09-22",
33
+ "version": "0.17.1"
24
34
  }
25
35
  ]
26
36
  }
@@ -1,2 +1,3 @@
1
1
  import type { Frontend } from '../../types';
2
+ /** Correctness defaults; project-specific formatting belongs in Prettier. */
2
3
  export declare const generateEslintConfig: (frontends: Frontend[]) => string;
@@ -1,261 +1,51 @@
1
- export const generateEslintConfig = (frontends) => {
2
- const hasReact = frontends.includes('react');
3
- const reactImports = hasReact
4
- ? `import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
5
- import reactPlugin from 'eslint-plugin-react';
6
- import reactCompilerPlugin from 'eslint-plugin-react-compiler';
7
- import reactHooksPlugin from 'eslint-plugin-react-hooks';
8
- `
9
- : '';
10
- const reactBlock = hasReact
11
- ? ` {
12
- files: ['example/**/*.{js,jsx,ts,tsx}'],
13
- plugins: {
14
- 'jsx-a11y': fixupPluginRules(jsxA11yPlugin),
15
- react: fixupPluginRules(reactPlugin),
16
- 'react-compiler': reactCompilerPlugin,
17
- 'react-hooks': reactHooksPlugin
18
- },
19
- rules: {
20
- 'jsx-a11y/prefer-tag-over-role': 'error',
21
- 'react-compiler/react-compiler': 'error',
22
- 'react-hooks/exhaustive-deps': 'warn',
23
- 'react-hooks/rules-of-hooks': 'error',
24
- 'react/checked-requires-onchange-or-readonly': 'error',
25
- 'react/destructuring-assignment': ['error', 'always'],
26
- 'react/jsx-filename-extension': ['error', { extensions: ['.tsx'] }],
27
- 'react/jsx-no-leaked-render': 'error',
28
- 'react/jsx-no-target-blank': 'error',
29
- 'react/jsx-no-useless-fragment': 'error',
30
- 'react/jsx-pascal-case': ['error', { allowAllCaps: true }],
31
- 'react/no-multi-comp': 'error',
32
- 'react/no-unknown-property': 'off',
33
- 'react/react-in-jsx-scope': 'off',
34
- 'react/self-closing-comp': 'error'
35
- },
36
- settings: {
37
- react: { version: 'detect' }
38
- }
39
- },
40
- `
41
- : '';
42
- return `// eslint.config.mjs
43
- import { dirname } from 'path';
44
- import { fileURLToPath } from 'url';
45
- import { fixupPluginRules } from '@eslint/compat';
46
- import pluginJs from '@eslint/js';
47
- import stylistic from '@stylistic/eslint-plugin';
48
- import tsParser from '@typescript-eslint/parser';
1
+ /** Correctness defaults; project-specific formatting belongs in Prettier. */
2
+ export const generateEslintConfig = (frontends) => `
49
3
  import { defineConfig } from 'eslint/config';
50
- import absolutePlugin from 'eslint-plugin-absolute';
51
- import importPlugin from 'eslint-plugin-import';
52
- ${reactImports}import promisePlugin from 'eslint-plugin-promise';
53
- import securityPlugin from 'eslint-plugin-security';
54
- import globals from 'globals';
55
4
  import tseslint from 'typescript-eslint';
56
-
57
- const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ import absolute from 'eslint-plugin-absolute';
6
+ ${frontends.includes('react') ? "import reactHooks from 'eslint-plugin-react-hooks';" : ''}
58
7
 
59
8
  export default defineConfig([
60
- pluginJs.configs.recommended,
61
-
62
- ...tseslint.configs.recommended,
63
-
64
- {
65
- files: ['**/*.{ts,tsx}'],
66
- languageOptions: {
67
- globals: globals.browser,
68
- parser: tsParser,
69
- parserOptions: {
70
- createDefaultProgram: true,
71
- project: './tsconfig.json',
72
- tsconfigRootDir: __dirname
73
- }
74
- }
75
- },
76
-
77
- {
78
- files: ['**/*.{ts,tsx}'],
79
- plugins: { '@stylistic': stylistic },
80
- rules: {
81
- '@stylistic/padding-line-between-statements': [
82
- 'error',
83
- { blankLine: 'always', next: 'return', prev: '*' }
84
- ]
85
- }
86
- },
87
-
88
- {
89
- files: ['**/*.{js,mjs,cjs,ts,tsx,jsx}'],
90
- ignores: ['example/build/**'],
91
- plugins: {
92
- absolute: fixupPluginRules(absolutePlugin),
93
- import: fixupPluginRules(importPlugin),
94
- promise: fixupPluginRules(promisePlugin),
95
- security: fixupPluginRules(securityPlugin)
96
- },
97
- rules: {
98
- 'absolute/button-icon-is-hidden': 'error',
99
- 'absolute/explicit-object-types': 'error',
100
- 'absolute/icon-button-has-accessible-name': 'error',
101
- 'absolute/localize-react-props': 'error',
102
- 'absolute/max-depth-extended': ['error', 1],
103
- 'absolute/max-jsxnesting': ['error', 5],
104
- 'absolute/min-var-length': [
105
- 'error',
106
- { allowedVars: ['_', 'id', 'db', 'OK'], minLength: 3 }
107
- ],
108
- 'absolute/no-button-navigation': 'error',
109
- 'absolute/no-explicit-return-type': 'error',
110
- 'absolute/no-inline-prop-types': 'error',
111
- 'absolute/no-multi-style-objects': 'error',
112
- 'absolute/no-nested-jsx-return': 'error',
113
- 'absolute/no-or-none-component': 'error',
114
- 'absolute/no-transition-cssproperties': 'error',
115
- 'absolute/no-unnecessary-div': 'error',
116
- 'absolute/no-unnecessary-key': 'error',
117
- 'absolute/no-useless-function': 'error',
118
- 'absolute/seperate-style-files': 'error',
119
- 'absolute/sort-exports': [
120
- 'error',
121
- {
122
- caseSensitive: true,
123
- natural: true,
124
- order: 'asc',
125
- variablesBeforeFunctions: true
126
- }
127
- ],
128
- 'absolute/sort-keys-fixable': [
129
- 'error',
130
- {
131
- caseSensitive: true,
132
- natural: true,
133
- order: 'asc',
134
- variablesBeforeFunctions: true
135
- }
136
- ],
137
- 'arrow-body-style': ['error', 'as-needed'],
138
- 'consistent-return': 'error',
139
- eqeqeq: 'error',
140
- 'func-style': [
141
- 'error',
142
- 'expression',
143
- { allowArrowFunctions: true }
144
- ],
145
- 'import/no-cycle': 'error',
146
- 'import/no-default-export': 'error',
147
- 'import/no-relative-packages': 'error',
148
- 'import/no-unused-modules': ['error', { missingExports: true }],
149
- 'import/order': ['error', { alphabetize: { order: 'asc' } }],
150
- 'no-await-in-loop': 'error',
151
- 'no-console': ['error', { allow: ['warn', 'error'] }],
152
- 'no-debugger': 'error',
153
- 'no-duplicate-case': 'error',
154
- 'no-duplicate-imports': 'error',
155
- 'no-else-return': 'error',
156
- 'no-empty-function': 'error',
157
- 'no-empty-pattern': 'error',
158
- 'no-empty-static-block': 'error',
159
- 'no-fallthrough': 'error',
160
- 'no-floating-decimal': 'error',
161
- 'no-global-assign': 'error',
162
- 'no-implicit-coercion': 'error',
163
- 'no-implicit-globals': 'error',
164
- 'no-loop-func': 'error',
165
- 'no-magic-numbers': [
166
- 'warn',
167
- { detectObjects: false, enforceConst: true, ignore: [0, 1] }
168
- ],
169
- 'no-misleading-character-class': 'error',
170
- 'no-nested-ternary': 'error',
171
- 'no-new-native-nonconstructor': 'error',
172
- 'no-new-wrappers': 'error',
173
- 'no-param-reassign': 'error',
174
- 'no-restricted-imports': [
175
- 'error',
176
- {
177
- paths: [
178
- {
179
- importNames: ['default'],
180
- message:
181
- 'Import only named React exports for tree-shaking.',
182
- name: 'react'
183
- },
184
- {
185
- importNames: ['default'],
186
- message: 'Import only the required Bun exports.',
187
- name: 'bun'
188
- }
189
- ]
190
- }
191
- ],
192
- 'no-return-await': 'error',
193
- 'no-shadow': 'error',
194
- 'no-undef': 'error',
195
- 'no-unneeded-ternary': 'error',
196
- 'no-unreachable': 'error',
197
- 'no-useless-assignment': 'error',
198
- 'no-useless-concat': 'error',
199
- 'no-useless-return': 'error',
200
- 'no-var': 'error',
201
- 'prefer-arrow-callback': 'error',
202
- 'prefer-const': 'error',
203
- 'prefer-destructuring': [
204
- 'error',
205
- { array: true, object: true },
206
- { enforceForRenamedProperties: false }
207
- ],
208
- 'prefer-template': 'error',
209
- 'promise/always-return': 'warn',
210
- 'promise/avoid-new': 'warn',
211
- 'promise/catch-or-return': 'error',
212
- 'promise/no-callback-in-promise': 'warn',
213
- 'promise/no-nesting': 'warn',
214
- 'promise/no-promise-in-callback': 'warn',
215
- 'promise/no-return-wrap': 'error',
216
- 'promise/param-names': 'error'
217
- }
218
- },
219
- {
220
- files: ['**/*.{html,vue,svelte,gjs,gts}'],
221
- ignores: ['example/build/**'],
222
- plugins: { absolute: fixupPluginRules(absolutePlugin) },
223
- processor: 'absolute/template-source'
224
- },
225
- ${reactBlock} {
226
- files: [
227
- 'example/server.ts',
228
- 'example/indexes/*.tsx',
229
- 'example/db/migrate.ts'
230
- ],
231
- rules: {
232
- 'import/no-unused-modules': 'off'
233
- }
234
- },
235
- {
236
- files: ['example/db/migrate.ts', 'example/utils/absoluteAuthConfig.ts'],
237
- rules: {
238
- 'no-console': 'off'
239
- }
240
- },
241
- {
242
- files: ['eslint.config.mjs'],
243
- rules: {
244
- 'no-magic-numbers': 'off'
245
- }
246
- },
247
- {
248
- files: ['eslint.config.mjs'],
249
- rules: {
250
- 'import/no-default-export': 'off'
251
- }
252
- },
253
- {
254
- files: ['example/db/schema.ts'],
255
- rules: {
256
- 'absolute/explicit-object-types': 'off'
257
- }
258
- }
9
+ { ignores: ['node_modules/**', 'build/**', 'dist/**', '.absolutejs/**', '.data/**', '**/.absolutejs-hmr-*', 'drizzle/**'] },
10
+ { linterOptions: { noInlineConfig: true, reportUnusedDisableDirectives: 'error' } },
11
+ ...tseslint.configs.recommended,
12
+ {
13
+ files: ['**/*.{ts,tsx,js,jsx,mjs}'],
14
+ plugins: { absolute },
15
+ rules: {
16
+ '@typescript-eslint/ban-ts-comment': ['error', { 'ts-check': true, 'ts-expect-error': true, 'ts-ignore': true, 'ts-nocheck': true }],
17
+ 'absolute/no-chained-type-assertions': 'error',
18
+ 'absolute/no-unsafe-schema-types': 'error',
19
+ 'absolute/prefer-drizzle-query-builders': 'error',
20
+ 'absolute/elysia-composition-boundaries': 'error',
21
+ 'absolute/no-nondeterministic-render': 'error',
22
+ 'absolute/button-icon-is-hidden': 'error',
23
+ 'absolute/icon-button-has-accessible-name': 'error',
24
+ 'absolute/loading-indicator-has-aria-busy': 'error',
25
+ 'absolute/progressbar-has-state': 'error',
26
+ },
27
+ },
28
+ {
29
+ files: ['src/backend/**/*.{ts,tsx}'],
30
+ rules: { 'absolute/elysia-no-response-return': 'error' },
31
+ },
32
+ {
33
+ files: ['src/frontend/**/*.{ts,tsx,js,jsx}'],
34
+ rules: {
35
+ 'no-restricted-syntax': ['error',
36
+ { selector: "CallExpression[callee.name='fetch']", message: 'Use a directly typed Eden subapp client.' },
37
+ { selector: "CallExpression[callee.property.name='fetch']", message: 'Use a directly typed Eden subapp client.' },
38
+ ],
39
+ ${frontends.includes('react') ? "'absolute/eden-requires-react-query': 'error'," : ''}
40
+ },
41
+ },
42
+ { files: ['**/*.{html,vue,svelte,gjs,gts}'], plugins: { absolute }, processor: 'absolute/template-source' },
43
+ ${frontends.includes('react')
44
+ ? `{
45
+ files: ['src/frontend/**/*.{ts,tsx,js,jsx}'],
46
+ plugins: { 'react-hooks': reactHooks },
47
+ rules: { 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'error' },
48
+ },`
49
+ : ''}
259
50
  ]);
260
51
  `;
261
- };
@@ -67,11 +67,12 @@ export const generateServerFile = ({ tailwind, authOption, plugins, buildDirecto
67
67
  ? `const authPlugin = auth(absoluteAuthConfig(${hasDatabase ? 'db' : ''}))\n`
68
68
  : '';
69
69
  const content = `${importsBlock}
70
+ import { api } from './api'
70
71
 
71
72
  ${manifestBlock}
72
73
  ${dbBlock ? `${dbBlock}\n` : ''}${authBlock}
73
- const server = new Elysia()
74
- .use(absolutejs)
74
+ export const server = new Elysia()
75
+ .use([absolutejs, api])
75
76
  ${useBlock}${authOption === 'abs' ? `\n${guardBlock}` : ''}
76
77
  ${routesBlock}
77
78
  .use(networking)
@@ -79,7 +80,7 @@ ${useBlock}${authOption === 'abs' ? `\n${guardBlock}` : ''}
79
80
  console.error(\`Server error on \${request.method} \${request.url}\`, error)
80
81
  })
81
82
 
82
- export type Server = typeof server
83
83
  `;
84
+ writeFileSync(join(backendDirectory, 'api.ts'), "import { Elysia } from 'elysia'\n\n// Add typed JSON subapps here; keep page rendering and lifecycle in server.ts.\nexport const api = new Elysia({ name: 'application-api' })\nexport type Api = typeof api\n");
84
85
  writeFileSync(serverFilePath, content);
85
86
  };
package/dist/index.js CHANGED
File without changes
package/dist/scaffold.js CHANGED
@@ -91,14 +91,14 @@ export const scaffold = async ({ response: { agentic, projectName, codeQualityTo
91
91
  const utilsDirectory = join(frontendDirectory, 'utils');
92
92
  mkdirSync(utilsDirectory, { recursive: true });
93
93
  writeFileSync(join(utilsDirectory, 'edenTreaty.ts'), `import { treaty } from '@elysia/eden'
94
- import type { Server } from '../../backend/server'
94
+ import type { Api } from '../../backend/api'
95
95
 
96
96
  const serverUrl =
97
97
  typeof window !== 'undefined'
98
98
  ? window.location.origin
99
99
  : 'http://localhost:3000'
100
100
 
101
- export const server = treaty<Server>(serverUrl)
101
+ export const server = treaty<Api>(serverUrl)
102
102
  `);
103
103
  if (installDependenciesNow) {
104
104
  await installDependencies(packageManager, projectName);
@@ -1,243 +1,47 @@
1
- // eslint.config.mjs
2
- import { dirname } from 'path';
3
- import { fileURLToPath } from 'url';
4
- import { fixupPluginRules } from '@eslint/compat';
5
- import pluginJs from '@eslint/js';
6
- import stylistic from '@stylistic/eslint-plugin';
7
- import tsParser from '@typescript-eslint/parser';
1
+
8
2
  import { defineConfig } from 'eslint/config';
9
- import absolutePlugin from 'eslint-plugin-absolute';
10
- import importPlugin from 'eslint-plugin-import';
11
- import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
12
- import promisePlugin from 'eslint-plugin-promise';
13
- import reactPlugin from 'eslint-plugin-react';
14
- import reactCompilerPlugin from 'eslint-plugin-react-compiler';
15
- import reactHooksPlugin from 'eslint-plugin-react-hooks';
16
- import securityPlugin from 'eslint-plugin-security';
17
- import globals from 'globals';
18
3
  import tseslint from 'typescript-eslint';
19
-
20
- const __dirname = dirname(fileURLToPath(import.meta.url));
4
+ import absolute from 'eslint-plugin-absolute';
5
+ import reactHooks from 'eslint-plugin-react-hooks';
21
6
 
22
7
  export default defineConfig([
23
- pluginJs.configs.recommended,
24
-
25
- ...tseslint.configs.recommended,
26
-
27
- {
28
- files: ['**/*.{ts,tsx}'],
29
- languageOptions: {
30
- globals: globals.browser,
31
- parser: tsParser,
32
- parserOptions: {
33
- createDefaultProgram: true,
34
- project: './tsconfig.json',
35
- tsconfigRootDir: __dirname
36
- }
37
- }
38
- },
39
-
40
- {
41
- files: ['**/*.{ts,tsx}'],
42
- plugins: { '@stylistic': stylistic },
43
- rules: {
44
- '@stylistic/padding-line-between-statements': [
45
- 'error',
46
- { blankLine: 'always', next: 'return', prev: '*' }
47
- ]
48
- }
49
- },
50
-
51
- {
52
- files: ['**/*.{js,mjs,cjs,ts,tsx,jsx}'],
53
- ignores: ['example/build/**'],
54
- plugins: {
55
- absolute: fixupPluginRules(absolutePlugin),
56
- import: fixupPluginRules(importPlugin),
57
- promise: fixupPluginRules(promisePlugin),
58
- security: fixupPluginRules(securityPlugin)
59
- },
60
- rules: {
61
- 'absolute/explicit-object-types': 'error',
62
- 'absolute/localize-react-props': 'error',
63
- 'absolute/max-depth-extended': ['error', 1],
64
- 'absolute/max-jsxnesting': ['error', 5],
65
- 'absolute/min-var-length': [
66
- 'error',
67
- { allowedVars: ['_', 'id', 'db', 'OK'], minLength: 3 }
68
- ],
69
- 'absolute/no-button-navigation': 'error',
70
- 'absolute/no-explicit-return-type': 'error',
71
- 'absolute/no-inline-prop-types': 'error',
72
- 'absolute/no-multi-style-objects': 'error',
73
- 'absolute/no-nested-jsx-return': 'error',
74
- 'absolute/no-or-none-component': 'error',
75
- 'absolute/no-transition-cssproperties': 'error',
76
- 'absolute/no-unnecessary-div': 'error',
77
- 'absolute/no-unnecessary-key': 'error',
78
- 'absolute/no-useless-function': 'error',
79
- 'absolute/seperate-style-files': 'error',
80
- 'absolute/sort-exports': [
81
- 'error',
82
- {
83
- caseSensitive: true,
84
- natural: true,
85
- order: 'asc',
86
- variablesBeforeFunctions: true
87
- }
88
- ],
89
- 'absolute/sort-keys-fixable': [
90
- 'error',
91
- {
92
- caseSensitive: true,
93
- natural: true,
94
- order: 'asc',
95
- variablesBeforeFunctions: true
96
- }
97
- ],
98
- 'arrow-body-style': ['error', 'as-needed'],
99
- 'consistent-return': 'error',
100
- eqeqeq: 'error',
101
- 'func-style': [
102
- 'error',
103
- 'expression',
104
- { allowArrowFunctions: true }
105
- ],
106
- 'import/no-cycle': 'error',
107
- 'import/no-default-export': 'error',
108
- 'import/no-relative-packages': 'error',
109
- 'import/no-unused-modules': ['error', { missingExports: true }],
110
- 'import/order': ['error', { alphabetize: { order: 'asc' } }],
111
- 'no-await-in-loop': 'error',
112
- 'no-console': ['error', { allow: ['warn', 'error'] }],
113
- 'no-debugger': 'error',
114
- 'no-duplicate-case': 'error',
115
- 'no-duplicate-imports': 'error',
116
- 'no-else-return': 'error',
117
- 'no-empty-function': 'error',
118
- 'no-empty-pattern': 'error',
119
- 'no-empty-static-block': 'error',
120
- 'no-fallthrough': 'error',
121
- 'no-floating-decimal': 'error',
122
- 'no-global-assign': 'error',
123
- 'no-implicit-coercion': 'error',
124
- 'no-implicit-globals': 'error',
125
- 'no-loop-func': 'error',
126
- 'no-magic-numbers': [
127
- 'warn',
128
- { detectObjects: false, enforceConst: true, ignore: [0, 1] }
129
- ],
130
- 'no-misleading-character-class': 'error',
131
- 'no-nested-ternary': 'error',
132
- 'no-new-native-nonconstructor': 'error',
133
- 'no-new-wrappers': 'error',
134
- 'no-param-reassign': 'error',
135
- 'no-restricted-imports': [
136
- 'error',
137
- {
138
- paths: [
139
- {
140
- importNames: ['default'],
141
- message:
142
- 'Import only named React exports for tree-shaking.',
143
- name: 'react'
144
- },
145
- {
146
- importNames: ['default'],
147
- message: 'Import only the required Bun exports.',
148
- name: 'bun'
149
- }
150
- ]
151
- }
152
- ],
153
- 'no-return-await': 'error',
154
- 'no-shadow': 'error',
155
- 'no-undef': 'error',
156
- 'no-unneeded-ternary': 'error',
157
- 'no-unreachable': 'error',
158
- 'no-useless-assignment': 'error',
159
- 'no-useless-concat': 'error',
160
- 'no-useless-return': 'error',
161
- 'no-var': 'error',
162
- 'prefer-arrow-callback': 'error',
163
- 'prefer-const': 'error',
164
- 'prefer-destructuring': [
165
- 'error',
166
- { array: true, object: true },
167
- { enforceForRenamedProperties: false }
168
- ],
169
- 'prefer-template': 'error',
170
- 'promise/always-return': 'warn',
171
- 'promise/avoid-new': 'warn',
172
- 'promise/catch-or-return': 'error',
173
- 'promise/no-callback-in-promise': 'warn',
174
- 'promise/no-nesting': 'warn',
175
- 'promise/no-promise-in-callback': 'warn',
176
- 'promise/no-return-wrap': 'error',
177
- 'promise/param-names': 'error'
178
- }
179
- },
180
- {
181
- files: ['example/**/*.{js,jsx,ts,tsx}'],
182
- plugins: {
183
- 'jsx-a11y': fixupPluginRules(jsxA11yPlugin),
184
- react: fixupPluginRules(reactPlugin),
185
- 'react-compiler': reactCompilerPlugin,
186
- 'react-hooks': reactHooksPlugin
187
- },
188
- rules: {
189
- 'jsx-a11y/prefer-tag-over-role': 'error',
190
- 'react-compiler/react-compiler': 'error',
191
- 'react-hooks/exhaustive-deps': 'warn',
192
- 'react-hooks/rules-of-hooks': 'error',
193
- 'react/checked-requires-onchange-or-readonly': 'error',
194
- 'react/destructuring-assignment': ['error', 'always'],
195
- 'react/jsx-filename-extension': ['error', { extensions: ['.tsx'] }],
196
- 'react/jsx-no-leaked-render': 'error',
197
- 'react/jsx-no-target-blank': 'error',
198
- 'react/jsx-no-useless-fragment': 'error',
199
- 'react/jsx-pascal-case': ['error', { allowAllCaps: true }],
200
- 'react/no-multi-comp': 'error',
201
- 'react/no-unknown-property': 'off',
202
- 'react/react-in-jsx-scope': 'off',
203
- 'react/self-closing-comp': 'error'
204
- },
205
- settings: {
206
- react: { version: 'detect' }
207
- }
208
- },
209
- {
210
- files: [
211
- 'example/server.ts',
212
- 'example/indexes/*.tsx',
213
- 'example/db/migrate.ts'
214
- ],
215
- rules: {
216
- 'import/no-unused-modules': 'off'
217
- }
218
- },
219
- {
220
- files: ['example/db/migrate.ts', 'example/utils/absoluteAuthConfig.ts'],
221
- rules: {
222
- 'no-console': 'off'
223
- }
224
- },
225
- {
226
- files: ['eslint.config.mjs'],
227
- rules: {
228
- 'no-magic-numbers': 'off'
229
- }
230
- },
231
- {
232
- files: ['eslint.config.mjs'],
233
- rules: {
234
- 'import/no-default-export': 'off'
235
- }
236
- },
237
- {
238
- files: ['example/db/schema.ts'],
239
- rules: {
240
- 'absolute/explicit-object-types': 'off'
241
- }
242
- }
8
+ { ignores: ['node_modules/**', 'build/**', 'dist/**', '.absolutejs/**', '.data/**', '**/.absolutejs-hmr-*', 'drizzle/**'] },
9
+ { linterOptions: { noInlineConfig: true, reportUnusedDisableDirectives: 'error' } },
10
+ ...tseslint.configs.recommended,
11
+ {
12
+ files: ['**/*.{ts,tsx,js,jsx,mjs}'],
13
+ plugins: { absolute },
14
+ rules: {
15
+ '@typescript-eslint/ban-ts-comment': ['error', { 'ts-check': true, 'ts-expect-error': true, 'ts-ignore': true, 'ts-nocheck': true }],
16
+ 'absolute/no-chained-type-assertions': 'error',
17
+ 'absolute/no-unsafe-schema-types': 'error',
18
+ 'absolute/prefer-drizzle-query-builders': 'error',
19
+ 'absolute/elysia-composition-boundaries': 'error',
20
+ 'absolute/no-nondeterministic-render': 'error',
21
+ 'absolute/button-icon-is-hidden': 'error',
22
+ 'absolute/icon-button-has-accessible-name': 'error',
23
+ 'absolute/loading-indicator-has-aria-busy': 'error',
24
+ 'absolute/progressbar-has-state': 'error',
25
+ },
26
+ },
27
+ {
28
+ files: ['src/backend/**/*.{ts,tsx}'],
29
+ rules: { 'absolute/elysia-no-response-return': 'error' },
30
+ },
31
+ {
32
+ files: ['src/frontend/**/*.{ts,tsx,js,jsx}'],
33
+ rules: {
34
+ 'no-restricted-syntax': ['error',
35
+ { selector: "CallExpression[callee.name='fetch']", message: 'Use a directly typed Eden subapp client.' },
36
+ { selector: "CallExpression[callee.property.name='fetch']", message: 'Use a directly typed Eden subapp client.' },
37
+ ],
38
+ 'absolute/eden-requires-react-query': 'error',
39
+ },
40
+ },
41
+ { files: ['**/*.{html,vue,svelte,gjs,gts}'], plugins: { absolute }, processor: 'absolute/template-source' },
42
+ {
43
+ files: ['src/frontend/**/*.{ts,tsx,js,jsx}'],
44
+ plugins: { 'react-hooks': reactHooks },
45
+ rules: { 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'error' },
46
+ },
243
47
  ]);
@@ -55,7 +55,7 @@ export declare const versions: {
55
55
  readonly 'elysia-rate-limit': "4.5.0";
56
56
  readonly '@absolutejs/scoped-state': "0.2.0";
57
57
  readonly eslint: "9.39.2";
58
- readonly 'eslint-plugin-absolute': "0.11.13";
58
+ readonly 'eslint-plugin-absolute': "0.12.0";
59
59
  readonly 'eslint-plugin-import': "2.32.0";
60
60
  readonly 'eslint-plugin-jsx-a11y': "6.10.2";
61
61
  readonly 'eslint-plugin-promise': "7.2.1";
package/dist/versions.js CHANGED
@@ -65,7 +65,7 @@ export const versions = {
65
65
  'elysia-rate-limit': '4.5.0',
66
66
  '@absolutejs/scoped-state': '0.2.0',
67
67
  eslint: '9.39.2',
68
- 'eslint-plugin-absolute': '0.11.13',
68
+ 'eslint-plugin-absolute': '0.12.0',
69
69
  'eslint-plugin-import': '2.32.0',
70
70
  /* ── ESLint React ─────────────────────────────────────── */
71
71
  'eslint-plugin-jsx-a11y': '6.10.2',
package/package.json CHANGED
@@ -20,7 +20,7 @@
20
20
  "drizzle-kit": "1.0.0-rc.4",
21
21
  "drizzle-orm": "1.0.0-rc.4",
22
22
  "eslint": "10.0.1",
23
- "eslint-plugin-absolute": "0.11.13",
23
+ "eslint-plugin-absolute": "0.12.0",
24
24
  "eslint-plugin-import": "2.32.0",
25
25
  "eslint-plugin-promise": "7.2.1",
26
26
  "eslint-plugin-security": "4.0.0",
@@ -58,5 +58,5 @@
58
58
  "prepublishOnly": "bun run check:package"
59
59
  },
60
60
  "type": "module",
61
- "version": "0.17.2"
61
+ "version": "0.17.3"
62
62
  }