@sablier/devkit 1.6.0 → 1.7.0
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/biome/base.jsonc +30 -7
- package/biome/ui.jsonc +11 -50
- package/just/csv.just +76 -0
- package/just/tsv.just +6 -71
- package/package.json +5 -7
- package/vitest/base.js +32 -0
- package/vitest/index.ts +0 -29
package/biome/base.jsonc
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// which files to lint and format. For example:
|
|
7
7
|
//
|
|
8
8
|
// {
|
|
9
|
-
// "extends": ["@sablier/devkit/biome"],
|
|
9
|
+
// "extends": ["@sablier/devkit/biome/base"],
|
|
10
10
|
// "files": {
|
|
11
11
|
// "includes": ["**/*.{css,js,jsx,json,ts,tsx}", "!node_modules"]
|
|
12
12
|
// }
|
|
@@ -38,23 +38,41 @@
|
|
|
38
38
|
"linter": {
|
|
39
39
|
"enabled": true,
|
|
40
40
|
"rules": {
|
|
41
|
+
"recommended": true,
|
|
42
|
+
"complexity": {
|
|
43
|
+
"noImplicitCoercions": "error", // forbid `!!foo`, allow `Boolean(foo)`
|
|
44
|
+
"noVoid": "off" // void is useful in some cases e.g. `useEffect` callbacks
|
|
45
|
+
},
|
|
41
46
|
"correctness": {
|
|
42
|
-
"noUnusedImports": "off",
|
|
43
|
-
"noUnusedVariables": "error"
|
|
44
|
-
"useExhaustiveDependencies": "error"
|
|
47
|
+
"noUnusedImports": "off", // allow unused imports during development
|
|
48
|
+
"noUnusedVariables": "error"
|
|
45
49
|
},
|
|
46
50
|
"nursery": {
|
|
47
|
-
"noFloatingPromises": "error"
|
|
51
|
+
"noFloatingPromises": "error", // floating promises can lead to bugs
|
|
52
|
+
"noUselessUndefined": "off" // we want explicit undefined return values
|
|
53
|
+
},
|
|
54
|
+
"performance": {
|
|
55
|
+
"noBarrelFile": "off", // barrel exports lead to cleaner imports
|
|
56
|
+
"noDelete": "off", // disabled due to https://github.com/biomejs/biome/issues/4093
|
|
57
|
+
"noNamespaceImport": "off" // namespaces are cool
|
|
48
58
|
},
|
|
49
|
-
"recommended": true,
|
|
50
59
|
"style": {
|
|
60
|
+
"noNamespace": "off", // namespaces are cool
|
|
61
|
+
"useDefaultSwitchClause": "off", // already handled by TypeScript
|
|
62
|
+
"useFilenamingConvention": {
|
|
63
|
+
"level": "error",
|
|
64
|
+
"options": {
|
|
65
|
+
"filenameCases": ["kebab-case", "camelCase", "PascalCase", "export"]
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
// disabled due to https://github.com/biomejs/biome/issues/8450
|
|
51
69
|
"useImportType": {
|
|
52
70
|
"level": "warn",
|
|
53
71
|
"options": {
|
|
54
72
|
"style": "separatedType"
|
|
55
73
|
}
|
|
56
74
|
},
|
|
57
|
-
"useTemplate": "off"
|
|
75
|
+
"useTemplate": "off" // allow string concatenation using `+`
|
|
58
76
|
}
|
|
59
77
|
}
|
|
60
78
|
},
|
|
@@ -70,6 +88,11 @@
|
|
|
70
88
|
"includes": ["**/*.{json,json5,jsonc}"]
|
|
71
89
|
}
|
|
72
90
|
],
|
|
91
|
+
"json": {
|
|
92
|
+
"formatter": {
|
|
93
|
+
"lineWidth": 100
|
|
94
|
+
}
|
|
95
|
+
},
|
|
73
96
|
"vcs": {
|
|
74
97
|
"clientKind": "git",
|
|
75
98
|
"enabled": true,
|
package/biome/ui.jsonc
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// Sablier Devkit UI configuration for Biome v2
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
3
|
+
// Extends base configuration with UI-specific rules for accessibility,
|
|
4
|
+
// Tailwind CSS class sorting, and CSS modules support.
|
|
5
5
|
//
|
|
6
|
-
// IMPORTANT: Consumers must
|
|
7
|
-
//
|
|
6
|
+
// IMPORTANT: Consumers must extend BOTH configs and add their own
|
|
7
|
+
// `files.includes` patterns. For example:
|
|
8
8
|
//
|
|
9
9
|
// {
|
|
10
|
-
// "extends": ["@sablier/devkit/biome/ui"],
|
|
10
|
+
// "extends": ["@sablier/devkit/biome/base", "@sablier/devkit/biome/ui"],
|
|
11
11
|
// "files": {
|
|
12
12
|
// "includes": ["**/*.{css,js,jsx,json,ts,tsx}", "!node_modules"]
|
|
13
13
|
// }
|
|
@@ -18,40 +18,28 @@
|
|
|
18
18
|
"enabled": true,
|
|
19
19
|
"actions": {
|
|
20
20
|
"source": {
|
|
21
|
-
"
|
|
22
|
-
"useSortedKeys": "on"
|
|
21
|
+
"useSortedAttributes": "on"
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
24
|
},
|
|
26
25
|
"css": {
|
|
26
|
+
"formatter": {
|
|
27
|
+
"lineWidth": 100
|
|
28
|
+
},
|
|
27
29
|
"parser": {
|
|
28
30
|
"cssModules": true,
|
|
29
31
|
"tailwindDirectives": true
|
|
30
32
|
}
|
|
31
33
|
},
|
|
32
|
-
"files": {
|
|
33
|
-
"maxSize": 5242880 // 5MB
|
|
34
|
-
},
|
|
35
|
-
"formatter": {
|
|
36
|
-
"enabled": true,
|
|
37
|
-
"formatWithErrors": true,
|
|
38
|
-
"indentStyle": "space",
|
|
39
|
-
"lineWidth": 100
|
|
40
|
-
},
|
|
41
34
|
"linter": {
|
|
42
|
-
"enabled": true,
|
|
43
35
|
"rules": {
|
|
44
36
|
"a11y": {
|
|
45
37
|
"noSvgWithoutTitle": "off",
|
|
46
38
|
"useKeyWithClickEvents": "off"
|
|
47
39
|
},
|
|
48
|
-
"correctness": {
|
|
49
|
-
"noUnusedImports": "off",
|
|
50
|
-
"noUnusedVariables": "error",
|
|
51
|
-
"useExhaustiveDependencies": "error"
|
|
52
|
-
},
|
|
53
40
|
"nursery": {
|
|
54
|
-
|
|
41
|
+
// Sort Tailwind CSS classes alphabetically
|
|
42
|
+
// See https://github.com/biomejs/biome/issues/1274#issuecomment-3490774696
|
|
55
43
|
"useSortedClasses": {
|
|
56
44
|
"fix": "safe",
|
|
57
45
|
"level": "warn",
|
|
@@ -60,34 +48,7 @@
|
|
|
60
48
|
"functions": ["clsx", "cva", "cn", "tv", "tw", "tw.*"]
|
|
61
49
|
}
|
|
62
50
|
}
|
|
63
|
-
},
|
|
64
|
-
"recommended": true,
|
|
65
|
-
"style": {
|
|
66
|
-
"useImportType": {
|
|
67
|
-
"level": "warn",
|
|
68
|
-
"options": {
|
|
69
|
-
"style": "separatedType"
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
"useTemplate": "off"
|
|
73
51
|
}
|
|
74
52
|
}
|
|
75
|
-
},
|
|
76
|
-
"overrides": [
|
|
77
|
-
{
|
|
78
|
-
"assist": {
|
|
79
|
-
"actions": {
|
|
80
|
-
"source": {
|
|
81
|
-
"useSortedKeys": "off"
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
"includes": ["**/*.{json,json5,jsonc}"]
|
|
86
|
-
}
|
|
87
|
-
],
|
|
88
|
-
"vcs": {
|
|
89
|
-
"clientKind": "git",
|
|
90
|
-
"enabled": true,
|
|
91
|
-
"useIgnoreFile": true
|
|
92
53
|
}
|
|
93
54
|
}
|
package/just/csv.just
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import "./settings.just"
|
|
2
|
+
|
|
3
|
+
# ---------------------------------------------------------------------------- #
|
|
4
|
+
# SCRIPTS #
|
|
5
|
+
# ---------------------------------------------------------------------------- #
|
|
6
|
+
|
|
7
|
+
# Check CSV/TSV files using qsv: https://github.com/dathere/qsv
|
|
8
|
+
[group("checks"), script("bash")]
|
|
9
|
+
_csv-check globs="data/*/*.csv" schema="" ignore="*.csv.invalid|*.csv.valid|*validation-errors.csv" ext="CSV":
|
|
10
|
+
if ! command -v qsv >/dev/null 2>&1; then
|
|
11
|
+
echo "✗ qsv CLI not found"
|
|
12
|
+
echo "Install it: https://github.com/dathere/qsv"
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
echo "Validating {{ ext }} files..."
|
|
17
|
+
found=0
|
|
18
|
+
for file in {{ globs }}; do
|
|
19
|
+
# Skip validation artifact files (only if ignore pattern is set)
|
|
20
|
+
{{ if ignore != "" { "case \"$file\" in\n " + ignore + ")\n continue\n ;;\n esac" } else { "" } }}
|
|
21
|
+
|
|
22
|
+
# Skip if no files match the pattern
|
|
23
|
+
[ -e "$file" ] || continue
|
|
24
|
+
|
|
25
|
+
found=$((found + 1))
|
|
26
|
+
schema_arg="{{ schema }}"
|
|
27
|
+
if ! qsv validate "$file" ${schema_arg:+"$schema_arg"} > /dev/null 2>&1; then
|
|
28
|
+
echo "❌ Validation failed for: $file"
|
|
29
|
+
just _csv-show-errors "$file" "{{ ext }}"
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
if [ "$found" -eq 0 ]; then
|
|
35
|
+
echo "ℹ️ No {{ ext }} files found to validate"
|
|
36
|
+
else
|
|
37
|
+
echo "✅ All {{ ext }} files are valid"
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Show validation errors for a CSV/TSV file
|
|
41
|
+
[group("checks"), script("bash")]
|
|
42
|
+
_csv-show-errors file ext="CSV":
|
|
43
|
+
error_file="{{ file }}.validation-errors.tsv"
|
|
44
|
+
|
|
45
|
+
if [ ! -f "$error_file" ]; then
|
|
46
|
+
echo "Error file not found: $error_file"
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Try to count total errors (subtract 1 for header row)
|
|
51
|
+
total_errors=$(qsv count "$error_file" 2>/dev/null || echo "0")
|
|
52
|
+
if [ "$total_errors" != "0" ]; then
|
|
53
|
+
total_errors=$((total_errors - 1))
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
echo ""
|
|
57
|
+
if [ "$total_errors" != "0" ] && [ "$total_errors" -gt 0 ]; then
|
|
58
|
+
echo "First 20 validation errors (${total_errors} total):"
|
|
59
|
+
else
|
|
60
|
+
echo "Validation errors:"
|
|
61
|
+
fi
|
|
62
|
+
echo ""
|
|
63
|
+
|
|
64
|
+
# Try to use qsv table for nice formatting, fall back to basic display
|
|
65
|
+
if qsv slice --start 0 --len 21 "$error_file" 2>/dev/null | qsv table 2>/dev/null; then
|
|
66
|
+
: # Success, output already shown
|
|
67
|
+
else
|
|
68
|
+
head -n 21 "$error_file"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
if [ "$total_errors" != "0" ] && [ "$total_errors" -gt 20 ]; then
|
|
72
|
+
echo ""
|
|
73
|
+
echo "... and $((total_errors - 20)) more errors"
|
|
74
|
+
fi
|
|
75
|
+
echo ""
|
|
76
|
+
echo "Full details: $error_file"
|
package/just/tsv.just
CHANGED
|
@@ -1,80 +1,15 @@
|
|
|
1
|
-
import "./
|
|
1
|
+
import "./csv.just"
|
|
2
2
|
|
|
3
3
|
# ---------------------------------------------------------------------------- #
|
|
4
|
-
#
|
|
4
|
+
# TSV WRAPPERS #
|
|
5
5
|
# ---------------------------------------------------------------------------- #
|
|
6
6
|
|
|
7
7
|
# Check TSV files using qsv: https://github.com/dathere/qsv
|
|
8
|
-
[group("checks")
|
|
8
|
+
[group("checks")]
|
|
9
9
|
_tsv-check globs="data/*/*.tsv" schema="" ignore="*.tsv.invalid|*.tsv.valid|*validation-errors.tsv":
|
|
10
|
-
|
|
11
|
-
echo "✗ qsv CLI not found"
|
|
12
|
-
echo "Install it: https://github.com/dathere/qsv"
|
|
13
|
-
exit 1
|
|
14
|
-
fi
|
|
15
|
-
|
|
16
|
-
echo "Validating TSV files..."
|
|
17
|
-
found=0
|
|
18
|
-
for file in {{ globs }}; do
|
|
19
|
-
# Skip validation artifact files
|
|
20
|
-
case "$file" in
|
|
21
|
-
{{ ignore }})
|
|
22
|
-
continue
|
|
23
|
-
;;
|
|
24
|
-
esac
|
|
25
|
-
|
|
26
|
-
# Skip if no files match the pattern
|
|
27
|
-
[ -e "$file" ] || continue
|
|
28
|
-
|
|
29
|
-
found=$((found + 1))
|
|
30
|
-
schema_arg="{{ schema }}"
|
|
31
|
-
if ! qsv validate "$file" ${schema_arg:+"$schema_arg"} > /dev/null 2>&1; then
|
|
32
|
-
echo "❌ Validation failed for: $file"
|
|
33
|
-
just _tsv-show-errors "$file"
|
|
34
|
-
exit 1
|
|
35
|
-
fi
|
|
36
|
-
done
|
|
37
|
-
|
|
38
|
-
if [ "$found" -eq 0 ]; then
|
|
39
|
-
echo "ℹ️ No TSV files found to validate"
|
|
40
|
-
else
|
|
41
|
-
echo "✅ All TSV files are valid"
|
|
42
|
-
fi
|
|
10
|
+
@just _csv-check "{{ globs }}" "{{ schema }}" "{{ ignore }}" "TSV"
|
|
43
11
|
|
|
44
12
|
# Show validation errors for a TSV file
|
|
45
|
-
[group("checks")
|
|
13
|
+
[group("checks")]
|
|
46
14
|
_tsv-show-errors file:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if [ ! -f "$error_file" ]; then
|
|
50
|
-
echo "Error file not found: $error_file"
|
|
51
|
-
exit 0
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
# Try to count total errors (subtract 1 for header row)
|
|
55
|
-
total_errors=$(qsv count "$error_file" 2>/dev/null || echo "0")
|
|
56
|
-
if [ "$total_errors" != "0" ]; then
|
|
57
|
-
total_errors=$((total_errors - 1))
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
echo ""
|
|
61
|
-
if [ "$total_errors" != "0" ] && [ "$total_errors" -gt 0 ]; then
|
|
62
|
-
echo "First 20 validation errors (${total_errors} total):"
|
|
63
|
-
else
|
|
64
|
-
echo "Validation errors:"
|
|
65
|
-
fi
|
|
66
|
-
echo ""
|
|
67
|
-
|
|
68
|
-
# Try to use qsv table for nice formatting, fall back to basic display
|
|
69
|
-
if qsv slice --start 0 --len 21 "$error_file" 2>/dev/null | qsv table 2>/dev/null; then
|
|
70
|
-
: # Success, output already shown
|
|
71
|
-
else
|
|
72
|
-
head -n 21 "$error_file"
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
if [ "$total_errors" != "0" ] && [ "$total_errors" -gt 20 ]; then
|
|
76
|
-
echo ""
|
|
77
|
-
echo "... and $((total_errors - 20)) more errors"
|
|
78
|
-
fi
|
|
79
|
-
echo ""
|
|
80
|
-
echo "Full details: $error_file"
|
|
15
|
+
@just _csv-show-errors "{{ file }}" "TSV"
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Configuration files and reusable scripts for Sablier repositories",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.7.0",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Sablier Labs Ltd",
|
|
9
9
|
"url": "https://sablier.com"
|
|
@@ -26,15 +26,13 @@
|
|
|
26
26
|
},
|
|
27
27
|
"exports": {
|
|
28
28
|
"./biome": "./biome/base.jsonc",
|
|
29
|
+
"./biome/base": "./biome/base.jsonc",
|
|
29
30
|
"./biome/ui": "./biome/ui.jsonc",
|
|
30
31
|
"./prettier": "./.prettierrc.json",
|
|
31
32
|
"./tsconfig/base": "./tsconfig/base.json",
|
|
32
33
|
"./tsconfig/build": "./tsconfig/build.json",
|
|
33
34
|
"./tsconfig/next": "./tsconfig/next.json",
|
|
34
|
-
"./vitest":
|
|
35
|
-
"import": "./vitest/index.js",
|
|
36
|
-
"types": "./vitest/index.d.ts"
|
|
37
|
-
}
|
|
35
|
+
"./vitest": "./vitest/base.js"
|
|
38
36
|
},
|
|
39
37
|
"engines": {
|
|
40
38
|
"node": ">=20"
|
|
@@ -42,9 +40,9 @@
|
|
|
42
40
|
"files": [
|
|
43
41
|
"biome/",
|
|
44
42
|
"just/",
|
|
45
|
-
".prettierrc.json",
|
|
46
43
|
"tsconfig/",
|
|
47
|
-
"vitest/"
|
|
44
|
+
"vitest/",
|
|
45
|
+
".prettierrc.json"
|
|
48
46
|
],
|
|
49
47
|
"keywords": [
|
|
50
48
|
"biome",
|
package/vitest/base.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { defineConfig, mergeConfig } from "vitest/config";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {Object} DevkitVitestOptions
|
|
5
|
+
* @property {"node" | "jsdom" | "happy-dom"} [environment]
|
|
6
|
+
* @property {string[]} [setupFiles]
|
|
7
|
+
* @property {boolean} [coverage]
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {DevkitVitestOptions} [options]
|
|
12
|
+
*/
|
|
13
|
+
export function defineDevkitConfig(options = {}) {
|
|
14
|
+
const isCI = Boolean(process.env.CI);
|
|
15
|
+
|
|
16
|
+
const baseConfig = {
|
|
17
|
+
test: {
|
|
18
|
+
coverage: options.coverage ? { provider: "v8" } : undefined,
|
|
19
|
+
environment: options.environment ?? "node",
|
|
20
|
+
globals: true,
|
|
21
|
+
reporters: isCI ? ["basic"] : ["verbose"],
|
|
22
|
+
retry: isCI ? 2 : 0,
|
|
23
|
+
setupFiles: options.setupFiles,
|
|
24
|
+
testTimeout: isCI ? 30_000 : 10_000,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
return defineConfig(baseConfig);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Re-export for merging with existing vite configs
|
|
32
|
+
export { mergeConfig };
|
package/vitest/index.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { UserConfig } from "vitest/config";
|
|
2
|
-
import { defineConfig } from "vitest/config";
|
|
3
|
-
|
|
4
|
-
export interface DevkitVitestOptions {
|
|
5
|
-
environment?: "node" | "jsdom" | "happy-dom";
|
|
6
|
-
setupFiles?: string[];
|
|
7
|
-
coverage?: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function defineDevkitConfig(options: DevkitVitestOptions = {}) {
|
|
11
|
-
const isCI = !!process.env.CI;
|
|
12
|
-
|
|
13
|
-
const baseConfig: UserConfig = {
|
|
14
|
-
test: {
|
|
15
|
-
coverage: options.coverage ? { provider: "v8" } : undefined,
|
|
16
|
-
environment: options.environment ?? "node",
|
|
17
|
-
globals: true,
|
|
18
|
-
reporters: isCI ? ["basic"] : ["verbose"],
|
|
19
|
-
retry: isCI ? 2 : 0,
|
|
20
|
-
setupFiles: options.setupFiles,
|
|
21
|
-
testTimeout: isCI ? 30_000 : 10_000,
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
return defineConfig(baseConfig);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Re-export for merging with existing vite configs
|
|
29
|
-
export { mergeConfig } from "vitest/config";
|