@fulmenhq/tsfulmen 0.1.6

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 (188) hide show
  1. package/CHANGELOG.md +616 -0
  2. package/LICENSE +57 -0
  3. package/README.md +674 -0
  4. package/config/crucible-ts/README.md +38 -0
  5. package/config/crucible-ts/library/foundry/country-codes.yaml +29 -0
  6. package/config/crucible-ts/library/foundry/exit-codes.snapshot.json +351 -0
  7. package/config/crucible-ts/library/foundry/exit-codes.yaml +483 -0
  8. package/config/crucible-ts/library/foundry/fixtures/signals/invalid/invalid-behavior.yaml +45 -0
  9. package/config/crucible-ts/library/foundry/fixtures/signals/invalid/invalid-exit-code.yaml +51 -0
  10. package/config/crucible-ts/library/foundry/fixtures/signals/invalid/malformed.yaml +44 -0
  11. package/config/crucible-ts/library/foundry/fixtures/signals/invalid/missing-required.yaml +36 -0
  12. package/config/crucible-ts/library/foundry/fixtures/signals/parity-snapshot.json +162 -0
  13. package/config/crucible-ts/library/foundry/fixtures/signals/valid/complete.yaml +314 -0
  14. package/config/crucible-ts/library/foundry/fixtures/signals/valid/custom-behavior.yaml +96 -0
  15. package/config/crucible-ts/library/foundry/fixtures/signals/valid/minimal.yaml +55 -0
  16. package/config/crucible-ts/library/foundry/http-statuses.yaml +148 -0
  17. package/config/crucible-ts/library/foundry/mime-types.yaml +39 -0
  18. package/config/crucible-ts/library/foundry/patterns.yaml +185 -0
  19. package/config/crucible-ts/library/foundry/signals.yaml +331 -0
  20. package/config/crucible-ts/library/foundry/similarity-fixtures.yaml +432 -0
  21. package/config/crucible-ts/library/foundry/simplified-modes.snapshot.json +117 -0
  22. package/config/crucible-ts/library/fulhash/fixtures.yaml +160 -0
  23. package/config/crucible-ts/library/v1.0.0/module-manifest.yaml +179 -0
  24. package/config/crucible-ts/repository/app-identity/app-identity.example.yaml +42 -0
  25. package/config/crucible-ts/repository/app-identity/fixtures/invalid/invalid-binary-name.yaml +7 -0
  26. package/config/crucible-ts/repository/app-identity/fixtures/invalid/invalid-env-prefix.yaml +7 -0
  27. package/config/crucible-ts/repository/app-identity/fixtures/invalid/invalid-vendor.yaml +7 -0
  28. package/config/crucible-ts/repository/app-identity/fixtures/invalid/malformed-yaml.yaml +8 -0
  29. package/config/crucible-ts/repository/app-identity/fixtures/invalid/missing-required.yaml +6 -0
  30. package/config/crucible-ts/repository/app-identity/fixtures/valid/complete.yaml +20 -0
  31. package/config/crucible-ts/repository/app-identity/fixtures/valid/minimal.yaml +7 -0
  32. package/config/crucible-ts/repository/app-identity/fixtures/valid/monorepo-api.yaml +10 -0
  33. package/config/crucible-ts/repository/app-identity/fixtures/valid/monorepo-worker.yaml +10 -0
  34. package/config/crucible-ts/repository/app-identity/parity-snapshot.json +125 -0
  35. package/config/crucible-ts/server/management/server-management.yaml +141 -0
  36. package/config/crucible-ts/sync/README.md +13 -0
  37. package/config/crucible-ts/sync/sync-keys.yaml +74 -0
  38. package/config/crucible-ts/taxonomy/languages.yaml +33 -0
  39. package/config/crucible-ts/taxonomy/metrics.yaml +115 -0
  40. package/config/crucible-ts/taxonomy/repository-categories.yaml +66 -0
  41. package/config/crucible-ts/terminal/v1.0.0/terminal-overrides-defaults.yaml +38 -0
  42. package/config/crucible-ts/web/branding/site-branding.yaml +21 -0
  43. package/config/crucible-ts/web/styling/site-styling.yaml +104 -0
  44. package/dist/appidentity/index.d.ts +304 -0
  45. package/dist/appidentity/index.js +5519 -0
  46. package/dist/appidentity/index.js.map +1 -0
  47. package/dist/config/index.d.ts +144 -0
  48. package/dist/config/index.js +5752 -0
  49. package/dist/config/index.js.map +1 -0
  50. package/dist/crucible/index.d.ts +78 -0
  51. package/dist/crucible/index.js +6038 -0
  52. package/dist/crucible/index.js.map +1 -0
  53. package/dist/docscribe/index.d.ts +110 -0
  54. package/dist/docscribe/index.js +682 -0
  55. package/dist/docscribe/index.js.map +1 -0
  56. package/dist/errors/index.d.ts +150 -0
  57. package/dist/errors/index.js +5583 -0
  58. package/dist/errors/index.js.map +1 -0
  59. package/dist/foundry/index.d.ts +1557 -0
  60. package/dist/foundry/index.js +5474 -0
  61. package/dist/foundry/index.js.map +1 -0
  62. package/dist/foundry/similarity/index.d.ts +17 -0
  63. package/dist/foundry/similarity/index.js +136 -0
  64. package/dist/foundry/similarity/index.js.map +1 -0
  65. package/dist/fulhash/index.d.ts +82 -0
  66. package/dist/fulhash/index.js +374 -0
  67. package/dist/fulhash/index.js.map +1 -0
  68. package/dist/fulmen-error-B_kX8jSC.d.ts +309 -0
  69. package/dist/index.d.ts +14 -0
  70. package/dist/index.js +6197 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/logger-JU2jYitA.d.ts +171 -0
  73. package/dist/logging/index.d.ts +198 -0
  74. package/dist/logging/index.js +578 -0
  75. package/dist/logging/index.js.map +1 -0
  76. package/dist/pathfinder/index.d.ts +532 -0
  77. package/dist/pathfinder/index.js +6750 -0
  78. package/dist/pathfinder/index.js.map +1 -0
  79. package/dist/registry-x1-Qi_Tz.d.ts +349 -0
  80. package/dist/schema/index.d.ts +388 -0
  81. package/dist/schema/index.js +5522 -0
  82. package/dist/schema/index.js.map +1 -0
  83. package/dist/suggest-CLqjLZ5L.d.ts +168 -0
  84. package/dist/telemetry/index.d.ts +161 -0
  85. package/dist/telemetry/index.js +5610 -0
  86. package/dist/telemetry/index.js.map +1 -0
  87. package/dist/types-B_WtvQbS.d.ts +214 -0
  88. package/package.json +130 -0
  89. package/schemas/crucible-ts/api/http/v1.0.0/README.md +22 -0
  90. package/schemas/crucible-ts/api/http/v1.0.0/error-response.schema.json +54 -0
  91. package/schemas/crucible-ts/api/http/v1.0.0/health-response.schema.json +70 -0
  92. package/schemas/crucible-ts/api/http/v1.0.0/success-response.schema.json +51 -0
  93. package/schemas/crucible-ts/api/http/v1.0.0/version-response.schema.json +61 -0
  94. package/schemas/crucible-ts/ascii/v1.0.0/README.md +69 -0
  95. package/schemas/crucible-ts/ascii/v1.0.0/box-chars.schema.json +60 -0
  96. package/schemas/crucible-ts/ascii/v1.0.0/string-analysis.schema.json +45 -0
  97. package/schemas/crucible-ts/assessment/README.md +25 -0
  98. package/schemas/crucible-ts/assessment/v1.0.0/severity-definitions.schema.json +60 -0
  99. package/schemas/crucible-ts/config/fulmen-ecosystem/v1.0.0/README.md +11 -0
  100. package/schemas/crucible-ts/config/fulmen-ecosystem/v1.0.0/fulmen-config-paths.schema.json +61 -0
  101. package/schemas/crucible-ts/config/goneat/README.md +60 -0
  102. package/schemas/crucible-ts/config/goneat/v1.0.0/dates.yaml +234 -0
  103. package/schemas/crucible-ts/config/goneat/v1.0.0/goneat-config.yaml +344 -0
  104. package/schemas/crucible-ts/config/goneat/v1.0.0/lifecycle-phase.json +20 -0
  105. package/schemas/crucible-ts/config/goneat/v1.0.0/release-phase.json +17 -0
  106. package/schemas/crucible-ts/config/goneat/v1.0.0/security-policy.yaml +178 -0
  107. package/schemas/crucible-ts/config/goneat/v1.0.0/version-policy.schema.yaml +205 -0
  108. package/schemas/crucible-ts/config/repository/app-identity/v1.0.0/app-identity.schema.json +143 -0
  109. package/schemas/crucible-ts/config/repository/v1.0.0/lifecycle-phase.json +20 -0
  110. package/schemas/crucible-ts/config/repository-category/codex/v1.0.0/codex-config.schema.json +288 -0
  111. package/schemas/crucible-ts/config/standards/v1.0.0/adr-adoption-status.json +60 -0
  112. package/schemas/crucible-ts/config/standards/v1.0.0/adr-frontmatter.schema.json +225 -0
  113. package/schemas/crucible-ts/config/standards/v1.0.0/adr-lifecycle-status.json +62 -0
  114. package/schemas/crucible-ts/config/sync-consumer-config.yaml +51 -0
  115. package/schemas/crucible-ts/config/sync-keys.schema.yaml +37 -0
  116. package/schemas/crucible-ts/content/README.md +19 -0
  117. package/schemas/crucible-ts/content/binary-embed-manifest/v1.0.0/README.md +13 -0
  118. package/schemas/crucible-ts/content/binary-embed-manifest/v1.0.0/binary-embed-manifest.schema.yaml +36 -0
  119. package/schemas/crucible-ts/content/embed-manifest/v1.1.0/README.md +13 -0
  120. package/schemas/crucible-ts/content/embed-manifest/v1.1.0/embed-manifest.schema.yaml +78 -0
  121. package/schemas/crucible-ts/content/ssot-provenance/v1.0.0/README.md +200 -0
  122. package/schemas/crucible-ts/content/ssot-provenance/v1.0.0/ssot-provenance.schema.json +128 -0
  123. package/schemas/crucible-ts/error-handling/v1.0.0/error-response.schema.json +75 -0
  124. package/schemas/crucible-ts/library/foundry/v1.0.0/country-codes.schema.json +58 -0
  125. package/schemas/crucible-ts/library/foundry/v1.0.0/exit-codes.schema.json +300 -0
  126. package/schemas/crucible-ts/library/foundry/v1.0.0/http-status-groups.schema.json +74 -0
  127. package/schemas/crucible-ts/library/foundry/v1.0.0/mime-types.schema.json +60 -0
  128. package/schemas/crucible-ts/library/foundry/v1.0.0/patterns.schema.json +97 -0
  129. package/schemas/crucible-ts/library/foundry/v1.0.0/signals.schema.json +457 -0
  130. package/schemas/crucible-ts/library/foundry/v1.0.0/similarity.schema.json +260 -0
  131. package/schemas/crucible-ts/library/foundry/v2.0.0/similarity.schema.json +558 -0
  132. package/schemas/crucible-ts/library/fulhash/v1.0.0/README.md +6 -0
  133. package/schemas/crucible-ts/library/fulhash/v1.0.0/checksum-string.schema.json +8 -0
  134. package/schemas/crucible-ts/library/fulhash/v1.0.0/digest.schema.json +100 -0
  135. package/schemas/crucible-ts/library/fulhash/v1.0.0/fixtures.schema.json +227 -0
  136. package/schemas/crucible-ts/library/module-manifest/v1.0.0/README.md +31 -0
  137. package/schemas/crucible-ts/library/module-manifest/v1.0.0/module-manifest.schema.json +132 -0
  138. package/schemas/crucible-ts/meta/README.md +23 -0
  139. package/schemas/crucible-ts/meta/draft-07/schema.json +245 -0
  140. package/schemas/crucible-ts/meta/draft-2020-12/meta/applicator.json +81 -0
  141. package/schemas/crucible-ts/meta/draft-2020-12/meta/content.json +21 -0
  142. package/schemas/crucible-ts/meta/draft-2020-12/meta/core.json +64 -0
  143. package/schemas/crucible-ts/meta/draft-2020-12/meta/format-annotation.json +15 -0
  144. package/schemas/crucible-ts/meta/draft-2020-12/meta/meta-data.json +35 -0
  145. package/schemas/crucible-ts/meta/draft-2020-12/meta/unevaluated.json +18 -0
  146. package/schemas/crucible-ts/meta/draft-2020-12/meta/validation.json +119 -0
  147. package/schemas/crucible-ts/meta/draft-2020-12/schema.json +80 -0
  148. package/schemas/crucible-ts/observability/logging/v1.0.0/README.md +82 -0
  149. package/schemas/crucible-ts/observability/logging/v1.0.0/definitions.schema.json +140 -0
  150. package/schemas/crucible-ts/observability/logging/v1.0.0/log-event.schema.json +179 -0
  151. package/schemas/crucible-ts/observability/logging/v1.0.0/logger-config.schema.json +518 -0
  152. package/schemas/crucible-ts/observability/logging/v1.0.0/logging-policy.schema.json +225 -0
  153. package/schemas/crucible-ts/observability/logging/v1.0.0/middleware-config.schema.json +181 -0
  154. package/schemas/crucible-ts/observability/logging/v1.0.0/severity-filter.schema.json +38 -0
  155. package/schemas/crucible-ts/observability/metrics/v1.0.0/metrics-event.schema.json +86 -0
  156. package/schemas/crucible-ts/pathfinder/v1.0.0/README.md +104 -0
  157. package/schemas/crucible-ts/pathfinder/v1.0.0/error-response.schema.json +35 -0
  158. package/schemas/crucible-ts/pathfinder/v1.0.0/find-query.schema.json +49 -0
  159. package/schemas/crucible-ts/pathfinder/v1.0.0/finder-config.schema.json +91 -0
  160. package/schemas/crucible-ts/pathfinder/v1.0.0/metadata.schema.json +61 -0
  161. package/schemas/crucible-ts/pathfinder/v1.0.0/path-constraint.schema.json +50 -0
  162. package/schemas/crucible-ts/pathfinder/v1.0.0/path-result.schema.json +40 -0
  163. package/schemas/crucible-ts/protocol/http/v1.0.0/README.md +22 -0
  164. package/schemas/crucible-ts/protocol/http/v1.0.0/error-response.schema.json +54 -0
  165. package/schemas/crucible-ts/protocol/http/v1.0.0/health-response.schema.json +70 -0
  166. package/schemas/crucible-ts/protocol/http/v1.0.0/success-response.schema.json +51 -0
  167. package/schemas/crucible-ts/protocol/http/v1.0.0/version-response.schema.json +61 -0
  168. package/schemas/crucible-ts/schema-validation/v1.0.0/README.md +65 -0
  169. package/schemas/crucible-ts/schema-validation/v1.0.0/schema-registry.schema.json +31 -0
  170. package/schemas/crucible-ts/schema-validation/v1.0.0/validator-config.schema.json +36 -0
  171. package/schemas/crucible-ts/server/management/v1.0.0/server-management.schema.json +199 -0
  172. package/schemas/crucible-ts/taxonomy/language/v1.0.0/README.md +30 -0
  173. package/schemas/crucible-ts/taxonomy/language/v1.0.0/language-key.schema.json +17 -0
  174. package/schemas/crucible-ts/taxonomy/language/v1.0.0/language-metadata.schema.json +44 -0
  175. package/schemas/crucible-ts/taxonomy/repository-category/v1.0.0/README.md +31 -0
  176. package/schemas/crucible-ts/taxonomy/repository-category/v1.0.0/category-key.schema.json +19 -0
  177. package/schemas/crucible-ts/taxonomy/repository-category/v1.0.0/category-metadata.schema.json +39 -0
  178. package/schemas/crucible-ts/terminal/v1.0.0/README.md +45 -0
  179. package/schemas/crucible-ts/terminal/v1.0.0/catalog/apple-terminal.yaml +2 -0
  180. package/schemas/crucible-ts/terminal/v1.0.0/catalog/ghostty.yaml +13 -0
  181. package/schemas/crucible-ts/terminal/v1.0.0/catalog/iterm2.yaml +13 -0
  182. package/schemas/crucible-ts/terminal/v1.0.0/schema.json +40 -0
  183. package/schemas/crucible-ts/tooling/external-tools/v1.0.0/README.md +164 -0
  184. package/schemas/crucible-ts/tooling/external-tools/v1.0.0/external-tools-manifest.schema.yaml +83 -0
  185. package/schemas/crucible-ts/tooling/goneat-tools/v1.0.0/README.md +177 -0
  186. package/schemas/crucible-ts/tooling/goneat-tools/v1.0.0/goneat-tools-config.schema.yaml +146 -0
  187. package/schemas/crucible-ts/web/branding/v1.0.0/site-branding.schema.json +79 -0
  188. package/schemas/crucible-ts/web/styling/v1.0.0/site-styling.schema.json +321 -0
@@ -0,0 +1,578 @@
1
+ import { hostname } from 'os';
2
+ import pino from 'pino';
3
+ import { readFileSync, appendFileSync } from 'fs';
4
+ import { parse } from 'yaml';
5
+
6
+ // src/logging/logger.ts
7
+
8
+ // src/logging/types.ts
9
+ var LoggingProfile = /* @__PURE__ */ ((LoggingProfile2) => {
10
+ LoggingProfile2["SIMPLE"] = "simple";
11
+ LoggingProfile2["STRUCTURED"] = "structured";
12
+ LoggingProfile2["ENTERPRISE"] = "enterprise";
13
+ LoggingProfile2["CUSTOM"] = "custom";
14
+ return LoggingProfile2;
15
+ })(LoggingProfile || {});
16
+ var PolicyError = class extends Error {
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = "PolicyError";
20
+ }
21
+ };
22
+
23
+ // src/logging/policy.ts
24
+ var PolicyEnforcer = class {
25
+ policy;
26
+ policyFile;
27
+ /**
28
+ * Create a new policy enforcer
29
+ *
30
+ * @param policyFile - Path to YAML policy file
31
+ * @throws {PolicyError} If policy file cannot be loaded or is invalid
32
+ */
33
+ constructor(policyFile) {
34
+ this.policyFile = policyFile;
35
+ this.policy = this.loadPolicy(policyFile);
36
+ }
37
+ /**
38
+ * Validate if a profile is allowed under the current policy
39
+ *
40
+ * @param profile - The logging profile to validate
41
+ * @param options - Optional validation context (appType, environment)
42
+ * @returns true if profile is allowed, false otherwise
43
+ *
44
+ * @example
45
+ * const enforcer = new PolicyEnforcer('/org/logging-policy.yaml');
46
+ * if (enforcer.validateProfile(LoggingProfile.ENTERPRISE, { environment: 'production' })) {
47
+ * // Profile is allowed
48
+ * }
49
+ */
50
+ validateProfile(profile, options) {
51
+ if (!this.policy.allowedProfiles.includes(profile)) {
52
+ return false;
53
+ }
54
+ if (options?.environment && this.policy.environmentRules) {
55
+ const envRules = this.policy.environmentRules[options.environment];
56
+ if (envRules && !envRules.includes(profile)) {
57
+ return false;
58
+ }
59
+ }
60
+ if (options?.appType && this.policy.requiredProfiles) {
61
+ const appTypeRules = this.policy.requiredProfiles[options.appType];
62
+ if (appTypeRules && !appTypeRules.includes(profile)) {
63
+ return false;
64
+ }
65
+ }
66
+ return true;
67
+ }
68
+ /**
69
+ * Get the required profile for a given app type and environment
70
+ *
71
+ * @param appType - The application type
72
+ * @param environment - The deployment environment
73
+ * @returns The required logging profile
74
+ * @throws {PolicyError} If no required profile found for app type
75
+ *
76
+ * @example
77
+ * const enforcer = new PolicyEnforcer('/org/logging-policy.yaml');
78
+ * const profile = enforcer.getRequiredProfile('api-server', 'production');
79
+ * // Returns LoggingProfile.ENTERPRISE
80
+ */
81
+ getRequiredProfile(appType, environment) {
82
+ if (this.policy.requiredProfiles?.[appType]) {
83
+ const profiles = this.policy.requiredProfiles[appType];
84
+ if (this.policy.environmentRules?.[environment]) {
85
+ const envProfiles = this.policy.environmentRules[environment];
86
+ const validProfiles = profiles.filter((p) => envProfiles.includes(p));
87
+ if (validProfiles.length > 0) {
88
+ return this.getMostRestrictiveProfile(validProfiles);
89
+ }
90
+ }
91
+ return this.getMostRestrictiveProfile(profiles);
92
+ }
93
+ throw new PolicyError(
94
+ `No required profile found for app type "${appType}" in policy ${this.policyFile}`
95
+ );
96
+ }
97
+ /**
98
+ * Get a helpful error message for policy validation failure
99
+ *
100
+ * @param profile - The profile that failed validation
101
+ * @param options - The validation options used
102
+ * @returns A descriptive error message
103
+ */
104
+ getValidationErrorMessage(profile, options) {
105
+ const parts = [`Profile "${profile}" not allowed by policy "${this.policyFile}".`];
106
+ if (options?.environment) {
107
+ parts.push(`Environment: ${options.environment}`);
108
+ }
109
+ if (options?.appType) {
110
+ parts.push(`App Type: ${options.appType}`);
111
+ }
112
+ parts.push(`Allowed profiles: ${this.policy.allowedProfiles.join(", ")}`);
113
+ if (options?.environment && this.policy.environmentRules?.[options.environment]) {
114
+ const envProfiles = this.policy.environmentRules[options.environment];
115
+ parts.push(`Environment "${options.environment}" allows: ${envProfiles.join(", ")}`);
116
+ }
117
+ if (options?.appType && this.policy.requiredProfiles?.[options.appType]) {
118
+ const appProfiles = this.policy.requiredProfiles[options.appType];
119
+ parts.push(`App type "${options.appType}" requires: ${appProfiles.join(", ")}`);
120
+ }
121
+ return parts.join(" | ");
122
+ }
123
+ /**
124
+ * Load and parse the policy file
125
+ *
126
+ * @param policyFile - Path to YAML policy file
127
+ * @returns Parsed logging policy
128
+ * @throws {PolicyError} If file cannot be read or parsed
129
+ */
130
+ loadPolicy(policyFile) {
131
+ try {
132
+ const content = readFileSync(policyFile, "utf-8");
133
+ const parsed = parse(content);
134
+ if (!parsed.allowedProfiles || !Array.isArray(parsed.allowedProfiles)) {
135
+ throw new PolicyError(
136
+ `Invalid policy file ${policyFile}: missing or invalid "allowedProfiles" field`
137
+ );
138
+ }
139
+ const validProfiles = Object.values(LoggingProfile);
140
+ for (const profile of parsed.allowedProfiles) {
141
+ if (!validProfiles.includes(profile)) {
142
+ throw new PolicyError(`Invalid policy file ${policyFile}: unknown profile "${profile}"`);
143
+ }
144
+ }
145
+ if (parsed.requiredProfiles) {
146
+ if (typeof parsed.requiredProfiles !== "object") {
147
+ throw new PolicyError(
148
+ `Invalid policy file ${policyFile}: "requiredProfiles" must be an object`
149
+ );
150
+ }
151
+ for (const [appType, profiles] of Object.entries(parsed.requiredProfiles)) {
152
+ if (!Array.isArray(profiles)) {
153
+ throw new PolicyError(
154
+ `Invalid policy file ${policyFile}: requiredProfiles["${appType}"] must be an array, got ${typeof profiles}. Check YAML formatting - each profile should be on a new line with a hyphen.`
155
+ );
156
+ }
157
+ for (const profile of profiles) {
158
+ if (!validProfiles.includes(profile)) {
159
+ throw new PolicyError(
160
+ `Invalid policy file ${policyFile}: requiredProfiles["${appType}"] contains unknown profile "${profile}"`
161
+ );
162
+ }
163
+ }
164
+ }
165
+ }
166
+ if (parsed.environmentRules) {
167
+ if (typeof parsed.environmentRules !== "object") {
168
+ throw new PolicyError(
169
+ `Invalid policy file ${policyFile}: "environmentRules" must be an object`
170
+ );
171
+ }
172
+ for (const [environment, profiles] of Object.entries(parsed.environmentRules)) {
173
+ if (!Array.isArray(profiles)) {
174
+ throw new PolicyError(
175
+ `Invalid policy file ${policyFile}: environmentRules["${environment}"] must be an array, got ${typeof profiles}. Check YAML formatting - each profile should be on a new line with a hyphen.`
176
+ );
177
+ }
178
+ for (const profile of profiles) {
179
+ if (!validProfiles.includes(profile)) {
180
+ throw new PolicyError(
181
+ `Invalid policy file ${policyFile}: environmentRules["${environment}"] contains unknown profile "${profile}"`
182
+ );
183
+ }
184
+ }
185
+ }
186
+ }
187
+ return parsed;
188
+ } catch (error) {
189
+ if (error instanceof PolicyError) {
190
+ throw error;
191
+ }
192
+ if (error.code === "ENOENT") {
193
+ throw new PolicyError(`Policy file not found: ${policyFile}`);
194
+ }
195
+ throw new PolicyError(
196
+ `Failed to load policy file ${policyFile}: ${error.message}`
197
+ );
198
+ }
199
+ }
200
+ /**
201
+ * Get the most restrictive profile from a list
202
+ * Order: CUSTOM > ENTERPRISE > STRUCTURED > SIMPLE
203
+ *
204
+ * @param profiles - List of profiles
205
+ * @returns The most restrictive profile
206
+ */
207
+ getMostRestrictiveProfile(profiles) {
208
+ const order = [
209
+ "custom" /* CUSTOM */,
210
+ "enterprise" /* ENTERPRISE */,
211
+ "structured" /* STRUCTURED */,
212
+ "simple" /* SIMPLE */
213
+ ];
214
+ for (const profile of order) {
215
+ if (profiles.includes(profile)) {
216
+ return profile;
217
+ }
218
+ }
219
+ return profiles[0];
220
+ }
221
+ };
222
+ var ConsoleSink = class {
223
+ write(event) {
224
+ console.log(JSON.stringify(event));
225
+ }
226
+ };
227
+ var FileSink = class {
228
+ constructor(filePath) {
229
+ this.filePath = filePath;
230
+ }
231
+ write(event) {
232
+ try {
233
+ appendFileSync(this.filePath, `${JSON.stringify(event)}
234
+ `);
235
+ } catch (error) {
236
+ console.error(`FileSink: Failed to write to ${this.filePath}:`, error.message);
237
+ console.log(JSON.stringify(event));
238
+ }
239
+ }
240
+ };
241
+ var NullSink = class {
242
+ write(_event) {
243
+ }
244
+ };
245
+
246
+ // src/logging/logger.ts
247
+ var Logger = class {
248
+ service;
249
+ profile;
250
+ impl;
251
+ constructor(config) {
252
+ this.service = config.service;
253
+ this.profile = config.profile;
254
+ if (config.policyFile) {
255
+ this.validatePolicy(config.profile, config.policyFile);
256
+ }
257
+ this.impl = this.createImplementation(config);
258
+ }
259
+ debug(message, context) {
260
+ this.impl.debug(message, context);
261
+ }
262
+ info(message, context) {
263
+ this.impl.info(message, context);
264
+ }
265
+ warn(message, context) {
266
+ this.impl.warn(message, context);
267
+ }
268
+ error(message, error, context) {
269
+ this.impl.error(message, error, context);
270
+ }
271
+ child(bindings) {
272
+ const childLogger = Object.create(this);
273
+ childLogger.impl = this.impl.child(bindings);
274
+ return childLogger;
275
+ }
276
+ validatePolicy(profile, policyFile) {
277
+ const enforcer = new PolicyEnforcer(policyFile);
278
+ const appType = process.env.APP_TYPE;
279
+ const environment = process.env.NODE_ENV;
280
+ if (!enforcer.validateProfile(profile, { appType, environment })) {
281
+ throw new PolicyError(enforcer.getValidationErrorMessage(profile, { appType, environment }));
282
+ }
283
+ }
284
+ createImplementation(config) {
285
+ switch (config.profile) {
286
+ case "simple" /* SIMPLE */:
287
+ return new SimpleLogger(config.service);
288
+ case "structured" /* STRUCTURED */:
289
+ return new StructuredLogger(config.service, config.filePath);
290
+ case "enterprise" /* ENTERPRISE */:
291
+ return new EnterpriseLogger(config.service, {
292
+ // biome-ignore lint/suspicious/noExplicitAny: Phase 1 - proper discriminated union handling in Phase 2
293
+ sinks: config.sinks,
294
+ // biome-ignore lint/suspicious/noExplicitAny: Phase 1 - proper discriminated union handling in Phase 2
295
+ middleware: config.middleware
296
+ });
297
+ case "custom" /* CUSTOM */:
298
+ return new EnterpriseLogger(config.service, config.customConfig);
299
+ }
300
+ }
301
+ };
302
+ var SimpleLogger = class {
303
+ constructor(service) {
304
+ this.service = service;
305
+ this.pino = pino({
306
+ name: service,
307
+ level: "debug",
308
+ messageKey: "message",
309
+ base: void 0,
310
+ timestamp: false,
311
+ formatters: {
312
+ level: (label) => ({ severity: label.toUpperCase() }),
313
+ // biome-ignore lint/suspicious/noExplicitAny: Pino formatter requires any type
314
+ log: (object) => {
315
+ return {
316
+ service: this.service,
317
+ ...object
318
+ };
319
+ }
320
+ }
321
+ });
322
+ }
323
+ pino;
324
+ debug(message, context) {
325
+ this.pino.debug(context, message);
326
+ }
327
+ info(message, context) {
328
+ this.pino.info(context, message);
329
+ }
330
+ warn(message, context) {
331
+ this.pino.warn(context, message);
332
+ }
333
+ error(message, error, context) {
334
+ const errorContext = {
335
+ ...context,
336
+ ...error && { error: error.message, stack: error.stack }
337
+ };
338
+ this.pino.error(errorContext, message);
339
+ }
340
+ child(bindings) {
341
+ const childPino = this.pino.child(bindings);
342
+ const childLogger = Object.create(this);
343
+ childLogger.pino = childPino;
344
+ return childLogger;
345
+ }
346
+ };
347
+ var StructuredLogger = class {
348
+ constructor(service, filePath) {
349
+ this.service = service;
350
+ this.filePath = filePath;
351
+ const config = {
352
+ name: service,
353
+ level: "debug",
354
+ messageKey: "message",
355
+ base: void 0,
356
+ timestamp: () => `,"timestamp":"${(/* @__PURE__ */ new Date()).toISOString()}"`,
357
+ formatters: {
358
+ level: (label) => ({ severity: label.toUpperCase() }),
359
+ // biome-ignore lint/suspicious/noExplicitAny: Pino formatter requires any type
360
+ log: (object) => {
361
+ return {
362
+ service: this.service,
363
+ ...object
364
+ };
365
+ }
366
+ }
367
+ };
368
+ if (filePath) {
369
+ const streams = [
370
+ { stream: process.stdout },
371
+ { stream: pino.destination(filePath) }
372
+ ];
373
+ this.pino = pino(config, pino.multistream(streams));
374
+ } else {
375
+ this.pino = pino(config);
376
+ }
377
+ }
378
+ pino;
379
+ debug(message, context) {
380
+ this.pino.debug(context, message);
381
+ }
382
+ info(message, context) {
383
+ this.pino.info(context, message);
384
+ }
385
+ warn(message, context) {
386
+ this.pino.warn(context, message);
387
+ }
388
+ error(message, error, context) {
389
+ const errorContext = {
390
+ ...context,
391
+ ...error && { error: error.message, stack: error.stack }
392
+ };
393
+ this.pino.error(errorContext, message);
394
+ }
395
+ child(bindings) {
396
+ const childPino = this.pino.child(bindings);
397
+ const childLogger = Object.create(this);
398
+ childLogger.pino = childPino;
399
+ return childLogger;
400
+ }
401
+ };
402
+ var EnterpriseLogger = class _EnterpriseLogger {
403
+ constructor(service, config, bindings) {
404
+ this.service = service;
405
+ this.sinks = config?.sinks ?? [new ConsoleSink()];
406
+ this.middleware = config?.middleware ?? [];
407
+ this.bindings = bindings ?? {};
408
+ }
409
+ sinks;
410
+ middleware;
411
+ bindings;
412
+ debug(message, context) {
413
+ this.logWithPipeline("DEBUG", message, context);
414
+ }
415
+ info(message, context) {
416
+ this.logWithPipeline("INFO", message, context);
417
+ }
418
+ warn(message, context) {
419
+ this.logWithPipeline("WARN", message, context);
420
+ }
421
+ error(message, error, context) {
422
+ const errorContext = {
423
+ ...context,
424
+ ...error && {
425
+ error: error.message,
426
+ stack: error.stack,
427
+ errorType: error.constructor.name
428
+ }
429
+ };
430
+ this.logWithPipeline("ERROR", message, errorContext);
431
+ }
432
+ logWithPipeline(severity, message, context) {
433
+ let event = {
434
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
435
+ service: this.service,
436
+ severity,
437
+ message,
438
+ correlationId: context?.correlationId ?? this.generateCorrelationId(),
439
+ host: this.getHostname(),
440
+ pid: process.pid,
441
+ ...this.bindings,
442
+ ...context
443
+ };
444
+ for (const mw of this.middleware) {
445
+ event = mw.process(event);
446
+ }
447
+ for (const sink of this.sinks) {
448
+ sink.write(event);
449
+ }
450
+ }
451
+ child(bindings) {
452
+ const mergedBindings = { ...this.bindings, ...bindings };
453
+ return new _EnterpriseLogger(
454
+ this.service,
455
+ {
456
+ sinks: this.sinks,
457
+ middleware: this.middleware
458
+ },
459
+ mergedBindings
460
+ );
461
+ }
462
+ generateCorrelationId() {
463
+ return `corr-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
464
+ }
465
+ getHostname() {
466
+ try {
467
+ return hostname();
468
+ } catch {
469
+ return process.env.HOSTNAME || "unknown";
470
+ }
471
+ }
472
+ };
473
+
474
+ // src/logging/create-logger.ts
475
+ function createLogger(config) {
476
+ return new Logger(config);
477
+ }
478
+ function createSimpleLogger(service) {
479
+ return new Logger({
480
+ service,
481
+ profile: "simple" /* SIMPLE */
482
+ });
483
+ }
484
+ function createStructuredLogger(service, filePath) {
485
+ return new Logger({
486
+ service,
487
+ profile: "structured" /* STRUCTURED */,
488
+ filePath
489
+ });
490
+ }
491
+ function createEnterpriseLogger(service, options) {
492
+ return new Logger({
493
+ service,
494
+ profile: "enterprise" /* ENTERPRISE */,
495
+ ...options
496
+ });
497
+ }
498
+
499
+ // src/logging/middleware.ts
500
+ var RedactSecretsMiddleware = class {
501
+ secretKeys;
502
+ constructor(secretKeys) {
503
+ this.secretKeys = secretKeys ?? [
504
+ "password",
505
+ "apiKey",
506
+ "api_key",
507
+ "token",
508
+ "secret",
509
+ "authorization",
510
+ "auth",
511
+ "accessToken",
512
+ "access_token",
513
+ "refreshToken",
514
+ "refresh_token"
515
+ ];
516
+ }
517
+ process(event) {
518
+ const redacted = { ...event };
519
+ for (const key of this.secretKeys) {
520
+ if (key in redacted) {
521
+ redacted[key] = "[REDACTED]";
522
+ }
523
+ }
524
+ this.redactNested(redacted);
525
+ return redacted;
526
+ }
527
+ redactNested(obj) {
528
+ for (const [key, value] of Object.entries(obj)) {
529
+ if (this.secretKeys.includes(key)) {
530
+ obj[key] = "[REDACTED]";
531
+ } else if (value && typeof value === "object") {
532
+ if (Array.isArray(value)) {
533
+ this.redactArray(value);
534
+ } else {
535
+ this.redactNested(value);
536
+ }
537
+ }
538
+ }
539
+ }
540
+ redactArray(arr) {
541
+ for (let i = 0; i < arr.length; i++) {
542
+ const item = arr[i];
543
+ if (item && typeof item === "object") {
544
+ if (Array.isArray(item)) {
545
+ this.redactArray(item);
546
+ } else {
547
+ this.redactNested(item);
548
+ }
549
+ }
550
+ }
551
+ }
552
+ };
553
+ var AddFieldsMiddleware = class {
554
+ constructor(fields) {
555
+ this.fields = fields;
556
+ }
557
+ process(event) {
558
+ return {
559
+ ...event,
560
+ ...this.fields
561
+ };
562
+ }
563
+ };
564
+ var TransformMiddleware = class {
565
+ constructor(transformer) {
566
+ this.transformer = transformer;
567
+ }
568
+ process(event) {
569
+ return this.transformer(event);
570
+ }
571
+ };
572
+
573
+ // src/logging/index.ts
574
+ var VERSION = "0.1.0";
575
+
576
+ export { AddFieldsMiddleware, ConsoleSink, FileSink, Logger, LoggingProfile, NullSink, PolicyEnforcer, PolicyError, RedactSecretsMiddleware, TransformMiddleware, VERSION, createEnterpriseLogger, createLogger, createSimpleLogger, createStructuredLogger };
577
+ //# sourceMappingURL=index.js.map
578
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/logging/types.ts","../../src/logging/policy.ts","../../src/logging/sinks.ts","../../src/logging/logger.ts","../../src/logging/create-logger.ts","../../src/logging/middleware.ts","../../src/logging/index.ts"],"names":["LoggingProfile","parseYaml"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Core types for progressive logging interface\n */\n\n/**\n * Logging profile enum matching cross-language standard\n */\nexport enum LoggingProfile {\n /**\n * Basic logging for CLI tools and simple applications.\n *\n * Features:\n * - Console output only\n * - Basic severity levels (DEBUG, INFO, WARN, ERROR)\n * - Simple string formatting\n * - No correlation/middleware support\n */\n SIMPLE = 'simple',\n\n /**\n * Structured logging with basic enterprise features.\n *\n * Features:\n * - JSON output with core envelope fields\n * - Correlation and request IDs\n * - Basic middleware (redaction)\n * - Console and file sinks\n * - No throttling/advanced features\n */\n STRUCTURED = 'structured',\n\n /**\n * Full enterprise logging with all features.\n *\n * Features:\n * - Complete JSON envelope (20+ fields)\n * - Full correlation/trace support\n * - Complete middleware pipeline\n * - Multiple sink types with rotation\n * - Throttling and backpressure\n * - Performance optimization\n */\n ENTERPRISE = 'enterprise',\n\n /**\n * User-defined configuration with explicit parameters.\n *\n * Features:\n * - Full parameter control\n * - Custom sink/middleware combinations\n * - Advanced configuration options\n */\n CUSTOM = 'custom',\n}\n\n/**\n * Base logger configuration\n */\nexport interface BaseLoggerConfig {\n service: string;\n profile: LoggingProfile;\n policyFile?: string;\n}\n\n/**\n * Profile-specific configurations using discriminated unions\n */\nexport type LoggerConfig =\n | ({ profile: LoggingProfile.SIMPLE } & BaseLoggerConfig)\n | ({\n profile: LoggingProfile.STRUCTURED;\n filePath?: string;\n } & BaseLoggerConfig)\n | ({\n profile: LoggingProfile.ENTERPRISE;\n sinks?: Sink[];\n middleware?: Middleware[];\n } & BaseLoggerConfig)\n | ({\n profile: LoggingProfile.CUSTOM;\n customConfig: CustomLoggerConfig;\n } & BaseLoggerConfig);\n\n/**\n * Custom configuration for CUSTOM profile\n */\nexport interface CustomLoggerConfig {\n sinks: Sink[];\n middleware?: Middleware[];\n throttling?: ThrottlingConfig;\n envelope?: EnvelopeConfig;\n}\n\n/**\n * Log context for structured/enterprise profiles\n */\nexport interface LogContext {\n correlationId?: string;\n requestId?: string;\n userId?: string | number;\n traceId?: string;\n spanId?: string;\n [key: string]: unknown;\n}\n\n/**\n * Sink interface for log output destinations\n */\nexport interface Sink {\n write(event: LogEvent): void;\n}\n\n/**\n * Middleware interface for log processing pipeline\n */\nexport interface Middleware {\n process(event: LogEvent): LogEvent;\n}\n\n/**\n * Base log event interface\n */\nexport interface LogEvent {\n timestamp: string;\n service: string;\n severity: string;\n message: string;\n [key: string]: unknown;\n}\n\n/**\n * Enterprise log event with full envelope\n */\nexport interface EnterpriseLogEvent extends LogEvent {\n correlationId: string;\n requestId?: string;\n traceId?: string;\n spanId?: string;\n userId?: string | number;\n host?: string;\n pid?: number;\n version?: string;\n environment?: string;\n region?: string;\n zone?: string;\n instanceId?: string;\n cluster?: string;\n namespace?: string;\n deployment?: string;\n component?: string;\n module?: string;\n function?: string;\n line?: number;\n stackTrace?: string;\n}\n\n/**\n * Throttling configuration\n */\nexport interface ThrottlingConfig {\n maxPerSecond: number;\n maxPerMinute?: number;\n burstSize?: number;\n}\n\n/**\n * Envelope configuration\n */\nexport interface EnvelopeConfig {\n includeStackTrace?: boolean;\n includeHostInfo?: boolean;\n includeProcessInfo?: boolean;\n customFields?: Record<string, unknown>;\n}\n\n/**\n * Logger implementation interface\n */\nexport interface LoggerImplementation {\n debug(message: string, context?: LogContext): void;\n info(message: string, context?: LogContext): void;\n warn(message: string, context?: LogContext): void;\n error(message: string, error?: Error, context?: LogContext): void;\n child(bindings: Record<string, unknown>): LoggerImplementation;\n}\n\n/**\n * Logging policy definition\n */\nexport interface LoggingPolicy {\n allowedProfiles: LoggingProfile[];\n requiredProfiles?: Record<string, LoggingProfile[]>;\n environmentRules?: Record<string, LoggingProfile[]>;\n customRequirements?: Record<string, unknown>;\n}\n\n/**\n * Policy error thrown when profile not allowed\n */\nexport class PolicyError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'PolicyError';\n }\n}\n","/**\n * Policy enforcement for progressive logging profiles\n */\n\nimport { readFileSync } from 'node:fs';\nimport { parse as parseYaml } from 'yaml';\nimport { type LoggingPolicy, LoggingProfile, PolicyError } from './types.js';\n\n/**\n * Options for profile validation\n */\nexport interface PolicyValidationOptions {\n appType?: string;\n environment?: string;\n}\n\n/**\n * Policy enforcer for validating logging profiles against organizational policies\n */\nexport class PolicyEnforcer {\n private readonly policy: LoggingPolicy;\n private readonly policyFile: string;\n\n /**\n * Create a new policy enforcer\n *\n * @param policyFile - Path to YAML policy file\n * @throws {PolicyError} If policy file cannot be loaded or is invalid\n */\n constructor(policyFile: string) {\n this.policyFile = policyFile;\n this.policy = this.loadPolicy(policyFile);\n }\n\n /**\n * Validate if a profile is allowed under the current policy\n *\n * @param profile - The logging profile to validate\n * @param options - Optional validation context (appType, environment)\n * @returns true if profile is allowed, false otherwise\n *\n * @example\n * const enforcer = new PolicyEnforcer('/org/logging-policy.yaml');\n * if (enforcer.validateProfile(LoggingProfile.ENTERPRISE, { environment: 'production' })) {\n * // Profile is allowed\n * }\n */\n validateProfile(profile: LoggingProfile, options?: PolicyValidationOptions): boolean {\n // Check if profile is in allowed list\n if (!this.policy.allowedProfiles.includes(profile)) {\n return false;\n }\n\n // Check environment-specific rules if environment provided\n if (options?.environment && this.policy.environmentRules) {\n const envRules = this.policy.environmentRules[options.environment];\n if (envRules && !envRules.includes(profile)) {\n return false;\n }\n }\n\n // Check app-type specific requirements if appType provided\n if (options?.appType && this.policy.requiredProfiles) {\n const appTypeRules = this.policy.requiredProfiles[options.appType];\n if (appTypeRules && !appTypeRules.includes(profile)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Get the required profile for a given app type and environment\n *\n * @param appType - The application type\n * @param environment - The deployment environment\n * @returns The required logging profile\n * @throws {PolicyError} If no required profile found for app type\n *\n * @example\n * const enforcer = new PolicyEnforcer('/org/logging-policy.yaml');\n * const profile = enforcer.getRequiredProfile('api-server', 'production');\n * // Returns LoggingProfile.ENTERPRISE\n */\n getRequiredProfile(appType: string, environment: string): LoggingProfile {\n // Check required profiles by app type\n if (this.policy.requiredProfiles?.[appType]) {\n const profiles = this.policy.requiredProfiles[appType];\n\n // If environment rules exist, filter by environment\n if (this.policy.environmentRules?.[environment]) {\n const envProfiles = this.policy.environmentRules[environment];\n const validProfiles = profiles.filter((p) => envProfiles.includes(p));\n\n if (validProfiles.length > 0) {\n // Return most restrictive (highest in enum order)\n return this.getMostRestrictiveProfile(validProfiles);\n }\n }\n\n // Return most restrictive from app type requirements\n return this.getMostRestrictiveProfile(profiles);\n }\n\n throw new PolicyError(\n `No required profile found for app type \"${appType}\" in policy ${this.policyFile}`,\n );\n }\n\n /**\n * Get a helpful error message for policy validation failure\n *\n * @param profile - The profile that failed validation\n * @param options - The validation options used\n * @returns A descriptive error message\n */\n getValidationErrorMessage(profile: LoggingProfile, options?: PolicyValidationOptions): string {\n const parts: string[] = [`Profile \"${profile}\" not allowed by policy \"${this.policyFile}\".`];\n\n if (options?.environment) {\n parts.push(`Environment: ${options.environment}`);\n }\n\n if (options?.appType) {\n parts.push(`App Type: ${options.appType}`);\n }\n\n parts.push(`Allowed profiles: ${this.policy.allowedProfiles.join(', ')}`);\n\n if (options?.environment && this.policy.environmentRules?.[options.environment]) {\n const envProfiles = this.policy.environmentRules[options.environment];\n parts.push(`Environment \"${options.environment}\" allows: ${envProfiles.join(', ')}`);\n }\n\n if (options?.appType && this.policy.requiredProfiles?.[options.appType]) {\n const appProfiles = this.policy.requiredProfiles[options.appType];\n parts.push(`App type \"${options.appType}\" requires: ${appProfiles.join(', ')}`);\n }\n\n return parts.join(' | ');\n }\n\n /**\n * Load and parse the policy file\n *\n * @param policyFile - Path to YAML policy file\n * @returns Parsed logging policy\n * @throws {PolicyError} If file cannot be read or parsed\n */\n private loadPolicy(policyFile: string): LoggingPolicy {\n try {\n const content = readFileSync(policyFile, 'utf-8');\n const parsed = parseYaml(content) as LoggingPolicy;\n\n // Validate required fields\n if (!parsed.allowedProfiles || !Array.isArray(parsed.allowedProfiles)) {\n throw new PolicyError(\n `Invalid policy file ${policyFile}: missing or invalid \"allowedProfiles\" field`,\n );\n }\n\n // Ensure all profile values are valid\n const validProfiles = Object.values(LoggingProfile);\n for (const profile of parsed.allowedProfiles) {\n if (!validProfiles.includes(profile)) {\n throw new PolicyError(`Invalid policy file ${policyFile}: unknown profile \"${profile}\"`);\n }\n }\n\n // Validate requiredProfiles structure if present\n if (parsed.requiredProfiles) {\n if (typeof parsed.requiredProfiles !== 'object') {\n throw new PolicyError(\n `Invalid policy file ${policyFile}: \"requiredProfiles\" must be an object`,\n );\n }\n\n for (const [appType, profiles] of Object.entries(parsed.requiredProfiles)) {\n if (!Array.isArray(profiles)) {\n throw new PolicyError(\n `Invalid policy file ${policyFile}: requiredProfiles[\"${appType}\"] must be an array, got ${typeof profiles}. ` +\n 'Check YAML formatting - each profile should be on a new line with a hyphen.',\n );\n }\n\n for (const profile of profiles) {\n if (!validProfiles.includes(profile)) {\n throw new PolicyError(\n `Invalid policy file ${policyFile}: requiredProfiles[\"${appType}\"] contains unknown profile \"${profile}\"`,\n );\n }\n }\n }\n }\n\n // Validate environmentRules structure if present\n if (parsed.environmentRules) {\n if (typeof parsed.environmentRules !== 'object') {\n throw new PolicyError(\n `Invalid policy file ${policyFile}: \"environmentRules\" must be an object`,\n );\n }\n\n for (const [environment, profiles] of Object.entries(parsed.environmentRules)) {\n if (!Array.isArray(profiles)) {\n throw new PolicyError(\n `Invalid policy file ${policyFile}: environmentRules[\"${environment}\"] must be an array, got ${typeof profiles}. ` +\n 'Check YAML formatting - each profile should be on a new line with a hyphen.',\n );\n }\n\n for (const profile of profiles) {\n if (!validProfiles.includes(profile)) {\n throw new PolicyError(\n `Invalid policy file ${policyFile}: environmentRules[\"${environment}\"] contains unknown profile \"${profile}\"`,\n );\n }\n }\n }\n }\n\n return parsed;\n } catch (error) {\n if (error instanceof PolicyError) {\n throw error;\n }\n\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n throw new PolicyError(`Policy file not found: ${policyFile}`);\n }\n\n throw new PolicyError(\n `Failed to load policy file ${policyFile}: ${(error as Error).message}`,\n );\n }\n }\n\n /**\n * Get the most restrictive profile from a list\n * Order: CUSTOM > ENTERPRISE > STRUCTURED > SIMPLE\n *\n * @param profiles - List of profiles\n * @returns The most restrictive profile\n */\n private getMostRestrictiveProfile(profiles: LoggingProfile[]): LoggingProfile {\n const order = [\n LoggingProfile.CUSTOM,\n LoggingProfile.ENTERPRISE,\n LoggingProfile.STRUCTURED,\n LoggingProfile.SIMPLE,\n ];\n\n for (const profile of order) {\n if (profiles.includes(profile)) {\n return profile;\n }\n }\n\n // Fallback to first in list (shouldn't happen with valid input)\n return profiles[0];\n }\n}\n","/**\n * Sink implementations for log output destinations\n */\n\nimport { appendFileSync } from 'node:fs';\nimport type { LogEvent, Sink } from './types.js';\n\n/**\n * Console sink - writes log events to stdout as JSON\n */\nexport class ConsoleSink implements Sink {\n write(event: LogEvent): void {\n console.log(JSON.stringify(event));\n }\n}\n\n/**\n * File sink - appends log events to a file as JSON\n */\nexport class FileSink implements Sink {\n constructor(private readonly filePath: string) {}\n\n write(event: LogEvent): void {\n try {\n appendFileSync(this.filePath, `${JSON.stringify(event)}\\n`);\n } catch (error) {\n // Log to stderr if file write fails to avoid losing the log\n console.error(`FileSink: Failed to write to ${this.filePath}:`, (error as Error).message);\n // Fall back to console\n console.log(JSON.stringify(event));\n }\n }\n}\n\n/**\n * Null sink - discards all log events (useful for testing or disabling logging)\n */\nexport class NullSink implements Sink {\n write(_event: LogEvent): void {\n // Intentionally do nothing\n }\n}\n","/**\n * Progressive logging interface with profile-driven configuration\n */\n\nimport { hostname } from 'node:os';\nimport pino from 'pino';\nimport { PolicyEnforcer } from './policy.js';\nimport { ConsoleSink } from './sinks.js';\nimport {\n type LogContext,\n type LogEvent,\n type LoggerConfig,\n type LoggerImplementation,\n LoggingProfile,\n type Middleware,\n PolicyError,\n type Sink,\n} from './types.js';\n\n/**\n * Progressive logger with profile-based configuration\n */\nexport class Logger {\n private readonly service: string;\n private readonly profile: LoggingProfile;\n private readonly impl: LoggerImplementation;\n\n constructor(config: LoggerConfig) {\n this.service = config.service;\n this.profile = config.profile;\n\n // Validate against policy if provided\n if (config.policyFile) {\n this.validatePolicy(config.profile, config.policyFile);\n }\n\n // Create appropriate implementation\n this.impl = this.createImplementation(config);\n }\n\n debug(message: string, context?: LogContext): void {\n this.impl.debug(message, context);\n }\n\n info(message: string, context?: LogContext): void {\n this.impl.info(message, context);\n }\n\n warn(message: string, context?: LogContext): void {\n this.impl.warn(message, context);\n }\n\n error(message: string, error?: Error, context?: LogContext): void {\n this.impl.error(message, error, context);\n }\n\n child(bindings: Record<string, unknown>): Logger {\n const childLogger = Object.create(this);\n childLogger.impl = this.impl.child(bindings);\n return childLogger;\n }\n\n private validatePolicy(profile: LoggingProfile, policyFile: string): void {\n const enforcer = new PolicyEnforcer(policyFile);\n const appType = process.env.APP_TYPE;\n const environment = process.env.NODE_ENV;\n\n if (!enforcer.validateProfile(profile, { appType, environment })) {\n throw new PolicyError(enforcer.getValidationErrorMessage(profile, { appType, environment }));\n }\n }\n\n private createImplementation(config: LoggerConfig): LoggerImplementation {\n switch (config.profile) {\n case LoggingProfile.SIMPLE:\n return new SimpleLogger(config.service);\n case LoggingProfile.STRUCTURED:\n // biome-ignore lint/suspicious/noExplicitAny: Phase 1 - proper discriminated union handling in Phase 2\n return new StructuredLogger(config.service, (config as any).filePath);\n case LoggingProfile.ENTERPRISE:\n return new EnterpriseLogger(config.service, {\n // biome-ignore lint/suspicious/noExplicitAny: Phase 1 - proper discriminated union handling in Phase 2\n sinks: (config as any).sinks,\n // biome-ignore lint/suspicious/noExplicitAny: Phase 1 - proper discriminated union handling in Phase 2\n middleware: (config as any).middleware,\n });\n case LoggingProfile.CUSTOM:\n // biome-ignore lint/suspicious/noExplicitAny: Phase 1 - proper discriminated union handling in Phase 2\n return new EnterpriseLogger(config.service, (config as any).customConfig);\n }\n }\n}\n\n/**\n * Simple logger implementation using Pino\n */\nclass SimpleLogger implements LoggerImplementation {\n private readonly pino: pino.Logger;\n\n constructor(private readonly service: string) {\n this.pino = pino({\n name: service,\n level: 'debug',\n messageKey: 'message',\n base: undefined,\n timestamp: false,\n formatters: {\n level: (label: string) => ({ severity: label.toUpperCase() }),\n // biome-ignore lint/suspicious/noExplicitAny: Pino formatter requires any type\n log: (object: any) => {\n return {\n service: this.service,\n ...object,\n };\n },\n },\n });\n }\n\n debug(message: string, context?: LogContext): void {\n this.pino.debug(context, message);\n }\n\n info(message: string, context?: LogContext): void {\n this.pino.info(context, message);\n }\n\n warn(message: string, context?: LogContext): void {\n this.pino.warn(context, message);\n }\n\n error(message: string, error?: Error, context?: LogContext): void {\n const errorContext = {\n ...context,\n ...(error && { error: error.message, stack: error.stack }),\n };\n this.pino.error(errorContext, message);\n }\n\n child(bindings: Record<string, unknown>): LoggerImplementation {\n const childPino = this.pino.child(bindings);\n const childLogger = Object.create(this);\n childLogger.pino = childPino;\n return childLogger;\n }\n}\n\n/**\n * Structured logger implementation using Pino\n */\nclass StructuredLogger implements LoggerImplementation {\n private readonly pino: pino.Logger;\n\n constructor(\n private readonly service: string,\n readonly filePath?: string,\n ) {\n const config: pino.LoggerOptions = {\n name: service,\n level: 'debug',\n messageKey: 'message',\n base: undefined,\n timestamp: () => `,\"timestamp\":\"${new Date().toISOString()}\"`,\n formatters: {\n level: (label: string) => ({ severity: label.toUpperCase() }),\n // biome-ignore lint/suspicious/noExplicitAny: Pino formatter requires any type\n log: (object: any) => {\n return {\n service: this.service,\n ...object,\n };\n },\n },\n };\n\n // Configure output streams (console + optional file)\n if (filePath) {\n const streams: pino.StreamEntry[] = [\n { stream: process.stdout },\n { stream: pino.destination(filePath) },\n ];\n this.pino = pino(config, pino.multistream(streams));\n } else {\n this.pino = pino(config);\n }\n }\n\n debug(message: string, context?: LogContext): void {\n this.pino.debug(context, message);\n }\n\n info(message: string, context?: LogContext): void {\n this.pino.info(context, message);\n }\n\n warn(message: string, context?: LogContext): void {\n this.pino.warn(context, message);\n }\n\n error(message: string, error?: Error, context?: LogContext): void {\n const errorContext = {\n ...context,\n ...(error && { error: error.message, stack: error.stack }),\n };\n this.pino.error(errorContext, message);\n }\n\n child(bindings: Record<string, unknown>): LoggerImplementation {\n const childPino = this.pino.child(bindings);\n const childLogger = Object.create(this);\n childLogger.pino = childPino;\n return childLogger;\n }\n}\n\n/**\n * Enterprise logger implementation using Pino\n */\nclass EnterpriseLogger implements LoggerImplementation {\n private readonly sinks: Sink[];\n private readonly middleware: Middleware[];\n private readonly bindings: Record<string, unknown>;\n\n constructor(\n private readonly service: string,\n // biome-ignore lint/suspicious/noExplicitAny: Phase 1 - proper discriminated union handling in Phase 2\n config?: any,\n bindings?: Record<string, unknown>,\n ) {\n this.sinks = config?.sinks ?? [new ConsoleSink()];\n this.middleware = config?.middleware ?? [];\n this.bindings = bindings ?? {};\n }\n\n debug(message: string, context?: LogContext): void {\n this.logWithPipeline('DEBUG', message, context);\n }\n\n info(message: string, context?: LogContext): void {\n this.logWithPipeline('INFO', message, context);\n }\n\n warn(message: string, context?: LogContext): void {\n this.logWithPipeline('WARN', message, context);\n }\n\n error(message: string, error?: Error, context?: LogContext): void {\n const errorContext = {\n ...context,\n ...(error && {\n error: error.message,\n stack: error.stack,\n errorType: error.constructor.name,\n }),\n };\n this.logWithPipeline('ERROR', message, errorContext);\n }\n\n private logWithPipeline(severity: string, message: string, context?: LogContext): void {\n // Create enterprise log event\n let event: LogEvent = {\n timestamp: new Date().toISOString(),\n service: this.service,\n severity,\n message,\n correlationId: context?.correlationId ?? this.generateCorrelationId(),\n host: this.getHostname(),\n pid: process.pid,\n ...this.bindings,\n ...context,\n };\n\n // Apply middleware pipeline\n for (const mw of this.middleware) {\n event = mw.process(event);\n }\n\n // Emit to all sinks\n for (const sink of this.sinks) {\n sink.write(event);\n }\n }\n\n child(bindings: Record<string, unknown>): LoggerImplementation {\n const mergedBindings = { ...this.bindings, ...bindings };\n return new EnterpriseLogger(\n this.service,\n {\n sinks: this.sinks,\n middleware: this.middleware,\n },\n mergedBindings,\n );\n }\n\n private generateCorrelationId(): string {\n // Simple correlation ID generation - will be enhanced in Phase 2\n return `corr-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n }\n\n private getHostname(): string {\n try {\n return hostname();\n } catch {\n return process.env.HOSTNAME || 'unknown';\n }\n }\n}\n","/**\n * Factory function for creating loggers with progressive interface\n */\n\nimport { Logger } from './logger.js';\nimport { type LoggerConfig, LoggingProfile } from './types.js';\n\n/**\n * Create a logger with the specified configuration\n *\n * @param config - Logger configuration\n * @returns Configured logger instance\n *\n * @example\n * // Simple logger for CLI\n * const logger = createLogger({\n * service: 'mycli',\n * profile: LoggingProfile.SIMPLE\n * });\n *\n * @example\n * // Structured logger with file output\n * const logger = createLogger({\n * service: 'myapp',\n * profile: LoggingProfile.STRUCTURED,\n * filePath: '/var/log/app.log'\n * });\n */\nexport function createLogger(config: LoggerConfig): Logger {\n return new Logger(config);\n}\n\n/**\n * Create a simple logger for CLI tools\n *\n * @param service - Service name\n * @returns Simple logger instance\n */\nexport function createSimpleLogger(service: string): Logger {\n return new Logger({\n service,\n profile: LoggingProfile.SIMPLE,\n });\n}\n\n/**\n * Create a structured logger with JSON output\n *\n * @param service - Service name\n * @param filePath - Optional file path for log output\n * @returns Structured logger instance\n */\nexport function createStructuredLogger(service: string, filePath?: string): Logger {\n return new Logger({\n service,\n profile: LoggingProfile.STRUCTURED,\n filePath,\n });\n}\n\n/**\n * Create an enterprise logger with full features\n *\n * @param service - Service name\n * @param options - Enterprise options (sinks, middleware, etc.)\n * @returns Enterprise logger instance\n */\nexport function createEnterpriseLogger(\n service: string,\n options?: {\n // biome-ignore lint/suspicious/noExplicitAny: Phase 1 - Sink type to be properly defined in Phase 2\n sinks?: any[];\n // biome-ignore lint/suspicious/noExplicitAny: Phase 1 - Middleware type to be properly defined in Phase 2\n middleware?: any[];\n },\n): Logger {\n return new Logger({\n service,\n profile: LoggingProfile.ENTERPRISE,\n ...options,\n });\n}\n","/**\n * Middleware implementations for log processing pipeline\n */\n\nimport type { LogEvent, Middleware } from './types.js';\n\n/**\n * Redact secrets middleware - removes sensitive data from log events\n */\nexport class RedactSecretsMiddleware implements Middleware {\n private readonly secretKeys: string[];\n\n constructor(secretKeys?: string[]) {\n this.secretKeys = secretKeys ?? [\n 'password',\n 'apiKey',\n 'api_key',\n 'token',\n 'secret',\n 'authorization',\n 'auth',\n 'accessToken',\n 'access_token',\n 'refreshToken',\n 'refresh_token',\n ];\n }\n\n process(event: LogEvent): LogEvent {\n const redacted = { ...event };\n\n // Redact top-level secret fields\n for (const key of this.secretKeys) {\n if (key in redacted) {\n redacted[key] = '[REDACTED]';\n }\n }\n\n // Recursively redact nested objects\n this.redactNested(redacted);\n\n return redacted;\n }\n\n private redactNested(obj: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(obj)) {\n if (this.secretKeys.includes(key)) {\n obj[key] = '[REDACTED]';\n } else if (value && typeof value === 'object') {\n if (Array.isArray(value)) {\n // Recursively redact array elements\n this.redactArray(value);\n } else {\n // Recursively redact object properties\n this.redactNested(value as Record<string, unknown>);\n }\n }\n }\n }\n\n private redactArray(arr: unknown[]): void {\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n if (item && typeof item === 'object') {\n if (Array.isArray(item)) {\n // Handle nested arrays\n this.redactArray(item);\n } else {\n // Handle objects within arrays\n this.redactNested(item as Record<string, unknown>);\n }\n }\n }\n }\n}\n\n/**\n * Add fields middleware - enriches log events with additional context\n */\nexport class AddFieldsMiddleware implements Middleware {\n constructor(private readonly fields: Record<string, unknown>) {}\n\n process(event: LogEvent): LogEvent {\n return {\n ...event,\n ...this.fields,\n };\n }\n}\n\n/**\n * Transform middleware - applies a transformation function to log events\n */\nexport class TransformMiddleware implements Middleware {\n constructor(private readonly transformer: (event: LogEvent) => LogEvent) {}\n\n process(event: LogEvent): LogEvent {\n return this.transformer(event);\n }\n}\n","/**\n * Logging module - progressive logging interface with policy enforcement\n *\n * Provides profile-based logging from simple CLI to enterprise-scale applications\n */\n\nexport const VERSION = '0.1.0';\n\n// Factory functions\nexport {\n createEnterpriseLogger,\n createLogger,\n createSimpleLogger,\n createStructuredLogger,\n} from './create-logger.js';\n// Core exports\nexport { Logger } from './logger.js';\nexport {\n AddFieldsMiddleware,\n RedactSecretsMiddleware,\n TransformMiddleware,\n} from './middleware.js';\nexport { PolicyEnforcer } from './policy.js';\nexport { ConsoleSink, FileSink, NullSink } from './sinks.js';\nexport {\n type CustomLoggerConfig,\n type LogContext,\n type LogEvent,\n type LoggerConfig,\n type LoggingPolicy,\n LoggingProfile,\n type Middleware,\n PolicyError,\n type Sink,\n} from './types.js';\n"]}