@b9g/shovel 0.2.0-beta.10 → 0.2.0-beta.11

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/chunk-CSH7M4MK.js DELETED
@@ -1,861 +0,0 @@
1
- // src/utils/project.ts
2
- import { existsSync, readFileSync } from "fs";
3
- import { dirname, join } from "path";
4
- function findProjectRoot(startDir = process.cwd()) {
5
- let dir = startDir;
6
- while (dir !== dirname(dir)) {
7
- if (existsSync(join(dir, "package.json"))) {
8
- return dir;
9
- }
10
- dir = dirname(dir);
11
- }
12
- return startDir;
13
- }
14
- function findWorkspaceRoot(startDir = process.cwd()) {
15
- let dir = startDir;
16
- while (dir !== dirname(dir)) {
17
- const packageJsonPath = join(dir, "package.json");
18
- if (existsSync(packageJsonPath)) {
19
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
20
- if (packageJson.workspaces) {
21
- return dir;
22
- }
23
- }
24
- dir = dirname(dir);
25
- }
26
- return null;
27
- }
28
- function getNodeModulesPath(startDir) {
29
- return join(findProjectRoot(startDir), "node_modules");
30
- }
31
-
32
- // src/utils/config.ts
33
- import { readFileSync as readFileSync2 } from "fs";
34
- var DEFAULTS = {
35
- SERVER: {
36
- PORT: 3e3,
37
- HOST: "localhost"
38
- },
39
- WORKERS: 1
40
- // Single worker for development - user can override with --workers flag
41
- };
42
- var EXPRESSION_PATTERN = /(\|\||&&|===|!==|==|!=|[?:!]|^[A-Z][A-Z0-9_]*$)/;
43
- function getEnv() {
44
- if (typeof import.meta !== "undefined" && import.meta.env) {
45
- return import.meta.env;
46
- }
47
- if (typeof process !== "undefined" && process.env) {
48
- return process.env;
49
- }
50
- return {};
51
- }
52
- var Tokenizer = class {
53
- #input;
54
- #pos;
55
- constructor(input) {
56
- this.#input = input;
57
- this.#pos = 0;
58
- }
59
- #peek() {
60
- return this.#input[this.#pos] || "";
61
- }
62
- #advance() {
63
- return this.#input[this.#pos++] || "";
64
- }
65
- #skipWhitespace() {
66
- while (/\s/.test(this.#peek())) {
67
- this.#advance();
68
- }
69
- }
70
- next() {
71
- this.#skipWhitespace();
72
- const start = this.#pos;
73
- const ch = this.#peek();
74
- if (!ch) {
75
- return { type: "EOF" /* EOF */, value: null, start, end: start };
76
- }
77
- if (ch === '"') {
78
- this.#advance();
79
- let value = "";
80
- while (this.#peek() && this.#peek() !== '"') {
81
- if (this.#peek() === "\\") {
82
- this.#advance();
83
- const next = this.#advance();
84
- if (next === "n")
85
- value += "\n";
86
- else if (next === "t")
87
- value += " ";
88
- else
89
- value += next;
90
- } else {
91
- value += this.#advance();
92
- }
93
- }
94
- if (this.#peek() !== '"') {
95
- throw new Error(`Unterminated string at position ${start}`);
96
- }
97
- this.#advance();
98
- return { type: "STRING" /* STRING */, value, start, end: this.#pos };
99
- }
100
- if (/\d/.test(ch)) {
101
- let value = "";
102
- while (/\d/.test(this.#peek())) {
103
- value += this.#advance();
104
- }
105
- return {
106
- type: "NUMBER" /* NUMBER */,
107
- value: parseInt(value, 10),
108
- start,
109
- end: this.#pos
110
- };
111
- }
112
- if (ch === "=" && this.#input[this.#pos + 1] === "=" && this.#input[this.#pos + 2] === "=") {
113
- this.#pos += 3;
114
- return { type: "===" /* EQ_STRICT */, value: "===", start, end: this.#pos };
115
- }
116
- if (ch === "!" && this.#input[this.#pos + 1] === "=" && this.#input[this.#pos + 2] === "=") {
117
- this.#pos += 3;
118
- return { type: "!==" /* NE_STRICT */, value: "!==", start, end: this.#pos };
119
- }
120
- if (ch === "=" && this.#input[this.#pos + 1] === "=") {
121
- this.#pos += 2;
122
- return { type: "==" /* EQ */, value: "==", start, end: this.#pos };
123
- }
124
- if (ch === "!" && this.#input[this.#pos + 1] === "=") {
125
- this.#pos += 2;
126
- return { type: "!=" /* NE */, value: "!=", start, end: this.#pos };
127
- }
128
- if (ch === "|" && this.#input[this.#pos + 1] === "|") {
129
- this.#pos += 2;
130
- return { type: "||" /* OR */, value: "||", start, end: this.#pos };
131
- }
132
- if (ch === "&" && this.#input[this.#pos + 1] === "&") {
133
- this.#pos += 2;
134
- return { type: "&&" /* AND */, value: "&&", start, end: this.#pos };
135
- }
136
- if (ch === "?") {
137
- this.#advance();
138
- return { type: "?" /* QUESTION */, value: "?", start, end: this.#pos };
139
- }
140
- if (ch === "!") {
141
- this.#advance();
142
- return { type: "!" /* NOT */, value: "!", start, end: this.#pos };
143
- }
144
- if (ch === "(") {
145
- this.#advance();
146
- return { type: "(" /* LPAREN */, value: "(", start, end: this.#pos };
147
- }
148
- if (ch === ")") {
149
- this.#advance();
150
- return { type: ")" /* RPAREN */, value: ")", start, end: this.#pos };
151
- }
152
- if (ch === ":") {
153
- const next = this.#input[this.#pos + 1];
154
- if (next !== "/" && !/\d/.test(next)) {
155
- this.#advance();
156
- return { type: ":" /* COLON */, value: ":", start, end: this.#pos };
157
- }
158
- }
159
- if (/\S/.test(ch) && !/[?!()=|&]/.test(ch)) {
160
- let value = "";
161
- while (/\S/.test(this.#peek()) && !/[?!()=|&]/.test(this.#peek())) {
162
- if (this.#peek() === ":") {
163
- const next = this.#input[this.#pos + 1];
164
- if (next !== "/" && !/\d/.test(next)) {
165
- break;
166
- }
167
- }
168
- value += this.#advance();
169
- }
170
- if (value === "true")
171
- return { type: "TRUE" /* TRUE */, value: true, start, end: this.#pos };
172
- if (value === "false")
173
- return { type: "FALSE" /* FALSE */, value: false, start, end: this.#pos };
174
- if (value === "null")
175
- return { type: "NULL" /* NULL */, value: null, start, end: this.#pos };
176
- if (value === "undefined")
177
- return {
178
- type: "UNDEFINED" /* UNDEFINED */,
179
- value: void 0,
180
- start,
181
- end: this.#pos
182
- };
183
- return { type: "IDENTIFIER" /* IDENTIFIER */, value, start, end: this.#pos };
184
- }
185
- throw new Error(`Unexpected character '${ch}' at position ${start}`);
186
- }
187
- };
188
- var Parser = class {
189
- #tokens;
190
- #pos;
191
- #env;
192
- #strict;
193
- constructor(input, env, strict) {
194
- const tokenizer = new Tokenizer(input);
195
- this.#tokens = [];
196
- let token;
197
- do {
198
- token = tokenizer.next();
199
- this.#tokens.push(token);
200
- } while (token.type !== "EOF" /* EOF */);
201
- this.#pos = 0;
202
- this.#env = env;
203
- this.#strict = strict;
204
- }
205
- #peek() {
206
- return this.#tokens[this.#pos];
207
- }
208
- #advance() {
209
- return this.#tokens[this.#pos++];
210
- }
211
- #expect(type) {
212
- const token = this.#peek();
213
- if (token.type !== type) {
214
- throw new Error(
215
- `Expected ${type} but got ${token.type} at position ${token.start}`
216
- );
217
- }
218
- return this.#advance();
219
- }
220
- parse() {
221
- const result = this.#parseExpr();
222
- this.#expect("EOF" /* EOF */);
223
- return result;
224
- }
225
- // Expr := Ternary
226
- #parseExpr() {
227
- return this.#parseTernary();
228
- }
229
- // Ternary := LogicalOr ('?' Expr ':' Expr)?
230
- #parseTernary() {
231
- let left = this.#parseLogicalOr();
232
- if (this.#peek().type === "?" /* QUESTION */) {
233
- this.#advance();
234
- const trueBranch = this.#parseExpr();
235
- this.#expect(":" /* COLON */);
236
- const falseBranch = this.#parseExpr();
237
- return left ? trueBranch : falseBranch;
238
- }
239
- return left;
240
- }
241
- // LogicalOr := LogicalAnd ('||' LogicalAnd)*
242
- #parseLogicalOr() {
243
- let left = this.#parseLogicalAnd();
244
- while (this.#peek().type === "||" /* OR */) {
245
- this.#advance();
246
- const right = this.#parseLogicalAnd();
247
- left = left || right;
248
- }
249
- return left;
250
- }
251
- // LogicalAnd := Equality ('&&' Equality)*
252
- #parseLogicalAnd() {
253
- let left = this.#parseEquality();
254
- while (this.#peek().type === "&&" /* AND */) {
255
- this.#advance();
256
- const right = this.#parseEquality();
257
- left = left && right;
258
- }
259
- return left;
260
- }
261
- // Equality := Unary (('===' | '!==' | '==' | '!=') Unary)*
262
- #parseEquality() {
263
- let left = this.#parseUnary();
264
- while (true) {
265
- const token = this.#peek();
266
- if (token.type === "===" /* EQ_STRICT */) {
267
- this.#advance();
268
- const right = this.#parseUnary();
269
- left = left === right;
270
- } else if (token.type === "!==" /* NE_STRICT */) {
271
- this.#advance();
272
- const right = this.#parseUnary();
273
- left = left !== right;
274
- } else if (token.type === "==" /* EQ */) {
275
- this.#advance();
276
- const right = this.#parseUnary();
277
- left = left == right;
278
- } else if (token.type === "!=" /* NE */) {
279
- this.#advance();
280
- const right = this.#parseUnary();
281
- left = left != right;
282
- } else {
283
- break;
284
- }
285
- }
286
- return left;
287
- }
288
- // Unary := '!' Unary | Primary
289
- #parseUnary() {
290
- if (this.#peek().type === "!" /* NOT */) {
291
- this.#advance();
292
- return !this.#parseUnary();
293
- }
294
- return this.#parsePrimary();
295
- }
296
- // Primary := EnvVar | Literal | '(' Expr ')'
297
- #parsePrimary() {
298
- const token = this.#peek();
299
- if (token.type === "(" /* LPAREN */) {
300
- this.#advance();
301
- const value = this.#parseExpr();
302
- this.#expect(")" /* RPAREN */);
303
- return value;
304
- }
305
- if (token.type === "STRING" /* STRING */) {
306
- this.#advance();
307
- return token.value;
308
- }
309
- if (token.type === "NUMBER" /* NUMBER */) {
310
- this.#advance();
311
- return token.value;
312
- }
313
- if (token.type === "TRUE" /* TRUE */) {
314
- this.#advance();
315
- return true;
316
- }
317
- if (token.type === "FALSE" /* FALSE */) {
318
- this.#advance();
319
- return false;
320
- }
321
- if (token.type === "NULL" /* NULL */) {
322
- this.#advance();
323
- return null;
324
- }
325
- if (token.type === "UNDEFINED" /* UNDEFINED */) {
326
- this.#advance();
327
- return void 0;
328
- }
329
- if (token.type === "IDENTIFIER" /* IDENTIFIER */) {
330
- this.#advance();
331
- const name = token.value;
332
- if (/^[A-Z][A-Z0-9_]*$/.test(name)) {
333
- const value = this.#env[name];
334
- if (this.#strict && value === void 0) {
335
- throw new Error(
336
- `Undefined environment variable: ${name}
337
- Fix:
338
- 1. Set the env var: export ${name}=value
339
- 2. Add a fallback: ${name} || defaultValue
340
- 3. Add null check: ${name} == null ? ... : ...
341
- 4. Use empty string for falsy: export ${name}=""`
342
- );
343
- }
344
- if (typeof value === "string" && /^\d+$/.test(value)) {
345
- return parseInt(value, 10);
346
- }
347
- return value;
348
- }
349
- return name;
350
- }
351
- throw new Error(
352
- `Unexpected token ${token.type} at position ${token.start}`
353
- );
354
- }
355
- };
356
- function parseConfigExpr(expr, env = getEnv(), options = {}) {
357
- const strict = options.strict !== false;
358
- try {
359
- const parser = new Parser(expr, env, strict);
360
- return parser.parse();
361
- } catch (error) {
362
- throw new Error(
363
- `Invalid config expression: ${expr}
364
- Error: ${error instanceof Error ? error.message : String(error)}`
365
- );
366
- }
367
- }
368
- function processConfigValue(value, env = getEnv(), options = {}) {
369
- if (typeof value === "string") {
370
- if (EXPRESSION_PATTERN.test(value)) {
371
- return parseConfigExpr(value, env, options);
372
- }
373
- return value;
374
- }
375
- if (Array.isArray(value)) {
376
- return value.map((item) => processConfigValue(item, env, options));
377
- }
378
- if (value !== null && typeof value === "object") {
379
- const processed = {};
380
- for (const [key, val] of Object.entries(value)) {
381
- processed[key] = processConfigValue(val, env, options);
382
- }
383
- return processed;
384
- }
385
- return value;
386
- }
387
- var BUILTIN_CACHE_PROVIDERS = {
388
- memory: "@b9g/cache/memory.js",
389
- redis: "@b9g/cache-redis"
390
- };
391
- var BUILTIN_DIRECTORY_PROVIDERS = {
392
- node: "@b9g/filesystem/node.js",
393
- memory: "@b9g/filesystem/memory.js",
394
- s3: "@b9g/filesystem-s3"
395
- };
396
- var BUILTIN_SINK_PROVIDERS = {
397
- console: { module: "@logtape/logtape", factory: "getConsoleSink" },
398
- file: { module: "@logtape/file", factory: "getFileSink" },
399
- rotating: { module: "@logtape/file", factory: "getRotatingFileSink" },
400
- "stream-file": { module: "@logtape/file", factory: "getStreamFileSink" },
401
- otel: { module: "@logtape/otel", factory: "getOpenTelemetrySink" },
402
- sentry: { module: "@logtape/sentry", factory: "getSentrySink" },
403
- syslog: { module: "@logtape/syslog", factory: "getSyslogSink" },
404
- cloudwatch: {
405
- module: "@logtape/cloudwatch-logs",
406
- factory: "getCloudWatchLogsSink"
407
- }
408
- };
409
- var CodeGenerator = class {
410
- #tokens;
411
- #pos;
412
- constructor(input) {
413
- const tokenizer = new Tokenizer(input);
414
- this.#tokens = [];
415
- let token;
416
- do {
417
- token = tokenizer.next();
418
- this.#tokens.push(token);
419
- } while (token.type !== "EOF" /* EOF */);
420
- this.#pos = 0;
421
- }
422
- #peek() {
423
- return this.#tokens[this.#pos];
424
- }
425
- #advance() {
426
- return this.#tokens[this.#pos++];
427
- }
428
- #expect(type) {
429
- const token = this.#peek();
430
- if (token.type !== type) {
431
- throw new Error(
432
- `Expected ${type} but got ${token.type} at position ${token.start}`
433
- );
434
- }
435
- return this.#advance();
436
- }
437
- generate() {
438
- const result = this.#generateExpr();
439
- this.#expect("EOF" /* EOF */);
440
- return result;
441
- }
442
- #generateExpr() {
443
- return this.#generateTernary();
444
- }
445
- #generateTernary() {
446
- let left = this.#generateLogicalOr();
447
- if (this.#peek().type === "?" /* QUESTION */) {
448
- this.#advance();
449
- const trueBranch = this.#generateExpr();
450
- this.#expect(":" /* COLON */);
451
- const falseBranch = this.#generateExpr();
452
- return `(${left} ? ${trueBranch} : ${falseBranch})`;
453
- }
454
- return left;
455
- }
456
- #generateLogicalOr() {
457
- let left = this.#generateLogicalAnd();
458
- while (this.#peek().type === "||" /* OR */) {
459
- this.#advance();
460
- const right = this.#generateLogicalAnd();
461
- left = `(${left} || ${right})`;
462
- }
463
- return left;
464
- }
465
- #generateLogicalAnd() {
466
- let left = this.#generateEquality();
467
- while (this.#peek().type === "&&" /* AND */) {
468
- this.#advance();
469
- const right = this.#generateEquality();
470
- left = `(${left} && ${right})`;
471
- }
472
- return left;
473
- }
474
- #generateEquality() {
475
- let left = this.#generateUnary();
476
- while (true) {
477
- const token = this.#peek();
478
- if (token.type === "===" /* EQ_STRICT */) {
479
- this.#advance();
480
- const right = this.#generateUnary();
481
- left = `(${left} === ${right})`;
482
- } else if (token.type === "!==" /* NE_STRICT */) {
483
- this.#advance();
484
- const right = this.#generateUnary();
485
- left = `(${left} !== ${right})`;
486
- } else if (token.type === "==" /* EQ */) {
487
- this.#advance();
488
- const right = this.#generateUnary();
489
- left = `(${left} == ${right})`;
490
- } else if (token.type === "!=" /* NE */) {
491
- this.#advance();
492
- const right = this.#generateUnary();
493
- left = `(${left} != ${right})`;
494
- } else {
495
- break;
496
- }
497
- }
498
- return left;
499
- }
500
- #generateUnary() {
501
- if (this.#peek().type === "!" /* NOT */) {
502
- this.#advance();
503
- return `!${this.#generateUnary()}`;
504
- }
505
- return this.#generatePrimary();
506
- }
507
- #generatePrimary() {
508
- const token = this.#peek();
509
- if (token.type === "(" /* LPAREN */) {
510
- this.#advance();
511
- const value = this.#generateExpr();
512
- this.#expect(")" /* RPAREN */);
513
- return `(${value})`;
514
- }
515
- if (token.type === "STRING" /* STRING */) {
516
- this.#advance();
517
- return JSON.stringify(token.value);
518
- }
519
- if (token.type === "NUMBER" /* NUMBER */) {
520
- this.#advance();
521
- return String(token.value);
522
- }
523
- if (token.type === "TRUE" /* TRUE */) {
524
- this.#advance();
525
- return "true";
526
- }
527
- if (token.type === "FALSE" /* FALSE */) {
528
- this.#advance();
529
- return "false";
530
- }
531
- if (token.type === "NULL" /* NULL */) {
532
- this.#advance();
533
- return "null";
534
- }
535
- if (token.type === "UNDEFINED" /* UNDEFINED */) {
536
- this.#advance();
537
- return "undefined";
538
- }
539
- if (token.type === "IDENTIFIER" /* IDENTIFIER */) {
540
- this.#advance();
541
- const name = token.value;
542
- if (/^[A-Z][A-Z0-9_]*$/.test(name)) {
543
- return `process.env.${name}`;
544
- }
545
- return JSON.stringify(name);
546
- }
547
- throw new Error(
548
- `Unexpected token ${token.type} at position ${token.start}`
549
- );
550
- }
551
- };
552
- function exprToCode(expr) {
553
- if (EXPRESSION_PATTERN.test(expr)) {
554
- try {
555
- const generator = new CodeGenerator(expr);
556
- return generator.generate();
557
- } catch (error) {
558
- throw new Error(
559
- `Invalid config expression: ${expr}
560
- Error: ${error instanceof Error ? error.message : String(error)}`
561
- );
562
- }
563
- }
564
- return JSON.stringify(expr);
565
- }
566
- function valueToCode(value) {
567
- if (typeof value === "string") {
568
- return exprToCode(value);
569
- }
570
- if (typeof value === "number" || typeof value === "boolean") {
571
- return JSON.stringify(value);
572
- }
573
- if (value === null) {
574
- return "null";
575
- }
576
- if (value === void 0) {
577
- return "undefined";
578
- }
579
- if (Array.isArray(value)) {
580
- const items = value.map((item) => valueToCode(item));
581
- return `[${items.join(", ")}]`;
582
- }
583
- if (typeof value === "object") {
584
- const entries = Object.entries(value).map(
585
- ([key, val]) => `${JSON.stringify(key)}: ${valueToCode(val)}`
586
- );
587
- return `{${entries.join(", ")}}`;
588
- }
589
- return JSON.stringify(value);
590
- }
591
- function sanitizeVarName(pattern) {
592
- return pattern.replace(/\*/g, "default").replace(/[^a-zA-Z0-9_]/g, "_").replace(/^(\d)/, "_$1");
593
- }
594
- function generateConfigModule(rawConfig, env = getEnv()) {
595
- const imports = [];
596
- const providerRefs = {};
597
- const sinkFactoryRefs = /* @__PURE__ */ new Map();
598
- let sinkCounter = 0;
599
- const processProvider = (expr, type, pattern) => {
600
- if (!expr)
601
- return null;
602
- const provider = parseConfigExpr(expr, env, { strict: false });
603
- if (!provider || provider === "memory") {
604
- return null;
605
- }
606
- const builtinMap = type === "cache" ? BUILTIN_CACHE_PROVIDERS : BUILTIN_DIRECTORY_PROVIDERS;
607
- const modulePath = builtinMap[provider] || provider;
608
- const varName = `${type}_${sanitizeVarName(pattern)}`;
609
- imports.push(`import * as ${varName} from ${JSON.stringify(modulePath)};`);
610
- providerRefs[`${type}.${pattern}`] = varName;
611
- return varName;
612
- };
613
- const processSinkProvider = (providerName) => {
614
- const builtin = BUILTIN_SINK_PROVIDERS[providerName];
615
- const modulePath = builtin?.module || providerName;
616
- const factoryName = builtin?.factory || "default";
617
- const key = `${modulePath}:${factoryName}`;
618
- if (sinkFactoryRefs.has(key)) {
619
- return sinkFactoryRefs.get(key);
620
- }
621
- const varName = `sink_${sinkCounter++}`;
622
- sinkFactoryRefs.set(key, varName);
623
- if (factoryName === "default") {
624
- imports.push(`import ${varName} from ${JSON.stringify(modulePath)};`);
625
- } else {
626
- imports.push(
627
- `import { ${factoryName} as ${varName} } from ${JSON.stringify(modulePath)};`
628
- );
629
- }
630
- return varName;
631
- };
632
- const collectSinks = (sinks) => {
633
- if (!sinks)
634
- return;
635
- for (const sink of sinks) {
636
- if (sink.provider) {
637
- processSinkProvider(String(sink.provider));
638
- }
639
- }
640
- };
641
- for (const [pattern, cfg] of Object.entries(rawConfig.caches || {})) {
642
- if (cfg.provider) {
643
- processProvider(String(cfg.provider), "cache", pattern);
644
- }
645
- }
646
- for (const [pattern, cfg] of Object.entries(rawConfig.directories || {})) {
647
- if (cfg.provider) {
648
- processProvider(String(cfg.provider), "directory", pattern);
649
- }
650
- }
651
- if (rawConfig.logging) {
652
- collectSinks(rawConfig.logging.sinks);
653
- if (rawConfig.logging.categories) {
654
- for (const categoryConfig of Object.values(
655
- rawConfig.logging.categories
656
- )) {
657
- collectSinks(categoryConfig.sinks);
658
- }
659
- }
660
- } else {
661
- processSinkProvider("console");
662
- }
663
- const generateConfigCode = () => {
664
- const lines = [];
665
- lines.push("{");
666
- if (rawConfig.platform !== void 0) {
667
- lines.push(` platform: ${valueToCode(rawConfig.platform)},`);
668
- }
669
- if (rawConfig.port !== void 0) {
670
- lines.push(` port: ${valueToCode(rawConfig.port)},`);
671
- } else {
672
- lines.push(
673
- ` port: process.env.PORT ? parseInt(process.env.PORT, 10) : 3000,`
674
- );
675
- }
676
- if (rawConfig.host !== void 0) {
677
- lines.push(` host: ${valueToCode(rawConfig.host)},`);
678
- } else {
679
- lines.push(` host: process.env.HOST || "localhost",`);
680
- }
681
- if (rawConfig.workers !== void 0) {
682
- lines.push(` workers: ${valueToCode(rawConfig.workers)},`);
683
- } else {
684
- lines.push(
685
- ` workers: process.env.WORKERS ? parseInt(process.env.WORKERS, 10) : 1,`
686
- );
687
- }
688
- const generateSinksCode = (sinks) => {
689
- const sinkLines = [];
690
- for (const sink of sinks) {
691
- const providerName = String(sink.provider);
692
- const builtin = BUILTIN_SINK_PROVIDERS[providerName];
693
- const modulePath = builtin?.module || providerName;
694
- const factoryName = builtin?.factory || "default";
695
- const key = `${modulePath}:${factoryName}`;
696
- const factoryVar = sinkFactoryRefs.get(key);
697
- const sinkProps = [];
698
- for (const [k, v] of Object.entries(sink)) {
699
- sinkProps.push(`${k}: ${valueToCode(v)}`);
700
- }
701
- if (factoryVar) {
702
- sinkProps.push(`factory: ${factoryVar}`);
703
- }
704
- sinkLines.push(`{${sinkProps.join(", ")}}`);
705
- }
706
- return `[${sinkLines.join(", ")}]`;
707
- };
708
- if (rawConfig.logging) {
709
- lines.push(" logging: {");
710
- lines.push(
711
- ` level: ${rawConfig.logging.level ? valueToCode(rawConfig.logging.level) : 'process.env.LOG_LEVEL || "info"'},`
712
- );
713
- const defaultSinks = rawConfig.logging.sinks || [{ provider: "console" }];
714
- lines.push(` sinks: ${generateSinksCode(defaultSinks)},`);
715
- if (rawConfig.logging.categories && Object.keys(rawConfig.logging.categories).length > 0) {
716
- lines.push(" categories: {");
717
- for (const [cat, catConfig] of Object.entries(
718
- rawConfig.logging.categories
719
- )) {
720
- lines.push(` ${JSON.stringify(cat)}: {`);
721
- if (catConfig.level) {
722
- lines.push(` level: ${valueToCode(catConfig.level)},`);
723
- }
724
- if (catConfig.sinks) {
725
- lines.push(` sinks: ${generateSinksCode(catConfig.sinks)},`);
726
- }
727
- lines.push(" },");
728
- }
729
- lines.push(" },");
730
- } else {
731
- lines.push(" categories: {},");
732
- }
733
- lines.push(" },");
734
- } else {
735
- const consoleFactoryVar = sinkFactoryRefs.get(
736
- "@logtape/logtape:getConsoleSink"
737
- );
738
- lines.push(
739
- ` logging: {level: process.env.LOG_LEVEL || "info", sinks: [{provider: "console", factory: ${consoleFactoryVar}}], categories: {}},`
740
- );
741
- }
742
- if (rawConfig.caches && Object.keys(rawConfig.caches).length > 0) {
743
- lines.push(" caches: {");
744
- for (const [pattern, cfg] of Object.entries(rawConfig.caches)) {
745
- const providerVar = providerRefs[`cache.${pattern}`];
746
- lines.push(` ${JSON.stringify(pattern)}: {`);
747
- for (const [key, val] of Object.entries(cfg)) {
748
- if (key === "provider" && providerVar) {
749
- lines.push(` provider: ${providerVar},`);
750
- } else {
751
- lines.push(` ${key}: ${valueToCode(val)},`);
752
- }
753
- }
754
- lines.push(" },");
755
- }
756
- lines.push(" },");
757
- }
758
- if (rawConfig.directories && Object.keys(rawConfig.directories).length > 0) {
759
- lines.push(" directories: {");
760
- for (const [pattern, cfg] of Object.entries(rawConfig.directories)) {
761
- const providerVar = providerRefs[`directory.${pattern}`];
762
- lines.push(` ${JSON.stringify(pattern)}: {`);
763
- for (const [key, val] of Object.entries(cfg)) {
764
- if (key === "provider" && providerVar) {
765
- lines.push(` provider: ${providerVar},`);
766
- } else {
767
- lines.push(` ${key}: ${valueToCode(val)},`);
768
- }
769
- }
770
- lines.push(" },");
771
- }
772
- lines.push(" },");
773
- }
774
- lines.push("}");
775
- return lines.join("\n");
776
- };
777
- const moduleLines = [];
778
- if (imports.length > 0) {
779
- moduleLines.push("// Provider imports (statically bundled)");
780
- moduleLines.push(...imports);
781
- moduleLines.push("");
782
- }
783
- moduleLines.push(
784
- "// Generated config (secrets stay as process.env references)"
785
- );
786
- moduleLines.push(`export const config = ${generateConfigCode()};`);
787
- return moduleLines.join("\n");
788
- }
789
- function loadRawConfig(cwd) {
790
- try {
791
- const shovelPath = `${cwd}/shovel.json`;
792
- const content = readFileSync2(shovelPath, "utf-8");
793
- return JSON.parse(content);
794
- } catch (error) {
795
- if (error?.code !== "ENOENT") {
796
- throw error;
797
- }
798
- try {
799
- const pkgPath = `${cwd}/package.json`;
800
- const content = readFileSync2(pkgPath, "utf-8");
801
- const pkgJSON = JSON.parse(content);
802
- return pkgJSON.shovel || {};
803
- } catch (error2) {
804
- if (error2?.code !== "ENOENT") {
805
- throw error2;
806
- }
807
- return {};
808
- }
809
- }
810
- }
811
- function loadConfig(cwd) {
812
- const env = getEnv();
813
- let rawConfig = {};
814
- try {
815
- const shovelPath = `${cwd}/shovel.json`;
816
- const content = readFileSync2(shovelPath, "utf-8");
817
- rawConfig = JSON.parse(content);
818
- } catch (error) {
819
- if (error?.code !== "ENOENT") {
820
- throw error;
821
- }
822
- try {
823
- const pkgPath = `${cwd}/package.json`;
824
- const content = readFileSync2(pkgPath, "utf-8");
825
- const pkgJSON = JSON.parse(content);
826
- rawConfig = pkgJSON.shovel || {};
827
- } catch (error2) {
828
- if (error2?.code !== "ENOENT") {
829
- throw error2;
830
- }
831
- }
832
- }
833
- const processed = processConfigValue(rawConfig, env, {
834
- strict: true
835
- });
836
- const defaultSinks = [{ provider: "console" }];
837
- const config = {
838
- platform: processed.platform ?? env.PLATFORM ?? void 0,
839
- port: processed.port !== void 0 ? typeof processed.port === "number" ? processed.port : parseInt(String(processed.port), 10) : env.PORT ? parseInt(env.PORT, 10) : 3e3,
840
- host: processed.host ?? env.HOST ?? "localhost",
841
- workers: processed.workers !== void 0 ? typeof processed.workers === "number" ? processed.workers : parseInt(String(processed.workers), 10) : env.WORKERS ? parseInt(env.WORKERS, 10) : 1,
842
- logging: {
843
- level: processed.logging?.level || "info",
844
- sinks: processed.logging?.sinks || defaultSinks,
845
- categories: processed.logging?.categories || {}
846
- },
847
- caches: processed.caches || {},
848
- directories: processed.directories || {}
849
- };
850
- return config;
851
- }
852
-
853
- export {
854
- findProjectRoot,
855
- findWorkspaceRoot,
856
- getNodeModulesPath,
857
- DEFAULTS,
858
- generateConfigModule,
859
- loadRawConfig,
860
- loadConfig
861
- };