@kabran-tecnologia/kabran-config 1.9.0 → 1.12.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.
@@ -16,6 +16,10 @@
16
16
 
17
17
  import {existsSync, readFileSync} from 'node:fs';
18
18
  import {join} from 'node:path';
19
+ import {loadConfig, DEFAULTS} from '../core/config-loader.mjs';
20
+
21
+ // Default path for backwards compatibility
22
+ export const DEFAULT_STANDARD_PATH = DEFAULTS.quality.standardPath;
19
23
 
20
24
  /**
21
25
  * Required sections that must be present in quality-standard.md
@@ -33,10 +37,11 @@ export const REQUIRED_FRONTMATTER = ['title', 'type', 'status'];
33
37
  /**
34
38
  * Find quality-standard.md file in the project
35
39
  * @param {string} cwd - Current working directory
40
+ * @param {string} [standardPath] - Path to quality standard file (relative to cwd)
36
41
  * @returns {{exists: boolean, path?: string} | null} File info or null
37
42
  */
38
- export function findQualityStandard(cwd = process.cwd()) {
39
- const expectedPath = join(cwd, 'docs', 'quality', '001-quality-standard.md');
43
+ export function findQualityStandard(cwd = process.cwd(), standardPath = DEFAULT_STANDARD_PATH) {
44
+ const expectedPath = join(cwd, standardPath);
40
45
 
41
46
  if (existsSync(expectedPath)) {
42
47
  return {
@@ -183,26 +188,30 @@ export function compareOverrides(documented, code) {
183
188
  * Validate quality-standard.md
184
189
  * @param {string} cwd - Current working directory
185
190
  * @param {boolean} silent - Suppress console output (for testing)
186
- * @returns {{valid: boolean, errors: string[], warnings: string[]}} Validation result
191
+ * @returns {Promise<{valid: boolean, errors: string[], warnings: string[]}>} Validation result
187
192
  */
188
- export function validate(cwd = process.cwd(), silent = false) {
193
+ export async function validate(cwd = process.cwd(), silent = false) {
189
194
  const log = silent ? () => {} : console.log.bind(console);
190
195
  const error = silent ? () => {} : console.error.bind(console);
191
196
 
192
197
  const errors = [];
193
198
  const warnings = [];
194
199
 
200
+ // Load project config
201
+ const config = await loadConfig(cwd);
202
+ const standardPath = config.quality.standardPath;
203
+
195
204
  log('');
196
205
  log('Validating Quality Standard...');
197
206
  log('='.repeat(50));
198
207
 
199
208
  // 1. Check file exists
200
- const fileInfo = findQualityStandard(cwd);
209
+ const fileInfo = findQualityStandard(cwd, standardPath);
201
210
 
202
211
  if (!fileInfo) {
203
- errors.push('Missing required file: docs/quality/001-quality-standard.md');
212
+ errors.push(`Missing required file: ${standardPath}`);
204
213
  error('');
205
- error('ERROR: Missing required file: docs/quality/001-quality-standard.md');
214
+ error(`ERROR: Missing required file: ${standardPath}`);
206
215
  error('');
207
216
  error('Run "npx kabran-setup" to create it, or create manually.');
208
217
  log('='.repeat(50));
@@ -210,7 +219,7 @@ export function validate(cwd = process.cwd(), silent = false) {
210
219
  }
211
220
 
212
221
  log('');
213
- log('File: docs/quality/001-quality-standard.md');
222
+ log(`File: ${standardPath}`);
214
223
  log(' Status: Found');
215
224
 
216
225
  // 2. Read and parse content
@@ -317,10 +326,12 @@ export function validate(cwd = process.cwd(), silent = false) {
317
326
  /**
318
327
  * Get quality standard validation result in ci-result.json format
319
328
  * @param {string} [cwd] - Directory to validate (defaults to process.cwd())
320
- * @returns {Object} Check result for ci-result.json
329
+ * @returns {Promise<Object>} Check result for ci-result.json
321
330
  */
322
- export function getQualityStandardCheckResult(cwd = process.cwd()) {
323
- const fileInfo = findQualityStandard(cwd);
331
+ export async function getQualityStandardCheckResult(cwd = process.cwd()) {
332
+ const config = await loadConfig(cwd);
333
+ const standardPath = config.quality.standardPath;
334
+ const fileInfo = findQualityStandard(cwd, standardPath);
324
335
 
325
336
  if (!fileInfo) {
326
337
  return {
@@ -372,11 +383,11 @@ if (isMainModule) {
372
383
  const cwd = args.find(a => !a.startsWith('--')) || process.cwd();
373
384
 
374
385
  if (jsonOutput) {
375
- const result = getQualityStandardCheckResult(cwd);
386
+ const result = await getQualityStandardCheckResult(cwd);
376
387
  console.log(JSON.stringify(result, null, 2));
377
388
  process.exit(result.status === 'fail' ? 1 : 0);
378
389
  } else {
379
- const result = validate(cwd);
390
+ const result = await validate(cwd);
380
391
  process.exit(result.valid ? 0 : 1);
381
392
  }
382
393
  } catch (err) {
@@ -16,21 +16,27 @@
16
16
 
17
17
  import fs from 'node:fs';
18
18
  import path from 'node:path';
19
+ import {loadConfig, DEFAULTS} from '../core/config-loader.mjs';
19
20
 
20
- // Required sections (blocking if missing)
21
+ /**
22
+ * Build section patterns from config array.
23
+ * @param {string[]} sections - Section names
24
+ * @returns {Array<{pattern: RegExp, name: string}>}
25
+ */
26
+ function buildSectionPatterns(sections) {
27
+ return sections.map(name => ({
28
+ pattern: new RegExp(`^##\\s+${name}`, 'mi'),
29
+ name,
30
+ }));
31
+ }
32
+
33
+ // Default sections for backwards compatibility (used when importing directly)
21
34
  export const REQUIRED_SECTIONS = [
22
35
  {pattern: /^#\s+.+/m, name: 'Project Title (# Heading)'},
23
- {pattern: /^##\s+Installation/mi, name: 'Installation'},
24
- {pattern: /^##\s+Usage/mi, name: 'Usage'},
25
- {pattern: /^##\s+License/mi, name: 'License'},
36
+ ...buildSectionPatterns(DEFAULTS.readme.required),
26
37
  ];
27
38
 
28
- // Recommended sections (warnings only)
29
- export const RECOMMENDED_SECTIONS = [
30
- {pattern: /^##\s+Development/mi, name: 'Development'},
31
- {pattern: /^##\s+Contributing/mi, name: 'Contributing'},
32
- {pattern: /^##\s+Testing/mi, name: 'Testing'},
33
- ];
39
+ export const RECOMMENDED_SECTIONS = buildSectionPatterns(DEFAULTS.readme.recommended);
34
40
 
35
41
  /**
36
42
  * Find README.md in directory
@@ -64,9 +70,9 @@ export function checkSection(content, section) {
64
70
  * Main validation function
65
71
  * @param {string} [cwd] - Directory to validate (defaults to process.cwd())
66
72
  * @param {boolean} [silent] - Suppress console output
67
- * @returns {{valid: boolean, errors: string[], warnings: string[]}}
73
+ * @returns {Promise<{valid: boolean, errors: string[], warnings: string[]}>}
68
74
  */
69
- export function validateReadme(cwd = process.cwd(), silent = false) {
75
+ export async function validateReadme(cwd = process.cwd(), silent = false) {
70
76
  const log = silent ? () => {} : console.log.bind(console);
71
77
  const error = silent ? () => {} : console.error.bind(console);
72
78
 
@@ -75,6 +81,16 @@ export function validateReadme(cwd = process.cwd(), silent = false) {
75
81
  const errors = [];
76
82
  const warnings = [];
77
83
 
84
+ // Load project config
85
+ const config = await loadConfig(cwd);
86
+
87
+ // Build section patterns from config
88
+ const requiredSections = [
89
+ {pattern: /^#\s+.+/m, name: 'Project Title (# Heading)'},
90
+ ...buildSectionPatterns(config.readme.required),
91
+ ];
92
+ const recommendedSections = buildSectionPatterns(config.readme.recommended);
93
+
78
94
  // Check if README exists
79
95
  const readme = findReadme(cwd);
80
96
  if (!readme) {
@@ -90,7 +106,7 @@ export function validateReadme(cwd = process.cwd(), silent = false) {
90
106
 
91
107
  // Check required sections
92
108
  log('Checking required sections:');
93
- for (const section of REQUIRED_SECTIONS) {
109
+ for (const section of requiredSections) {
94
110
  const exists = checkSection(content, section);
95
111
  if (exists) {
96
112
  log(` OK ${section.name}`);
@@ -102,7 +118,7 @@ export function validateReadme(cwd = process.cwd(), silent = false) {
102
118
 
103
119
  // Check recommended sections
104
120
  log('\nChecking recommended sections:');
105
- for (const section of RECOMMENDED_SECTIONS) {
121
+ for (const section of recommendedSections) {
106
122
  const exists = checkSection(content, section);
107
123
  if (exists) {
108
124
  log(` OK ${section.name}`);
@@ -134,10 +150,10 @@ export function validateReadme(cwd = process.cwd(), silent = false) {
134
150
  /**
135
151
  * Get README validation result in ci-result.json format
136
152
  * @param {string} [cwd] - Directory to validate (defaults to process.cwd())
137
- * @returns {Object} Check result for ci-result.json
153
+ * @returns {Promise<Object>} Check result for ci-result.json
138
154
  */
139
- export function getReadmeCheckResult(cwd = process.cwd()) {
140
- const result = validateReadme(cwd, true);
155
+ export async function getReadmeCheckResult(cwd = process.cwd()) {
156
+ const result = await validateReadme(cwd, true);
141
157
 
142
158
  // Determine status
143
159
  let status = 'pass';
@@ -169,11 +185,11 @@ if (isMainModule) {
169
185
  const cwd = args.find(a => !a.startsWith('--')) || process.cwd();
170
186
 
171
187
  if (jsonOutput) {
172
- const result = getReadmeCheckResult(cwd);
188
+ const result = await getReadmeCheckResult(cwd);
173
189
  console.log(JSON.stringify(result, null, 2));
174
190
  process.exit(result.status === 'fail' ? 1 : 0);
175
191
  } else {
176
- const result = validateReadme(cwd);
192
+ const result = await validateReadme(cwd);
177
193
  process.exit(result.valid ? 0 : 1);
178
194
  }
179
195
  } catch (err) {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  # ==============================================================================
3
3
  # Kabran Traceability Coverage Report
4
- # Part of @kabran-owner/kabran-config
4
+ # Part of @kabran-tecnologia/kabran-config
5
5
  # Implements PROP-006: JSDoc Traceability Tags
6
6
  #
7
7
  # Generates a report of spec coverage in the codebase.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  # ==============================================================================
3
3
  # Kabran Traceability Core - Shared Functions
4
- # Part of @kabran-owner/kabran-config
4
+ # Part of @kabran-tecnologia/kabran-config
5
5
  # Implements PROP-006: JSDoc Traceability Tags
6
6
  # ==============================================================================
7
7
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bash
2
2
  # ==============================================================================
3
3
  # Kabran Traceability Validator
4
- # Part of @kabran-owner/kabran-config
4
+ # Part of @kabran-tecnologia/kabran-config
5
5
  # Implements PROP-006: JSDoc Traceability Tags
6
6
  #
7
7
  # Validates FORMAT of traceability tags (not presence).
@@ -161,8 +161,8 @@ SERVICE_VERSION=1.0.0 # Service version (default: 1.0.0)
161
161
  ENVIRONMENT=production # Environment name (default: from NODE_ENV)
162
162
  OTEL_NAMESPACE=kabran # Service namespace (default: kabran)
163
163
 
164
- # OTLP Exporter
165
- OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.kabran.com.br # Collector endpoint
164
+ # OTLP Exporter (REQUIRED)
165
+ OTEL_EXPORTER_OTLP_ENDPOINT=https://your-otel-collector.example.com # Your collector endpoint
166
166
  OTEL_EXPORTER_OTLP_TIMEOUT=10000 # Export timeout in ms (default: 10000)
167
167
 
168
168
  # Sampling
@@ -188,7 +188,7 @@ initTelemetry({
188
188
  // Optional (all have sensible defaults)
189
189
  serviceVersion: '1.0.0',
190
190
  environment: 'production',
191
- endpoint: 'https://otel.kabran.com.br',
191
+ endpoint: process.env.OTEL_ENDPOINT, // Required - set via env var
192
192
  sampleRate: 0.1,
193
193
  enabled: true,
194
194
 
@@ -292,20 +292,20 @@ import {
292
292
  } from '@kabran-tecnologia/kabran-config/telemetry/shared'
293
293
  ```
294
294
 
295
- ## Integration with Kosmos Observability
295
+ ## Integration with Observability Stack
296
296
 
297
- This package is designed to work with the Kosmos observability stack:
297
+ This package is designed to work with standard observability stacks:
298
298
 
299
- - **Traces** → Grafana Tempo
299
+ - **Traces** → Grafana Tempo, Jaeger, or any OTLP-compatible backend
300
300
  - **Logs** → Grafana Loki (via stdout/Promtail or direct export)
301
- - **Metrics** → Prometheus (planned, see [GAP-006])
301
+ - **Metrics** → Prometheus (planned)
302
302
 
303
- Default endpoint: `https://otel.kabran.com.br`
303
+ **Note:** You must configure `OTEL_ENDPOINT` to point to your OTLP collector.
304
304
 
305
305
  ### Viewing Traces
306
306
 
307
- 1. Open Grafana at your Kosmos instance
308
- 2. Go to Explore → Select Tempo
307
+ 1. Open your observability dashboard (e.g., Grafana)
308
+ 2. Go to Explore → Select your trace backend (Tempo, Jaeger, etc.)
309
309
  3. Search by service name or trace ID
310
310
 
311
311
  ## Best Practices
@@ -404,4 +404,4 @@ initTelemetry({
404
404
 
405
405
  - [OpenTelemetry JavaScript](https://opentelemetry.io/docs/languages/js/)
406
406
  - [W3C Trace Context](https://www.w3.org/TR/trace-context/)
407
- - [Kosmos Observability Stack](https://github.com/kabran-owner/kosmos/tree/main/services/observability)
407
+ - [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/)
@@ -76,9 +76,10 @@ function parseIgnorePaths(value) {
76
76
 
77
77
  /**
78
78
  * Default OTLP endpoint
79
- * Override: OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_ENDPOINT
79
+ * REQUIRED: Set via OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_ENDPOINT
80
+ * No default is provided - users must configure their own collector endpoint
80
81
  */
81
- export const DEFAULT_ENDPOINT = 'https://otel.kabran.com.br'
82
+ export const DEFAULT_ENDPOINT = null
82
83
 
83
84
  /**
84
85
  * Default OTLP traces path
@@ -107,12 +108,9 @@ export const DEFAULT_NAMESPACE = 'kabran'
107
108
  /**
108
109
  * Default CORS URLs for trace header propagation
109
110
  * Override: OTEL_PROPAGATE_TRACE_HEADER_CORS_URLS (comma-separated regex patterns)
111
+ * Only localhost is included by default - configure additional domains via env var
110
112
  */
111
- export const DEFAULT_CORS_URLS = [
112
- /.*\.supabase\.co/,
113
- /.*\.kabran\.com\.br/,
114
- /localhost/,
115
- ]
113
+ export const DEFAULT_CORS_URLS = [/localhost/]
116
114
 
117
115
  /**
118
116
  * Default instrumentation options
@@ -21,7 +21,7 @@ export interface TelemetryConfig {
21
21
  /** Deployment environment (default: from NODE_ENV or 'development') */
22
22
  environment?: string
23
23
 
24
- /** OTLP endpoint URL (default: 'https://otel.kabran.com.br') */
24
+ /** OTLP endpoint URL (required - set via OTEL_ENDPOINT env var) */
25
25
  endpoint?: string
26
26
 
27
27
  /** Sampling rate 0.0-1.0 (default: 0.1) */
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Kabran Configuration File
3
+ *
4
+ * This file customizes the behavior of kabran-config validators and tools.
5
+ * All settings are optional - defaults are applied for any missing values.
6
+ *
7
+ * @see https://github.com/kabran-owner/kabran-config
8
+ */
9
+
10
+ /** @type {import('@kabran-tecnologia/kabran-config/core/config-loader').KabranConfig} */
11
+ export default {
12
+ /**
13
+ * README Validator Configuration
14
+ *
15
+ * Customize which sections are required and recommended in your README.md
16
+ */
17
+ readme: {
18
+ // Sections that MUST be present (validation fails if missing)
19
+ required: ['Installation', 'Usage', 'License'],
20
+
21
+ // Sections that SHOULD be present (warning if missing)
22
+ recommended: ['Development', 'Testing', 'Contributing'],
23
+ },
24
+
25
+ /**
26
+ * Environment Validator Configuration
27
+ *
28
+ * Customize how environment variable usage is detected
29
+ */
30
+ env: {
31
+ // Require .env.example file if env vars are detected
32
+ requireExample: true,
33
+
34
+ // Patterns to search for when detecting env var usage
35
+ detectPatterns: [
36
+ 'process.env', // Node.js
37
+ 'import.meta.env', // Vite/ESM
38
+ 'Deno.env', // Deno
39
+ 'os.getenv', // Python
40
+ '$_ENV', // PHP
41
+ ],
42
+ },
43
+
44
+ /**
45
+ * Quality Standard Validator Configuration
46
+ *
47
+ * Customize the location of your quality standard documentation
48
+ */
49
+ quality: {
50
+ // Path to quality standard file (relative to project root)
51
+ standardPath: 'docs/quality/001-quality-standard.md',
52
+ },
53
+ };