@pattern-stack/codegen 0.6.0 → 0.6.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.
- package/CHANGELOG.md +12 -0
- package/package.json +6 -1
- package/src/config/case-converters.mjs +181 -0
- package/src/config/config-loader.mjs +34 -0
- package/src/config/locations.mjs +298 -0
- package/src/config/naming-config.mjs +173 -0
- package/src/config/paths.mjs +690 -0
- package/src/patterns/library/activity.pattern.ts +32 -0
- package/src/patterns/library/base.pattern.ts +28 -0
- package/src/patterns/library/index.ts +30 -0
- package/src/patterns/library/knowledge.pattern.ts +31 -0
- package/src/patterns/library/metadata.pattern.ts +31 -0
- package/src/patterns/library/synced.pattern.ts +34 -0
- package/src/patterns/pattern-definition.ts +280 -0
- package/src/patterns/registry.ts +365 -0
- package/src/schema/naming-config.schema.mjs +119 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Naming Configuration Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads and validates backend naming configuration from codegen.config.yaml.
|
|
5
|
+
* Provides defaults matching current hardcoded behavior for backward compatibility.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { getNamingConfig, resolveLayerNaming } from './naming-config.mjs';
|
|
9
|
+
*
|
|
10
|
+
* const config = getNamingConfig();
|
|
11
|
+
* const domainNaming = resolveLayerNaming(config, 'domain');
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { projectConfig } from './config-loader.mjs';
|
|
15
|
+
import {
|
|
16
|
+
BackendNamingConfigSchema,
|
|
17
|
+
DEFAULT_BACKEND_NAMING,
|
|
18
|
+
resolveLayerNaming as resolveLayer,
|
|
19
|
+
} from '../schema/naming-config.schema.mjs';
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Deep Merge Utility
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Check if value is a plain object (not array, null, or other types)
|
|
27
|
+
*/
|
|
28
|
+
function isPlainObject(obj) {
|
|
29
|
+
return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Deep merge two objects, with source taking precedence
|
|
34
|
+
*
|
|
35
|
+
* - Recursively merges nested objects
|
|
36
|
+
* - Source values override target values
|
|
37
|
+
* - Handles null/undefined gracefully
|
|
38
|
+
*
|
|
39
|
+
* @param {object} target - Base object with defaults
|
|
40
|
+
* @param {object} source - Override object (takes precedence)
|
|
41
|
+
* @returns {object} Merged object
|
|
42
|
+
*/
|
|
43
|
+
function deepMerge(target, source) {
|
|
44
|
+
if (source == null) return target;
|
|
45
|
+
if (target == null) return source;
|
|
46
|
+
|
|
47
|
+
const result = { ...target };
|
|
48
|
+
|
|
49
|
+
for (const key in source) {
|
|
50
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
51
|
+
const sourceValue = source[key];
|
|
52
|
+
const targetValue = target[key];
|
|
53
|
+
|
|
54
|
+
if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
|
|
55
|
+
result[key] = deepMerge(targetValue, sourceValue);
|
|
56
|
+
} else if (sourceValue !== undefined) {
|
|
57
|
+
result[key] = sourceValue;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// Configuration Loading
|
|
67
|
+
// ============================================================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Load and validate naming configuration
|
|
71
|
+
*
|
|
72
|
+
* - Reads `naming` section from project config
|
|
73
|
+
* - Deep merges with defaults for backward compatibility
|
|
74
|
+
* - Validates against Zod schema
|
|
75
|
+
* - Caches result for performance
|
|
76
|
+
*
|
|
77
|
+
* @returns {import('../schema/naming-config.schema.ts').BackendNamingConfig}
|
|
78
|
+
*/
|
|
79
|
+
function loadNamingConfig() {
|
|
80
|
+
// Get naming section from project config (may be undefined)
|
|
81
|
+
const rawConfig = projectConfig?.naming;
|
|
82
|
+
|
|
83
|
+
// If no config, use defaults
|
|
84
|
+
if (!rawConfig) {
|
|
85
|
+
return BackendNamingConfigSchema.parse(DEFAULT_BACKEND_NAMING);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Deep merge user config with defaults
|
|
89
|
+
const merged = deepMerge(DEFAULT_BACKEND_NAMING, rawConfig);
|
|
90
|
+
|
|
91
|
+
// Validate and return
|
|
92
|
+
try {
|
|
93
|
+
return BackendNamingConfigSchema.parse(merged);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error('Invalid naming configuration:');
|
|
96
|
+
if (error.errors) {
|
|
97
|
+
for (const err of error.errors) {
|
|
98
|
+
console.error(` - ${err.path.join('.')}: ${err.message}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
throw new Error(
|
|
102
|
+
`Failed to load naming configuration: ${error.message}\n` +
|
|
103
|
+
'Check your codegen.config.yaml naming section.'
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ============================================================================
|
|
109
|
+
// Cached Configuration
|
|
110
|
+
// ============================================================================
|
|
111
|
+
|
|
112
|
+
// Load config once at module initialization
|
|
113
|
+
let _cachedConfig = null;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get the naming configuration
|
|
117
|
+
*
|
|
118
|
+
* Returns cached, validated config with all defaults applied.
|
|
119
|
+
* First call loads and validates; subsequent calls return cached value.
|
|
120
|
+
*
|
|
121
|
+
* NOTE: Config is cached at first access. Changes to codegen.config.yaml
|
|
122
|
+
* require restarting the CLI to take effect. Use clearNamingConfigCache()
|
|
123
|
+
* in tests to reset the cache between test runs.
|
|
124
|
+
*
|
|
125
|
+
* @returns {import('../schema/naming-config.schema.ts').BackendNamingConfig}
|
|
126
|
+
*/
|
|
127
|
+
export function getNamingConfig() {
|
|
128
|
+
if (_cachedConfig === null) {
|
|
129
|
+
_cachedConfig = loadNamingConfig();
|
|
130
|
+
}
|
|
131
|
+
return _cachedConfig;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Clear cached config (useful for testing)
|
|
136
|
+
*/
|
|
137
|
+
export function clearNamingConfigCache() {
|
|
138
|
+
_cachedConfig = null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ============================================================================
|
|
142
|
+
// Layer Resolution
|
|
143
|
+
// ============================================================================
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Resolve effective naming config for a specific layer
|
|
147
|
+
*
|
|
148
|
+
* Merges layer-specific overrides with global defaults.
|
|
149
|
+
* Returns fully resolved config with no optional fields.
|
|
150
|
+
*
|
|
151
|
+
* @param {'domain' | 'application' | 'infrastructure' | 'presentation'} layer
|
|
152
|
+
* @returns {import('../schema/naming-config.schema.ts').ResolvedLayerNaming}
|
|
153
|
+
*/
|
|
154
|
+
export function resolveLayerNaming(layer) {
|
|
155
|
+
const config = getNamingConfig();
|
|
156
|
+
return resolveLayer(config, layer);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ============================================================================
|
|
160
|
+
// Exports
|
|
161
|
+
// ============================================================================
|
|
162
|
+
|
|
163
|
+
export {
|
|
164
|
+
DEFAULT_BACKEND_NAMING,
|
|
165
|
+
deepMerge,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export default {
|
|
169
|
+
getNamingConfig,
|
|
170
|
+
resolveLayerNaming,
|
|
171
|
+
clearNamingConfigCache,
|
|
172
|
+
DEFAULT_BACKEND_NAMING,
|
|
173
|
+
};
|