@sun-asterisk/sunlint 1.2.2 → 1.3.1

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.
Files changed (124) hide show
  1. package/CHANGELOG.md +107 -1
  2. package/CONTRIBUTING.md +1654 -66
  3. package/README.md +19 -6
  4. package/config/ci-cd.json +54 -0
  5. package/config/development.json +56 -0
  6. package/config/engines/engines-enhanced.json +86 -0
  7. package/config/engines/semantic-config.json +114 -0
  8. package/config/eslint-rule-mapping.json +50 -38
  9. package/config/large-project.json +143 -0
  10. package/config/presets/all.json +0 -1
  11. package/config/release.json +70 -0
  12. package/config/rule-analysis-strategies.js +23 -4
  13. package/config/rules/S027-categories.json +122 -0
  14. package/config/rules/enhanced-rules-registry.json +2564 -0
  15. package/config/rules/rules-registry-generated.json +785 -837
  16. package/config/rules/rules-registry.json +13 -1
  17. package/core/adapters/sunlint-rule-adapter.js +25 -30
  18. package/core/analysis-orchestrator.js +42 -2
  19. package/core/categories.js +52 -0
  20. package/core/category-constants.js +39 -0
  21. package/core/cli-action-handler.js +53 -32
  22. package/core/cli-program.js +11 -3
  23. package/core/config-manager.js +111 -0
  24. package/core/config-merger.js +88 -0
  25. package/core/constants/categories.js +168 -0
  26. package/core/constants/defaults.js +165 -0
  27. package/core/constants/engines.js +185 -0
  28. package/core/constants/index.js +30 -0
  29. package/core/constants/rules.js +215 -0
  30. package/core/enhanced-rules-registry.js +3 -3
  31. package/core/file-targeting-service.js +128 -7
  32. package/core/interfaces/rule-plugin.interface.js +207 -0
  33. package/core/plugin-manager.js +448 -0
  34. package/core/rule-selection-service.js +42 -15
  35. package/core/semantic-engine.js +658 -0
  36. package/core/semantic-rule-base.js +433 -0
  37. package/core/unified-rule-registry.js +484 -0
  38. package/docs/COMMAND-EXAMPLES.md +134 -0
  39. package/docs/CONSTANTS-ARCHITECTURE.md +288 -0
  40. package/docs/LARGE-PROJECT-GUIDE.md +324 -0
  41. package/engines/core/base-engine.js +249 -0
  42. package/engines/engine-factory.js +275 -0
  43. package/engines/eslint-engine.js +171 -19
  44. package/engines/heuristic-engine.js +569 -78
  45. package/integrations/eslint/plugin/index.js +26 -28
  46. package/origin-rules/common-en.md +8 -8
  47. package/package.json +10 -6
  48. package/rules/common/C003_no_vague_abbreviations/analyzer.js +1 -1
  49. package/rules/common/C017_constructor_logic/analyzer.js +254 -17
  50. package/rules/common/C017_constructor_logic/semantic-analyzer.js +340 -0
  51. package/rules/common/C029_catch_block_logging/analyzer.js +17 -5
  52. package/rules/common/C033_separate_service_repository/README.md +78 -0
  53. package/rules/common/C033_separate_service_repository/analyzer.js +160 -0
  54. package/rules/common/C033_separate_service_repository/config.json +50 -0
  55. package/rules/common/C033_separate_service_repository/regex-based-analyzer.js +585 -0
  56. package/rules/common/C033_separate_service_repository/symbol-based-analyzer.js +368 -0
  57. package/rules/common/C035_error_logging_context/STRATEGY.md +99 -0
  58. package/rules/common/C035_error_logging_context/analyzer.js +230 -0
  59. package/rules/common/C035_error_logging_context/config.json +54 -0
  60. package/rules/common/C035_error_logging_context/regex-based-analyzer.js +299 -0
  61. package/rules/common/C035_error_logging_context/symbol-based-analyzer.js +454 -0
  62. package/rules/common/C040_centralized_validation/analyzer.js +165 -0
  63. package/rules/common/C040_centralized_validation/config.json +46 -0
  64. package/rules/common/C040_centralized_validation/regex-based-analyzer.js +243 -0
  65. package/rules/common/C040_centralized_validation/symbol-based-analyzer.js +416 -0
  66. package/rules/common/C047_no_duplicate_retry_logic/c047-semantic-rule.js +278 -0
  67. package/rules/common/C047_no_duplicate_retry_logic/symbol-analyzer-enhanced.js +968 -0
  68. package/rules/common/C047_no_duplicate_retry_logic/symbol-config.json +71 -0
  69. package/rules/common/{C076_single_test_behavior → C072_single_test_behavior}/analyzer.js +6 -6
  70. package/rules/common/C076_explicit_function_types/README.md +30 -0
  71. package/rules/common/C076_explicit_function_types/analyzer.js +172 -0
  72. package/rules/common/C076_explicit_function_types/config.json +15 -0
  73. package/rules/common/C076_explicit_function_types/semantic-analyzer.js +341 -0
  74. package/rules/index.js +8 -0
  75. package/rules/parser/rule-parser.js +13 -2
  76. package/rules/security/S005_no_origin_auth/README.md +226 -0
  77. package/rules/security/S005_no_origin_auth/analyzer.js +184 -0
  78. package/rules/security/S005_no_origin_auth/ast-analyzer.js +406 -0
  79. package/rules/security/S005_no_origin_auth/config.json +85 -0
  80. package/rules/security/S006_no_plaintext_recovery_codes/README.md +139 -0
  81. package/rules/security/S006_no_plaintext_recovery_codes/analyzer.js +306 -0
  82. package/rules/security/S006_no_plaintext_recovery_codes/config.json +48 -0
  83. package/rules/security/S007_no_plaintext_otp/README.md +198 -0
  84. package/rules/security/S007_no_plaintext_otp/analyzer.js +406 -0
  85. package/rules/security/S007_no_plaintext_otp/config.json +79 -0
  86. package/rules/security/S007_no_plaintext_otp/semantic-analyzer.js +609 -0
  87. package/rules/security/S007_no_plaintext_otp/semantic-config.json +195 -0
  88. package/rules/security/S007_no_plaintext_otp/semantic-wrapper.js +280 -0
  89. package/rules/security/S027_no_hardcoded_secrets/analyzer.js +180 -366
  90. package/rules/security/S027_no_hardcoded_secrets/categories.json +153 -0
  91. package/rules/security/S027_no_hardcoded_secrets/categorized-analyzer.js +250 -0
  92. package/scripts/category-manager.js +150 -0
  93. package/scripts/generate-rules-registry.js +88 -0
  94. package/scripts/migrate-rule-registry.js +157 -0
  95. package/scripts/prepare-release.sh +1 -1
  96. package/scripts/validate-system.js +48 -0
  97. package/.sunlint.json +0 -35
  98. package/config/README.md +0 -88
  99. package/config/engines/eslint-rule-mapping.json +0 -74
  100. package/config/schemas/sunlint-schema.json +0 -0
  101. package/config/testing/test-s005-working.ts +0 -22
  102. package/core/multi-rule-runner.js +0 -0
  103. package/docs/ESLINT-INTEGRATION-STRATEGY.md +0 -392
  104. package/docs/FUTURE_PACKAGES.md +0 -83
  105. package/docs/HEURISTIC_VS_AI.md +0 -113
  106. package/docs/PRODUCTION_DEPLOYMENT_ANALYSIS.md +0 -112
  107. package/docs/PRODUCTION_SIZE_IMPACT.md +0 -183
  108. package/docs/RELEASE_GUIDE.md +0 -230
  109. package/docs/STANDARDIZED-CATEGORY-FILTERING.md +0 -156
  110. package/engines/tree-sitter-parser.js +0 -0
  111. package/engines/universal-ast-engine.js +0 -0
  112. package/integrations/eslint/plugin/rules/common/c076-single-behavior-per-test.js +0 -254
  113. package/rules/common/C029_catch_block_logging/analyzer-backup.js +0 -426
  114. package/rules/common/C029_catch_block_logging/analyzer-fixed.js +0 -130
  115. package/rules/common/C029_catch_block_logging/analyzer-multi-tech.js +0 -487
  116. package/rules/common/C029_catch_block_logging/analyzer-simple.js +0 -110
  117. package/rules/common/C029_catch_block_logging/ast-analyzer-backup.js +0 -441
  118. package/rules/common/C029_catch_block_logging/ast-analyzer-new.js +0 -127
  119. package/rules/common/C029_catch_block_logging/ast-analyzer.js +0 -133
  120. package/rules/common/C029_catch_block_logging/cfg-analyzer.js +0 -408
  121. package/rules/common/C029_catch_block_logging/dataflow-analyzer.js +0 -454
  122. package/rules/common/C029_catch_block_logging/multi-language-ast-engine.js +0 -700
  123. package/rules/common/C029_catch_block_logging/pattern-learning-analyzer.js +0 -568
  124. package/rules/common/C029_catch_block_logging/semantic-analyzer.js +0 -459
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Rule Registry Migration Script
5
+ * Merges all rule mappings into Unified Rule Registry
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ console.log('🔄 RULE REGISTRY MIGRATION');
12
+ console.log('='.repeat(50));
13
+
14
+ // Load existing data
15
+ const rulesRegistry = JSON.parse(fs.readFileSync('./config/rules/rules-registry.json', 'utf8'));
16
+ const eslintMapping = JSON.parse(fs.readFileSync('./config/eslint-rule-mapping.json', 'utf8'));
17
+ const engineMapping = JSON.parse(fs.readFileSync('./config/engines/eslint-rule-mapping.json', 'utf8'));
18
+ const strategies = require('./config/rule-analysis-strategies.js');
19
+
20
+ // Current unified registry
21
+ const { UnifiedRuleRegistry } = require('./core/unified-rule-registry.js');
22
+ const registry = new UnifiedRuleRegistry();
23
+
24
+ async function migrateRuleData() {
25
+ console.log('📥 Loading current unified registry...');
26
+ await registry.initialize({ verbose: true });
27
+
28
+ console.log('🔍 Analyzing missing rules...');
29
+
30
+ // Get all rule IDs from different sources
31
+ const registryRules = Object.keys(rulesRegistry.rules || {});
32
+ const eslintRules = Object.keys(eslintMapping.mappings || {});
33
+ const engineRules = Object.keys(engineMapping || {});
34
+
35
+ // Find missing rules in unified registry
36
+ const missingFromEslint = eslintRules.filter(ruleId =>
37
+ !registryRules.includes(ruleId)
38
+ );
39
+
40
+ console.log(`📊 Found ${missingFromEslint.length} rules missing from registry:`,
41
+ missingFromEslint.slice(0, 10).join(', '));
42
+
43
+ // Extend unified registry with missing rules
44
+ const enhancedRegistry = { ...rulesRegistry };
45
+
46
+ missingFromEslint.forEach(ruleId => {
47
+ console.log(`➕ Adding missing rule: ${ruleId}`);
48
+
49
+ enhancedRegistry.rules[ruleId] = {
50
+ id: ruleId,
51
+ name: `Rule ${ruleId}`, // Will be improved
52
+ description: `Auto-migrated rule ${ruleId} from ESLint mapping`,
53
+ category: inferCategory(ruleId),
54
+ severity: 'warning',
55
+ languages: ['typescript', 'javascript'],
56
+ version: '1.0.0',
57
+ status: 'migrated',
58
+ tags: ['migrated'],
59
+
60
+ // ESLint engine mapping
61
+ engineMappings: {
62
+ eslint: eslintMapping.mappings[ruleId] || []
63
+ },
64
+
65
+ // Analysis strategy
66
+ strategy: {
67
+ preferred: inferStrategy(ruleId),
68
+ fallbacks: ['regex'],
69
+ accuracy: {}
70
+ }
71
+ };
72
+ });
73
+
74
+ // Add missing engine mappings
75
+ console.log('🔧 Adding engine mappings...');
76
+ Object.entries(engineMapping).forEach(([ruleId, eslintRules]) => {
77
+ if (enhancedRegistry.rules[ruleId]) {
78
+ enhancedRegistry.rules[ruleId].engineMappings = enhancedRegistry.rules[ruleId].engineMappings || {};
79
+ enhancedRegistry.rules[ruleId].engineMappings.eslint = eslintRules;
80
+ }
81
+ });
82
+
83
+ // Add analysis strategies
84
+ console.log('📈 Adding analysis strategies...');
85
+ Object.entries(strategies.astPreferred || {}).forEach(([ruleId, config]) => {
86
+ if (enhancedRegistry.rules[ruleId]) {
87
+ enhancedRegistry.rules[ruleId].strategy = {
88
+ preferred: 'ast',
89
+ fallbacks: config.methods || ['regex'],
90
+ accuracy: config.accuracy || {}
91
+ };
92
+ }
93
+ });
94
+
95
+ Object.entries(strategies.regexOptimal || {}).forEach(([ruleId, config]) => {
96
+ if (enhancedRegistry.rules[ruleId]) {
97
+ enhancedRegistry.rules[ruleId].strategy = {
98
+ preferred: 'regex',
99
+ fallbacks: config.methods || [],
100
+ accuracy: config.accuracy || {}
101
+ };
102
+ }
103
+ });
104
+
105
+ console.log('💾 Saving enhanced registry...');
106
+
107
+ // Save enhanced registry
108
+ fs.writeFileSync(
109
+ './config/rules/enhanced-rules-registry.json',
110
+ JSON.stringify(enhancedRegistry, null, 2)
111
+ );
112
+
113
+ console.log(`✅ Enhanced registry saved with ${Object.keys(enhancedRegistry.rules).length} rules`);
114
+
115
+ // Generate migration summary
116
+ const summary = {
117
+ originalRules: registryRules.length,
118
+ migratedRules: missingFromEslint.length,
119
+ totalRules: Object.keys(enhancedRegistry.rules).length,
120
+ eslintMappings: Object.keys(eslintMapping.mappings).length,
121
+ engineMappings: Object.keys(engineMapping).length
122
+ };
123
+
124
+ fs.writeFileSync(
125
+ './migration-summary.json',
126
+ JSON.stringify(summary, null, 2)
127
+ );
128
+
129
+ console.log('📄 Migration summary:', summary);
130
+ }
131
+
132
+ // Helper functions
133
+ function inferCategory(ruleId) {
134
+ if (ruleId.startsWith('S')) return 'security';
135
+ if (ruleId.startsWith('T')) return 'typescript';
136
+ if (ruleId.startsWith('R')) return 'react';
137
+
138
+ // Infer from common patterns
139
+ if (ruleId.includes('naming') || ruleId.includes('name')) return 'naming';
140
+ if (ruleId.includes('error') || ruleId.includes('exception')) return 'error-handling';
141
+ if (ruleId.includes('log')) return 'logging';
142
+ if (ruleId.includes('complexity')) return 'complexity';
143
+
144
+ return 'general';
145
+ }
146
+
147
+ function inferStrategy(ruleId) {
148
+ // Rules that typically need AST analysis
149
+ const astRules = ['C010', 'C012', 'C015', 'C017'];
150
+ if (astRules.includes(ruleId)) return 'ast';
151
+
152
+ // Most rules can start with regex
153
+ return 'regex';
154
+ }
155
+
156
+ // Run migration
157
+ migrateRuleData().catch(console.error);
@@ -135,7 +135,7 @@ sunlint --rule=C006 --input=src --format=summary
135
135
 
136
136
  # TypeScript Analysis
137
137
  --typescript # Enable TypeScript analysis
138
- --typescript-engine <type> # Engine: eslint, sunlint, hybrid
138
+ --typescript-engine <type> # Engine: eslint, heuristic, hybrid
139
139
 
140
140
  # Output Control
141
141
  --format <format> # Output: eslint, json, summary, table
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Quick validation that unified rule registry system is working
5
+ */
6
+
7
+ const { getInstance } = require('./core/unified-rule-registry');
8
+
9
+ async function validateUnifiedSystem() {
10
+ console.log('🔍 Validating unified rule registry system...\n');
11
+
12
+ try {
13
+ const registry = getInstance();
14
+ await registry.initialize();
15
+
16
+ console.log(`✅ Registry loaded: ${registry.rules.size} rules`);
17
+
18
+ // Test specific rules
19
+ const testRules = ['C006', 'C047', 'C002'];
20
+ console.log('\n📋 Testing specific rules:');
21
+
22
+ for (const ruleId of testRules) {
23
+ const rule = registry.rules.get(ruleId);
24
+ if (rule) {
25
+ console.log(` ✅ ${ruleId}: ${rule.title}`);
26
+ if (rule.engineMappings?.eslint) {
27
+ console.log(` ESLint: ${JSON.stringify(rule.engineMappings.eslint)}`);
28
+ }
29
+ if (rule.engineMappings?.heuristic) {
30
+ console.log(` Heuristic: ${rule.engineMappings.heuristic.implementation}`);
31
+ }
32
+ } else {
33
+ console.log(` ❌ ${ruleId}: NOT FOUND`);
34
+ }
35
+ }
36
+
37
+ console.log('\n🎉 Unified rule registry system is working correctly!');
38
+
39
+ } catch (error) {
40
+ console.error('❌ Validation failed:', error.message);
41
+ }
42
+ }
43
+
44
+ if (require.main === module) {
45
+ validateUnifiedSystem();
46
+ }
47
+
48
+ module.exports = { validateUnifiedSystem };
package/.sunlint.json DELETED
@@ -1,35 +0,0 @@
1
- {
2
- "extends": "@sun/sunlint/recommended",
3
- "rules": {
4
- "C019": "warn",
5
- "C006": "warn",
6
- "C029": "error",
7
- "C031": "warn",
8
- "S001": "warn",
9
- "S002": "warn",
10
- "S007": "warn",
11
- "S013": "warn",
12
- "T019": "error",
13
- "T020": "warn",
14
- "T021": "error"
15
- },
16
- "include": ["**/*.js", "**/*.ts", "**/*.jsx", "**/*.tsx"],
17
- "exclude": [
18
- "node_modules/**",
19
- "coverage/**",
20
- "**/*.min.*",
21
- ".git/**",
22
- "dist/**",
23
- "build/**"
24
- ],
25
- "engine": "eslint",
26
- "languages": ["typescript", "javascript"],
27
- "output": {
28
- "format": "summary",
29
- "console": true
30
- },
31
- "fileTargeting": {
32
- "followSymlinks": false,
33
- "maxDepth": 10
34
- }
35
- }
package/config/README.md DELETED
@@ -1,88 +0,0 @@
1
- # SunLint Configuration Structure
2
-
3
- This folder contains all configuration files for SunLint, organized for clarity and maintainability.
4
-
5
- ## 📁 Structure Overview
6
-
7
- ```
8
- config/
9
- ├── schemas/ # JSON schemas for validation
10
- │ └── sunlint-schema.json # Main SunLint config schema
11
- ├── engines/ # Analysis engine configurations
12
- │ ├── engines.json # Available engines (ESLint, TypeScript, etc.)
13
- │ └── eslint-rule-mapping.json # ESLint rule mappings
14
- ├── presets/ # Pre-defined rule configurations
15
- │ ├── beginner.json # Beginner-friendly preset
16
- │ ├── ci.json # CI/CD optimized preset
17
- │ ├── recommended.json # Recommended preset
18
- │ └── strict.json # Strict coding standards
19
- ├── integrations/ # Integration-specific configs
20
- │ └── eslint/
21
- │ ├── base.config.js # Base ESLint configuration
22
- │ ├── typescript.config.js # TypeScript ESLint config
23
- │ └── simple.config.js # Simplified ESLint config
24
- ├── rules/ # Rule definitions and registry
25
- │ └── rules-registry.json # Master rule registry
26
- ├── defaults/ # Default configurations
27
- │ ├── default.json # Default SunLint settings
28
- │ └── ai-rules-context.json # AI analysis context
29
- └── testing/ # Test configurations and samples
30
- └── test-s005-working.ts # Test file for S005 rule
31
- ```
32
-
33
- ## 🎯 Key Improvements
34
-
35
- ### ✅ Eliminated Duplicates
36
- - **Before**: ESLint configs in both `config/typescript/` and `integrations/eslint/`
37
- - **After**: All ESLint configs consolidated in `config/integrations/eslint/`
38
-
39
- ### ✅ Logical Organization
40
- - **Schemas**: All JSON schemas in one place
41
- - **Engines**: Engine-specific configurations separated
42
- - **Presets**: User-facing preset configurations grouped
43
- - **Integrations**: Third-party integration configs organized by tool
44
-
45
- ### ✅ Reduced Complexity
46
- - **Before**: 10+ files scattered in root config/
47
- - **After**: Organized into 6 logical categories
48
-
49
- ## 📋 Usage
50
-
51
- ### For ESLint Integration
52
- ```bash
53
- # Use the consolidated TypeScript ESLint config
54
- npx eslint --config config/integrations/eslint/typescript.config.js src/
55
-
56
- # Use the base ESLint config
57
- npx eslint --config config/integrations/eslint/base.config.js src/
58
- ```
59
-
60
- ### For Rule Presets
61
- ```json
62
- {
63
- "extends": "config/presets/recommended.json"
64
- }
65
- ```
66
-
67
- ### For Schema Validation
68
- ```json
69
- {
70
- "$schema": "config/schemas/sunlint-schema.json"
71
- }
72
- ```
73
-
74
- ## 🔧 Migration Notes
75
-
76
- - **Old `config/typescript/`**: ❌ Removed (duplicated functionality)
77
- - **ESLint configs**: ✅ Moved to `config/integrations/eslint/`
78
- - **Default configs**: ✅ Moved to `config/defaults/`
79
- - **Engine configs**: ✅ Moved to `config/engines/`
80
-
81
- ## 🚀 Next Steps
82
-
83
- 1. Update documentation references to new paths
84
- 2. Update CI/CD scripts to use new config locations
85
- 3. Consider adding more integration-specific configs as needed
86
-
87
- ---
88
- *Last updated: July 21, 2025 | SunLint Config Refactor*
@@ -1,74 +0,0 @@
1
- {
2
- "C005": [
3
- "max-statements-per-line",
4
- "complexity"
5
- ],
6
- "C006": [
7
- "func-names",
8
- "func-name-matching",
9
- "@typescript-eslint/naming-convention"
10
- ],
11
- "C007": [
12
- "spaced-comment",
13
- "no-inline-comments",
14
- "no-warning-comments"
15
- ],
16
- "C012": [
17
- "consistent-return",
18
- "no-void",
19
- "@typescript-eslint/no-confusing-void-expression"
20
- ],
21
- "C014": [
22
- "no-new",
23
- "no-new-wrappers",
24
- "@typescript-eslint/no-unnecessary-constructor"
25
- ],
26
- "C015": [
27
- "@typescript-eslint/naming-convention",
28
- "camelcase"
29
- ],
30
- "C019": [
31
- "no-console",
32
- "no-alert",
33
- "no-debugger"
34
- ],
35
- "C031": [
36
- "no-implicit-coercion",
37
- "eqeqeq",
38
- "@typescript-eslint/strict-boolean-expressions"
39
- ],
40
- "C032": [
41
- "no-new",
42
- "@typescript-eslint/no-floating-promises",
43
- "no-constructor-return"
44
- ],
45
- "C033": [
46
- "prefer-const",
47
- "no-var",
48
- "@typescript-eslint/prefer-readonly"
49
- ],
50
- "C034": [
51
- "no-global-assign",
52
- "no-implicit-globals",
53
- "@typescript-eslint/no-namespace"
54
- ],
55
- "C035": [
56
- "no-empty-catch",
57
- "@typescript-eslint/no-unused-vars"
58
- ],
59
- "C037": [
60
- "consistent-return",
61
- "@typescript-eslint/explicit-function-return-type",
62
- "@typescript-eslint/explicit-module-boundary-types"
63
- ],
64
- "C038": [
65
- "import/no-dynamic-require",
66
- "import/order",
67
- "@typescript-eslint/no-var-requires"
68
- ],
69
- "C040": [
70
- "no-duplicate-imports",
71
- "import/no-duplicates",
72
- "@typescript-eslint/no-duplicate-imports"
73
- ]
74
- }
File without changes
@@ -1,22 +0,0 @@
1
- function doAdminTask() {}
2
- function doAction() {}
3
- function isAuthenticated(req: any): boolean {
4
- return true;
5
- }
6
-
7
- function doPost(request: any, response: any) { // ❌
8
- const origin = request.getHeader("Origin");
9
-
10
- if (origin === "https://admin.example.com") {
11
- doAdminTask();
12
- }
13
- }
14
-
15
- function doPost_safe(request: any, response: any) { // ✅
16
- const origin = request.getHeader("Origin");
17
- console.log("Origin:", origin);
18
-
19
- if (isAuthenticated(request)) {
20
- doAction();
21
- }
22
- }
File without changes