@zap-js/client 0.1.2 → 0.1.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.
|
@@ -27,8 +27,16 @@ export async function buildCommand(options) {
|
|
|
27
27
|
cliLogger.error(error);
|
|
28
28
|
}
|
|
29
29
|
cliLogger.newline();
|
|
30
|
-
cliLogger.error('
|
|
31
|
-
cliLogger.
|
|
30
|
+
cliLogger.error('Server imports found in restricted locations');
|
|
31
|
+
cliLogger.newline();
|
|
32
|
+
cliLogger.info('Allowed locations for server imports:');
|
|
33
|
+
cliLogger.info(' - routes/api/** (server-side routes)');
|
|
34
|
+
cliLogger.info(' - routes/ws/** (WebSocket routes)');
|
|
35
|
+
cliLogger.info(' - src/api/** (API clients)');
|
|
36
|
+
cliLogger.info(' - src/services/** (business logic)');
|
|
37
|
+
cliLogger.info(' - src/generated/** (generated code)');
|
|
38
|
+
cliLogger.newline();
|
|
39
|
+
cliLogger.info('Move server imports to allowed directories or remove them.');
|
|
32
40
|
throw new Error('Build validation failed');
|
|
33
41
|
}
|
|
34
42
|
if (validation.warnings.length > 0) {
|
|
@@ -5,6 +5,11 @@ const SERVER_ONLY_IMPORTS = [
|
|
|
5
5
|
'@zap-js/client/node',
|
|
6
6
|
'@zap-js/client/server',
|
|
7
7
|
];
|
|
8
|
+
// Path classification tiers
|
|
9
|
+
const ALWAYS_ALLOWED = ['/routes/api/', '/routes/ws/'];
|
|
10
|
+
const BUSINESS_LOGIC_ALLOWED = ['/src/api/', '/src/services/', '/src/generated/', '/src/lib/api/'];
|
|
11
|
+
const UI_LAYER_BLOCKED = ['/src/components/', '/src/pages/', '/src/ui/'];
|
|
12
|
+
const ALLOWED_FILE_PATTERNS = [/\/rpc-client\.(ts|js)$/, /\/api-client\.(ts|js)$/];
|
|
8
13
|
/**
|
|
9
14
|
* Validates that frontend code doesn't import server-only packages
|
|
10
15
|
* Returns array of error messages (empty if valid)
|
|
@@ -15,16 +20,28 @@ export function validateNoServerImportsInFrontend(srcDir) {
|
|
|
15
20
|
// Only scan TypeScript/JavaScript files
|
|
16
21
|
if (!filePath.match(/\.(tsx?|jsx?)$/))
|
|
17
22
|
return;
|
|
18
|
-
// Skip API routes (these are server-side)
|
|
19
|
-
if (filePath.includes('/routes/api/'))
|
|
20
|
-
return;
|
|
21
|
-
if (filePath.includes('/routes/ws/'))
|
|
22
|
-
return;
|
|
23
23
|
// Skip node_modules
|
|
24
24
|
if (filePath.includes('node_modules'))
|
|
25
25
|
return;
|
|
26
|
+
// Tier 1: Check server-side paths first (early exit)
|
|
27
|
+
for (const allowed of ALWAYS_ALLOWED) {
|
|
28
|
+
if (filePath.includes(allowed))
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// Tier 2: Check business logic paths
|
|
32
|
+
for (const allowed of BUSINESS_LOGIC_ALLOWED) {
|
|
33
|
+
if (filePath.includes(allowed))
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Tier 3: Check special file patterns
|
|
37
|
+
for (const pattern of ALLOWED_FILE_PATTERNS) {
|
|
38
|
+
if (pattern.test(filePath))
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Now scan file for server imports
|
|
26
42
|
try {
|
|
27
43
|
const content = readFileSync(filePath, 'utf-8');
|
|
44
|
+
let serverImportFound = null;
|
|
28
45
|
for (const serverImport of SERVER_ONLY_IMPORTS) {
|
|
29
46
|
// Check for both single and double quotes
|
|
30
47
|
const patterns = [
|
|
@@ -35,10 +52,29 @@ export function validateNoServerImportsInFrontend(srcDir) {
|
|
|
35
52
|
];
|
|
36
53
|
for (const pattern of patterns) {
|
|
37
54
|
if (content.includes(pattern)) {
|
|
38
|
-
|
|
39
|
-
break;
|
|
55
|
+
serverImportFound = serverImport;
|
|
56
|
+
break;
|
|
40
57
|
}
|
|
41
58
|
}
|
|
59
|
+
if (serverImportFound)
|
|
60
|
+
break; // Only report once per file
|
|
61
|
+
}
|
|
62
|
+
// Tier 4: Classify and report errors
|
|
63
|
+
if (serverImportFound) {
|
|
64
|
+
// Check if in UI layer (explicit block)
|
|
65
|
+
let inUILayer = false;
|
|
66
|
+
for (const blocked of UI_LAYER_BLOCKED) {
|
|
67
|
+
if (filePath.includes(blocked)) {
|
|
68
|
+
inUILayer = true;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (inUILayer) {
|
|
73
|
+
errors.push(`${filePath}: Server import '${serverImportFound}' in UI layer`);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
errors.push(`${filePath}: Server import '${serverImportFound}' in unclassified path`);
|
|
77
|
+
}
|
|
42
78
|
}
|
|
43
79
|
}
|
|
44
80
|
catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zap-js/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "High-performance fullstack React framework - Client package",
|
|
5
5
|
"homepage": "https://github.com/saint0x/zapjs",
|
|
6
6
|
"repository": {
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
"ws": "^8.16.0"
|
|
72
72
|
},
|
|
73
73
|
"optionalDependencies": {
|
|
74
|
-
"@zap-js/darwin-arm64": "0.1.
|
|
75
|
-
"@zap-js/darwin-x64": "0.1.
|
|
76
|
-
"@zap-js/linux-x64": "0.1.
|
|
74
|
+
"@zap-js/darwin-arm64": "0.1.3",
|
|
75
|
+
"@zap-js/darwin-x64": "0.1.3",
|
|
76
|
+
"@zap-js/linux-x64": "0.1.3"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|
|
79
79
|
"react": "^18.0.0",
|