@archpublicwebsite/eslint-config 1.0.19 → 1.0.21
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/commitlint.config.cjs +31 -0
- package/eslint.config.mjs +30 -12
- package/lint-staged.config.mjs +11 -0
- package/package.json +7 -1
- package/prettier.config.mjs +11 -0
- package/tools/security/patterns.mjs +2 -2
- package/tools/setup/install.mjs +52 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
rules: {
|
|
3
|
+
'type-enum': [
|
|
4
|
+
2,
|
|
5
|
+
'always',
|
|
6
|
+
[
|
|
7
|
+
'feat',
|
|
8
|
+
'fix',
|
|
9
|
+
'docs',
|
|
10
|
+
'refactor',
|
|
11
|
+
'perf',
|
|
12
|
+
'test',
|
|
13
|
+
'build',
|
|
14
|
+
'ci',
|
|
15
|
+
'chore',
|
|
16
|
+
'style',
|
|
17
|
+
'types',
|
|
18
|
+
'workflow',
|
|
19
|
+
'release',
|
|
20
|
+
'deps',
|
|
21
|
+
'revert',
|
|
22
|
+
],
|
|
23
|
+
],
|
|
24
|
+
'type-case': [2, 'always', 'lower-case'],
|
|
25
|
+
'type-empty': [2, 'never'],
|
|
26
|
+
'scope-case': [2, 'always', ['lower-case', 'kebab-case']],
|
|
27
|
+
'subject-empty': [2, 'never'],
|
|
28
|
+
'subject-case': [0],
|
|
29
|
+
'header-max-length': [2, 'always', 100],
|
|
30
|
+
},
|
|
31
|
+
}
|
package/eslint.config.mjs
CHANGED
|
@@ -29,8 +29,12 @@ export function createArchipelagoConfig(...overrides) {
|
|
|
29
29
|
'**/coverage/**',
|
|
30
30
|
'**/.next/**',
|
|
31
31
|
'**/public/**',
|
|
32
|
+
'**/*.md',
|
|
32
33
|
'**/*.d.ts',
|
|
33
34
|
],
|
|
35
|
+
linterOptions: {
|
|
36
|
+
reportUnusedDisableDirectives: 'off',
|
|
37
|
+
},
|
|
34
38
|
},
|
|
35
39
|
|
|
36
40
|
// ── Tailwind ──────────────────────────────────────────────────────────────
|
|
@@ -198,6 +202,28 @@ export function createArchipelagoConfig(...overrides) {
|
|
|
198
202
|
'antfu/if-newline': 'off',
|
|
199
203
|
'antfu/no-import-dist': 'off',
|
|
200
204
|
|
|
205
|
+
// ── Compatibility mode for existing codebases ─────────────────────
|
|
206
|
+
// Keep the security-sensitive rules as errors, but avoid blocking
|
|
207
|
+
// commits on purely stylistic differences in current components/tools.
|
|
208
|
+
'style/semi': 'off',
|
|
209
|
+
'style/quotes': 'off',
|
|
210
|
+
'style/quote-props': 'off',
|
|
211
|
+
'style/no-multi-spaces': 'off',
|
|
212
|
+
'style/key-spacing': 'off',
|
|
213
|
+
'style/member-delimiter-style': 'off',
|
|
214
|
+
'style/max-statements-per-line': 'off',
|
|
215
|
+
'style/brace-style': 'off',
|
|
216
|
+
'jsdoc/require-returns-description': 'off',
|
|
217
|
+
'regexp/use-ignore-case': 'off',
|
|
218
|
+
'regexp/prefer-w': 'off',
|
|
219
|
+
'unicorn/escape-case': 'off',
|
|
220
|
+
|
|
221
|
+
// Allow progressive tightening later; for now do not block on these.
|
|
222
|
+
'no-unused-vars': 'off',
|
|
223
|
+
'unused-imports/no-unused-imports': 'off',
|
|
224
|
+
'unused-imports/no-unused-vars': 'off',
|
|
225
|
+
'ts/no-unused-vars': 'off',
|
|
226
|
+
|
|
201
227
|
// ── Vue ──────────────────────────────────────────────────────────────
|
|
202
228
|
'vue/multi-word-component-names': 'off',
|
|
203
229
|
'vue/no-required-prop-with-default': 'off',
|
|
@@ -212,26 +238,18 @@ export function createArchipelagoConfig(...overrides) {
|
|
|
212
238
|
'vue/prefer-separate-static-class': 'off',
|
|
213
239
|
'vue/attribute-hyphenation': 'off',
|
|
214
240
|
'vue/define-macros-order': 'off',
|
|
241
|
+
'vue/no-v-html': 'off',
|
|
215
242
|
'vue/max-attributes-per-line': ['error', {
|
|
216
243
|
singleline: 3,
|
|
217
244
|
multiline: 1,
|
|
218
245
|
}],
|
|
219
|
-
'vue/max-len':
|
|
220
|
-
code: 120,
|
|
221
|
-
ignoreComments: true,
|
|
222
|
-
ignoreUrls: true,
|
|
223
|
-
ignoreStrings: true,
|
|
224
|
-
ignoreTemplateLiterals: true,
|
|
225
|
-
ignoreRegExpLiterals: true,
|
|
226
|
-
ignoreHTMLAttributeValues: true,
|
|
227
|
-
ignoreHTMLTextContents: true,
|
|
228
|
-
}],
|
|
246
|
+
'vue/max-len': 'off',
|
|
229
247
|
|
|
230
248
|
// ── TypeScript ───────────────────────────────────────────────────────
|
|
231
249
|
'ts/no-use-before-define': 'off',
|
|
232
250
|
'ts/no-empty-object-type': 'off',
|
|
233
|
-
'ts/no-explicit-any': '
|
|
234
|
-
'ts/no-var-requires': '
|
|
251
|
+
'ts/no-explicit-any': 'off',
|
|
252
|
+
'ts/no-var-requires': 'off',
|
|
235
253
|
// Keep disabled globally to avoid parserServices errors on plain JS
|
|
236
254
|
// config files (tailwind/postcss/vite) during lint-staged runs.
|
|
237
255
|
'ts/consistent-type-imports': 'off',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@archpublicwebsite/eslint-config",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"author": "Archipelago Hotels",
|
|
5
5
|
"description": "Reusable ESLint flat config and git-hook toolkit for Archipelago projects",
|
|
6
6
|
"type": "module",
|
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
"import": "./eslint.config.mjs",
|
|
12
12
|
"default": "./eslint.config.mjs"
|
|
13
13
|
},
|
|
14
|
+
"./prettier": "./prettier.config.mjs",
|
|
15
|
+
"./commitlint": "./commitlint.config.cjs",
|
|
16
|
+
"./lint-staged": "./lint-staged.config.mjs",
|
|
14
17
|
"./tools/*": "./tools/*"
|
|
15
18
|
},
|
|
16
19
|
"repository": {
|
|
@@ -20,6 +23,9 @@
|
|
|
20
23
|
},
|
|
21
24
|
"files": [
|
|
22
25
|
"eslint.config.mjs",
|
|
26
|
+
"prettier.config.mjs",
|
|
27
|
+
"commitlint.config.cjs",
|
|
28
|
+
"lint-staged.config.mjs",
|
|
23
29
|
"tools",
|
|
24
30
|
"README.md"
|
|
25
31
|
],
|
|
@@ -233,8 +233,8 @@ export const FILE_PATTERNS = [
|
|
|
233
233
|
},
|
|
234
234
|
{
|
|
235
235
|
id: 'vue-v-html',
|
|
236
|
-
severity: '
|
|
237
|
-
message: 'v-html directive —
|
|
236
|
+
severity: 'medium',
|
|
237
|
+
message: 'v-html directive detected — ensure content is sanitised (e.g. DOMPurify) and never bind unsanitised user input',
|
|
238
238
|
// Matches both :v-html and v-html= in .vue template strings captured in JS
|
|
239
239
|
regex: /v-html\s*=/,
|
|
240
240
|
category: 'xss',
|
package/tools/setup/install.mjs
CHANGED
|
@@ -104,6 +104,15 @@ export default createArchipelagoConfig({
|
|
|
104
104
|
// ─── .prettierrc ────────────────────────────────────────────────────────────
|
|
105
105
|
|
|
106
106
|
function ensurePrettierConfig(projectRoot) {
|
|
107
|
+
const prettierModuleConfigPath = join(projectRoot, 'prettier.config.mjs')
|
|
108
|
+
const prettierModuleConfigContent = `import config from '@archpublicwebsite/eslint-config/prettier'
|
|
109
|
+
|
|
110
|
+
export default config
|
|
111
|
+
`
|
|
112
|
+
|
|
113
|
+
if (writeIfMissing(prettierModuleConfigPath, prettierModuleConfigContent))
|
|
114
|
+
log('Created prettier.config.mjs')
|
|
115
|
+
|
|
107
116
|
const prettierPath = join(projectRoot, '.prettierrc')
|
|
108
117
|
const defaults = {
|
|
109
118
|
plugins: ['prettier-plugin-tailwindcss'],
|
|
@@ -138,6 +147,41 @@ function ensurePrettierConfig(projectRoot) {
|
|
|
138
147
|
}
|
|
139
148
|
}
|
|
140
149
|
|
|
150
|
+
function ensureCommitlintConfig(projectRoot) {
|
|
151
|
+
const commitlintConfigPath = join(projectRoot, 'commitlint.config.cjs')
|
|
152
|
+
const content = `module.exports = require('@archpublicwebsite/eslint-config/commitlint')
|
|
153
|
+
`
|
|
154
|
+
if (writeIfMissing(commitlintConfigPath, content))
|
|
155
|
+
log('Created commitlint.config.cjs')
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function ensureLintStagedConfig(projectRoot) {
|
|
159
|
+
const lintStagedConfigPath = join(projectRoot, 'lint-staged.config.mjs')
|
|
160
|
+
const content = `import config from '@archpublicwebsite/eslint-config/lint-staged'
|
|
161
|
+
|
|
162
|
+
export default config
|
|
163
|
+
`
|
|
164
|
+
if (writeIfMissing(lintStagedConfigPath, content))
|
|
165
|
+
log('Created lint-staged.config.mjs')
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function ensurePrettierIgnore(projectRoot) {
|
|
169
|
+
const prettierIgnorePath = join(projectRoot, '.prettierignore')
|
|
170
|
+
const content = `node_modules
|
|
171
|
+
dist
|
|
172
|
+
coverage
|
|
173
|
+
.nuxt
|
|
174
|
+
.output
|
|
175
|
+
.next
|
|
176
|
+
.turbo
|
|
177
|
+
pnpm-lock.yaml
|
|
178
|
+
package-lock.json
|
|
179
|
+
yarn.lock
|
|
180
|
+
`
|
|
181
|
+
if (writeIfMissing(prettierIgnorePath, content))
|
|
182
|
+
log('Created .prettierignore')
|
|
183
|
+
}
|
|
184
|
+
|
|
141
185
|
// ─── .hooks ─────────────────────────────────────────────────────────────────
|
|
142
186
|
|
|
143
187
|
function ensureHooks(projectRoot) {
|
|
@@ -247,6 +291,11 @@ function ensurePackageScripts(projectRoot) {
|
|
|
247
291
|
|
|
248
292
|
const scripts = pkg.scripts && typeof pkg.scripts === 'object' ? pkg.scripts : {}
|
|
249
293
|
const desiredScripts = {
|
|
294
|
+
lint: 'eslint .',
|
|
295
|
+
'lint:fix': 'eslint . --fix',
|
|
296
|
+
format: 'prettier . --write',
|
|
297
|
+
typecheck: 'tsc --noEmit',
|
|
298
|
+
'lint-staged': 'lint-staged',
|
|
250
299
|
precommit: 'node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/pre-commit.mjs',
|
|
251
300
|
prepush: 'node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/pre-push.mjs',
|
|
252
301
|
'security:global-scan': 'bash ./node_modules/@archpublicwebsite/eslint-config/tools/security/scan-global.sh',
|
|
@@ -316,6 +365,9 @@ function main() {
|
|
|
316
365
|
ensureEslintUserIgnore(projectRoot)
|
|
317
366
|
ensureEslintConfig(projectRoot)
|
|
318
367
|
ensurePrettierConfig(projectRoot)
|
|
368
|
+
ensurePrettierIgnore(projectRoot)
|
|
369
|
+
ensureCommitlintConfig(projectRoot)
|
|
370
|
+
ensureLintStagedConfig(projectRoot)
|
|
319
371
|
ensureHooks(projectRoot)
|
|
320
372
|
ensureHooksPath(projectRoot)
|
|
321
373
|
ensureSecurityScripts(projectRoot)
|