@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('Cannot use server-side imports in frontend code');
31
- cliLogger.info('Server imports (@zap-js/server, @zap-js/client/node) should only be used in routes/api/ or routes/ws/');
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
- errors.push(`${filePath}: Illegal server import '${serverImport}' in frontend code`);
39
- break; // Only report once per file
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.2",
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.2",
75
- "@zap-js/darwin-x64": "0.1.2",
76
- "@zap-js/linux-x64": "0.1.2"
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",