Skip to content

Commit 3a4b7a1

Browse files
committed
Initial commit
0 parents  commit 3a4b7a1

File tree

442 files changed

+67754
-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.

442 files changed

+67754
-0
lines changed

.config/eslint.config.mjs

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

.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 controlled by -w flag in update script (check mode by default).
15+
write: false,
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)