Skip to content

Commit 81a6e42

Browse files
committed
Initial commit
0 parents  commit 81a6e42

File tree

199 files changed

+34627
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

199 files changed

+34627
-0
lines changed

.config/eslint.config.mjs

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
import { createRequire } from 'node:module'
2+
import path from 'node:path'
3+
import { fileURLToPath } from 'node:url'
4+
5+
import {
6+
convertIgnorePatternToMinimatch,
7+
includeIgnoreFile,
8+
} from '@eslint/compat'
9+
import jsPlugin from '@eslint/js'
10+
import { flatConfigs as origImportXFlatConfigs } from 'eslint-plugin-import-x'
11+
import nodePlugin from 'eslint-plugin-n'
12+
import sortDestructureKeysPlugin from 'eslint-plugin-sort-destructure-keys'
13+
import unicornPlugin from 'eslint-plugin-unicorn'
14+
import globals from 'globals'
15+
16+
const __filename = fileURLToPath(import.meta.url)
17+
const __dirname = path.dirname(__filename)
18+
const require = createRequire(import.meta.url)
19+
20+
// Get maintained Node versions
21+
const getMaintainedNodeVersions = () => ['18', '20', '22', '24']
22+
23+
const rootPath = path.dirname(__dirname)
24+
25+
const nodeGlobalsConfig = Object.fromEntries(
26+
Object.entries(globals.node).map(([k]) => [k, 'readonly']),
27+
)
28+
29+
const biomeConfigPath = path.join(rootPath, 'biome.json')
30+
const biomeConfig = require(biomeConfigPath)
31+
const biomeIgnores = {
32+
name: 'Imported biome.json ignore patterns',
33+
ignores: biomeConfig.files.includes
34+
.filter(p => p.startsWith('!'))
35+
.map(p => convertIgnorePatternToMinimatch(p.slice(1))),
36+
}
37+
38+
const gitignorePath = path.join(rootPath, '.gitignore')
39+
const gitIgnores = {
40+
...includeIgnoreFile(gitignorePath),
41+
name: 'Imported .gitignore ignore patterns',
42+
}
43+
44+
const sharedPlugins = {
45+
...nodePlugin.configs['flat/recommended-script'].plugins,
46+
'sort-destructure-keys': sortDestructureKeysPlugin,
47+
unicorn: unicornPlugin,
48+
}
49+
50+
const sharedRules = {
51+
'n/exports-style': ['error', 'module.exports'],
52+
'n/no-missing-require': ['off'],
53+
'n/no-process-exit': 'error',
54+
'n/no-unpublished-bin': 'error',
55+
'n/no-unsupported-features/es-builtins': 'error',
56+
'n/no-unsupported-features/es-syntax': [
57+
'error',
58+
{
59+
ignores: ['promise-withresolvers'],
60+
version: getMaintainedNodeVersions().current,
61+
},
62+
],
63+
'n/no-unsupported-features/node-builtins': [
64+
'error',
65+
{
66+
ignores: [
67+
'test',
68+
'test.describe',
69+
'ReadableStream',
70+
'events.getMaxListeners',
71+
],
72+
version: '>=24.10.0',
73+
},
74+
],
75+
'n/prefer-node-protocol': 'error',
76+
'unicorn/consistent-function-scoping': 'error',
77+
curly: 'error',
78+
'line-comment-position': ['error', { position: 'above' }],
79+
'no-await-in-loop': 'error',
80+
'no-control-regex': 'off',
81+
'no-empty': ['error', { allowEmptyCatch: true }],
82+
'no-new': 'error',
83+
'no-proto': 'error',
84+
'no-undef': 'error',
85+
'no-unexpected-multiline': 'off',
86+
'no-unused-vars': [
87+
'error',
88+
{
89+
argsIgnorePattern: '^_|^this$',
90+
ignoreRestSiblings: true,
91+
varsIgnorePattern: '^_',
92+
},
93+
],
94+
'no-var': 'error',
95+
'no-warning-comments': ['warn', { terms: ['fixme'] }],
96+
'prefer-const': 'error',
97+
'sort-destructure-keys/sort-destructure-keys': 'error',
98+
'sort-imports': 'off',
99+
}
100+
101+
const sharedRulesForImportX = {
102+
...origImportXFlatConfigs.recommended.rules,
103+
'import-x/extensions': [
104+
'error',
105+
'never',
106+
{
107+
cjs: 'ignorePackages',
108+
js: 'ignorePackages',
109+
json: 'always',
110+
mjs: 'ignorePackages',
111+
},
112+
],
113+
'import-x/no-unresolved': [
114+
'error',
115+
{
116+
// Ignore @socketsecurity subpaths - resolved by runtime loader
117+
ignore: ['^@socketsecurity/'],
118+
},
119+
],
120+
'import-x/order': [
121+
'warn',
122+
{
123+
groups: [
124+
'builtin',
125+
'external',
126+
'internal',
127+
['parent', 'sibling', 'index'],
128+
'type',
129+
],
130+
pathGroups: [
131+
{
132+
pattern: '@socket{registry,security}/**',
133+
group: 'internal',
134+
},
135+
],
136+
pathGroupsExcludedImportTypes: ['type'],
137+
'newlines-between': 'always',
138+
alphabetize: {
139+
order: 'asc',
140+
},
141+
},
142+
],
143+
}
144+
145+
function getImportXFlatConfigs(isEsm) {
146+
return {
147+
recommended: {
148+
...origImportXFlatConfigs.recommended,
149+
languageOptions: {
150+
...origImportXFlatConfigs.recommended.languageOptions,
151+
ecmaVersion: 'latest',
152+
sourceType: isEsm ? 'module' : 'script',
153+
},
154+
rules: {
155+
...sharedRulesForImportX,
156+
'import-x/no-named-as-default-member': 'off',
157+
},
158+
},
159+
typescript: {
160+
...origImportXFlatConfigs.typescript,
161+
plugins: origImportXFlatConfigs.recommended.plugins,
162+
settings: {
163+
...origImportXFlatConfigs.typescript.settings,
164+
},
165+
rules: {
166+
...sharedRulesForImportX,
167+
// TypeScript compilation already ensures that named imports exist in
168+
// the referenced module.
169+
'import-x/named': 'off',
170+
'import-x/no-named-as-default-member': 'off',
171+
'import-x/no-unresolved': 'off',
172+
},
173+
},
174+
}
175+
}
176+
177+
const importFlatConfigsForScript = getImportXFlatConfigs(false)
178+
const importFlatConfigsForModule = getImportXFlatConfigs(true)
179+
180+
export default [
181+
biomeIgnores,
182+
gitIgnores,
183+
{
184+
ignores: [
185+
// Dot folders.
186+
'.*/**',
187+
// Nested directories.
188+
'**/build/**',
189+
'**/coverage/**',
190+
'**/dist/**',
191+
'**/external/**',
192+
'**/node_modules/**',
193+
// Generated files.
194+
'**/*.d.ts',
195+
'**/*.d.ts.map',
196+
'**/*.tsbuildinfo',
197+
],
198+
},
199+
{
200+
files: ['**/*.{cjs,js}'],
201+
...jsPlugin.configs.recommended,
202+
...importFlatConfigsForScript.recommended,
203+
...nodePlugin.configs['flat/recommended-script'],
204+
languageOptions: {
205+
...jsPlugin.configs.recommended.languageOptions,
206+
...importFlatConfigsForModule.recommended.languageOptions,
207+
...nodePlugin.configs['flat/recommended-script'].languageOptions,
208+
globals: {
209+
...jsPlugin.configs.recommended.languageOptions?.globals,
210+
...importFlatConfigsForModule.recommended.languageOptions?.globals,
211+
...nodePlugin.configs['flat/recommended-script'].languageOptions
212+
?.globals,
213+
...nodeGlobalsConfig,
214+
},
215+
},
216+
plugins: {
217+
...jsPlugin.configs.recommended.plugins,
218+
...importFlatConfigsForScript.recommended.plugins,
219+
...sharedPlugins,
220+
},
221+
rules: {
222+
...jsPlugin.configs.recommended.rules,
223+
...importFlatConfigsForScript.recommended.rules,
224+
...nodePlugin.configs['flat/recommended-script'].rules,
225+
...sharedRules,
226+
},
227+
},
228+
{
229+
files: ['**/*.mjs'],
230+
...jsPlugin.configs.recommended,
231+
...importFlatConfigsForModule.recommended,
232+
languageOptions: {
233+
...jsPlugin.configs.recommended.languageOptions,
234+
...importFlatConfigsForModule.recommended.languageOptions,
235+
globals: {
236+
...jsPlugin.configs.recommended.languageOptions?.globals,
237+
...importFlatConfigsForModule.recommended.languageOptions?.globals,
238+
...nodeGlobalsConfig,
239+
},
240+
sourceType: 'module',
241+
},
242+
plugins: {
243+
...jsPlugin.configs.recommended.plugins,
244+
...importFlatConfigsForModule.recommended.plugins,
245+
...sharedPlugins,
246+
},
247+
rules: {
248+
...jsPlugin.configs.recommended.rules,
249+
...importFlatConfigsForModule.recommended.rules,
250+
...sharedRules,
251+
},
252+
},
253+
{
254+
// Relax rules for script files
255+
files: ['**/scripts/**/*.{cjs,mjs}'],
256+
rules: {
257+
'n/no-process-exit': 'off',
258+
'no-await-in-loop': 'off',
259+
},
260+
},
261+
]

.config/taze.config.mts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { defineConfig } from 'taze'
2+
3+
export default defineConfig({
4+
// Exclude these packages (add as needed).
5+
exclude: ['eslint-plugin-unicorn'],
6+
// Interactive mode disabled for automation.
7+
interactive: false,
8+
// Use minimal logging similar to ncu loglevel.
9+
loglevel: 'warn',
10+
// Only update packages that have been stable for 7 days.
11+
maturityPeriod: 7,
12+
// Update mode: 'latest' is similar to ncu's default behavior.
13+
mode: 'latest',
14+
// Write to package.json automatically.
15+
write: true,
16+
})

.git-hooks/commit-msg

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/bin/bash
2+
# Socket Security Commit-msg Hook
3+
# Additional security layer - validates commit even if pre-commit was bypassed.
4+
5+
set -e
6+
7+
# Colors for output.
8+
RED='\033[0;31m'
9+
GREEN='\033[0;32m'
10+
NC='\033[0m'
11+
12+
# Allowed public API key (used in socket-lib).
13+
ALLOWED_PUBLIC_KEY="sktsec_t_--RAN5U4ivauy4w37-6aoKyYPDt5ZbaT5JBVMqiwKo_api"
14+
15+
ERRORS=0
16+
17+
# Get files in this commit (for security checks).
18+
COMMITTED_FILES=$(git diff --cached --name-only --diff-filter=ACM 2>/dev/null || echo "")
19+
20+
# Quick checks for critical issues in committed files.
21+
if [ -n "$COMMITTED_FILES" ]; then
22+
for file in $COMMITTED_FILES; do
23+
if [ -f "$file" ]; then
24+
# Check for Socket API keys (except allowed).
25+
if grep -E 'sktsec_[a-zA-Z0-9_-]+' "$file" 2>/dev/null | grep -v "$ALLOWED_PUBLIC_KEY" | grep -v 'your_api_key_here' | grep -v 'fake-token' | grep -v 'test-token' | grep -v '\.example' | grep -q .; then
26+
printf "${RED}✗ SECURITY: Potential API key detected in commit!${NC}\n"
27+
echo "File: $file"
28+
ERRORS=$((ERRORS + 1))
29+
fi
30+
31+
# Check for .env files.
32+
if echo "$file" | grep -qE '^\.env(\.local)?$'; then
33+
printf "${RED}✗ SECURITY: .env file in commit!${NC}\n"
34+
ERRORS=$((ERRORS + 1))
35+
fi
36+
fi
37+
done
38+
fi
39+
40+
# Auto-strip AI attribution from commit message.
41+
COMMIT_MSG_FILE="$1"
42+
if [ -f "$COMMIT_MSG_FILE" ]; then
43+
# Create a temporary file to store the cleaned message.
44+
TEMP_FILE=$(mktemp)
45+
REMOVED_LINES=0
46+
47+
# Read the commit message line by line and filter out AI attribution.
48+
while IFS= read -r line || [ -n "$line" ]; do
49+
# Check if this line contains AI attribution patterns.
50+
if echo "$line" | grep -qiE "(Generated with|Co-Authored-By: Claude|Co-Authored-By: AI|🤖 Generated|AI generated|Claude Code|@anthropic|Assistant:|Generated by Claude|Machine generated)"; then
51+
REMOVED_LINES=$((REMOVED_LINES + 1))
52+
else
53+
# Line doesn't contain AI attribution, keep it.
54+
printf '%s\n' "$line" >> "$TEMP_FILE"
55+
fi
56+
done < "$COMMIT_MSG_FILE"
57+
58+
# Replace the original commit message with the cleaned version.
59+
if [ $REMOVED_LINES -gt 0 ]; then
60+
mv "$TEMP_FILE" "$COMMIT_MSG_FILE"
61+
printf "${GREEN}✓ Auto-stripped${NC} $REMOVED_LINES AI attribution line(s) from commit message\n"
62+
else
63+
# No lines were removed, just clean up the temp file.
64+
rm -f "$TEMP_FILE"
65+
fi
66+
fi
67+
68+
if [ $ERRORS -gt 0 ]; then
69+
printf "${RED}✗ Commit blocked by security validation${NC}\n"
70+
exit 1
71+
fi
72+
73+
exit 0

0 commit comments

Comments
 (0)