@stati/core 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +1 -1
  2. package/dist/core/dev.d.ts.map +1 -1
  3. package/dist/core/dev.js +154 -87
  4. package/dist/core/isg/hash.d.ts.map +1 -1
  5. package/dist/core/isg/hash.js +13 -1
  6. package/dist/core/markdown.d.ts.map +1 -1
  7. package/dist/core/markdown.js +21 -2
  8. package/dist/core/preview.d.ts.map +1 -1
  9. package/dist/core/preview.js +17 -21
  10. package/dist/core/templates.d.ts.map +1 -1
  11. package/dist/core/templates.js +84 -10
  12. package/dist/core/utils/error-overlay.d.ts +31 -0
  13. package/dist/core/utils/error-overlay.d.ts.map +1 -0
  14. package/dist/core/utils/error-overlay.js +562 -0
  15. package/dist/core/utils/partial-validation.d.ts +6 -0
  16. package/dist/core/utils/partial-validation.d.ts.map +1 -0
  17. package/dist/core/utils/partial-validation.js +129 -0
  18. package/dist/core/utils/server.d.ts +23 -0
  19. package/dist/core/utils/server.d.ts.map +1 -0
  20. package/dist/core/utils/server.js +61 -0
  21. package/dist/core/utils/template-errors.d.ts +28 -0
  22. package/dist/core/utils/template-errors.d.ts.map +1 -0
  23. package/dist/core/utils/template-errors.js +128 -0
  24. package/dist/core/utils/template-utils.d.ts +20 -0
  25. package/dist/core/utils/template-utils.d.ts.map +1 -0
  26. package/dist/core/utils/template-utils.js +39 -0
  27. package/dist/core/utils/version.d.ts +6 -0
  28. package/dist/core/utils/version.d.ts.map +1 -0
  29. package/dist/core/utils/version.js +20 -0
  30. package/dist/env.d.ts +3 -0
  31. package/dist/env.d.ts.map +1 -0
  32. package/dist/env.js +7 -0
  33. package/dist/index.d.ts +1 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +1 -0
  36. package/package.json +1 -1
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Creates inline error overlay HTML for missing partials
3
+ */
4
+ function createInlineErrorOverlay(partialName, suggestions) {
5
+ const suggestionText = suggestions.length > 0
6
+ ? `Did you mean: ${suggestions.map((s) => `"${s}"`).join(', ')}?`
7
+ : 'No similar partials found';
8
+ return `
9
+ <!-- Stati Development Error Overlay -->
10
+ <div style="
11
+ position: fixed;
12
+ top: 20px;
13
+ right: 20px;
14
+ z-index: 999999;
15
+ background: #dc2626;
16
+ color: white;
17
+ padding: 16px;
18
+ border-radius: 8px;
19
+ box-shadow: 0 4px 12px rgba(0,0,0,0.3);
20
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
21
+ font-size: 14px;
22
+ line-height: 1.4;
23
+ max-width: 400px;
24
+ border: 2px solid #fca5a5;
25
+ ">
26
+ <div style="font-weight: 600; margin-bottom: 8px; font-size: 16px;">
27
+ ⚠️ Template Error
28
+ </div>
29
+ <div style="margin-bottom: 8px;">
30
+ <strong>Partial "${partialName}" not found</strong>
31
+ </div>
32
+ <div style="color: #fca5a5; font-size: 13px;">
33
+ ${suggestionText}
34
+ </div>
35
+ <div style="margin-top: 12px; padding-top: 8px; border-top: 1px solid #fca5a5; font-size: 12px; opacity: 0.8;">
36
+ Fix the partial name in your template to dismiss this error
37
+ </div>
38
+ </div>
39
+ <!-- End Stati Error Overlay -->`;
40
+ }
41
+ /**
42
+ * Finds similar partial names to suggest when a partial is not found
43
+ */
44
+ function findSimilarPartialNames(targetName, availableNames) {
45
+ if (availableNames.length === 0)
46
+ return [];
47
+ // Simple similarity check based on common prefixes and substrings
48
+ const target = targetName.toLowerCase();
49
+ const suggestions = availableNames
50
+ .map((name) => {
51
+ const candidate = name.toLowerCase();
52
+ let score = 0;
53
+ // Exact match gets highest score
54
+ if (candidate === target)
55
+ return { name, score: 1000 };
56
+ // Check if one is contained in the other
57
+ if (candidate.includes(target) || target.includes(candidate)) {
58
+ score += 100;
59
+ }
60
+ // Check common prefix length
61
+ let prefixLen = 0;
62
+ for (let i = 0; i < Math.min(target.length, candidate.length); i++) {
63
+ if (target[i] === candidate[i]) {
64
+ prefixLen++;
65
+ }
66
+ else {
67
+ break;
68
+ }
69
+ }
70
+ score += prefixLen * 10;
71
+ // Check common characters
72
+ const targetChars = new Set(target);
73
+ const candidateChars = new Set(candidate);
74
+ const commonChars = [...targetChars].filter((char) => candidateChars.has(char));
75
+ score += commonChars.length;
76
+ return { name, score };
77
+ })
78
+ .filter((item) => item.score > 0) // Only include items with some similarity
79
+ .sort((a, b) => b.score - a.score) // Sort by score descending
80
+ .slice(0, 3) // Top 3 suggestions
81
+ .map((item) => item.name);
82
+ return suggestions;
83
+ }
84
+ /**
85
+ * Creates a development-mode Proxy for the partials object that throws errors
86
+ * when accessing non-existent partials instead of returning undefined
87
+ */
88
+ export function createValidatingPartialsProxy(partials) {
89
+ // In production, return partials as-is
90
+ // Only skip validation if explicitly set to production
91
+ if (process.env.NODE_ENV === 'production') {
92
+ return partials;
93
+ }
94
+ return new Proxy(partials, {
95
+ get(target, prop, receiver) {
96
+ // Allow normal object operations
97
+ if (typeof prop === 'symbol') {
98
+ return Reflect.get(target, prop, receiver);
99
+ }
100
+ const propName = String(prop);
101
+ // Check if the property exists
102
+ if (propName in target) {
103
+ return target[propName];
104
+ }
105
+ // Special case: allow accessing length, toString, etc.
106
+ if (propName in Object.prototype || propName === 'length') {
107
+ return Reflect.get(target, prop, receiver);
108
+ }
109
+ // Property doesn't exist - return error overlay HTML instead of throwing
110
+ const availablePartials = Object.keys(target);
111
+ const suggestions = findSimilarPartialNames(propName, availablePartials);
112
+ // Special case: throw error if no partials are available at all
113
+ if (availablePartials.length === 0) {
114
+ throw new Error('No partials are available');
115
+ }
116
+ // In development, render an inline error overlay
117
+ return createInlineErrorOverlay(propName, suggestions);
118
+ },
119
+ has(target, prop) {
120
+ return prop in target;
121
+ },
122
+ ownKeys(target) {
123
+ return Reflect.ownKeys(target);
124
+ },
125
+ getOwnPropertyDescriptor(target, prop) {
126
+ return Reflect.getOwnPropertyDescriptor(target, prop);
127
+ },
128
+ });
129
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Result of attempting to resolve a pretty URL path
3
+ */
4
+ export interface PrettyUrlResult {
5
+ /** The resolved file path to serve */
6
+ filePath: string | null;
7
+ /** Whether the path was found */
8
+ found: boolean;
9
+ }
10
+ /**
11
+ * Attempts to resolve pretty URL paths by trying various fallback strategies.
12
+ * This handles common patterns like:
13
+ * - /path/ -> /path/index.html
14
+ * - /path/ -> /path.html (if no index.html exists)
15
+ * - /path -> /path.html (when original path is not found)
16
+ *
17
+ * @param outDir The output directory to serve files from
18
+ * @param requestPath The requested URL path
19
+ * @param originalFilePath The original file path that was attempted
20
+ * @returns Promise resolving to the file path to serve or null if not found
21
+ */
22
+ export declare function resolvePrettyUrl(outDir: string, requestPath: string, originalFilePath: string): Promise<PrettyUrlResult>;
23
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/core/utils/server.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iCAAiC;IACjC,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,eAAe,CAAC,CA+C1B"}
@@ -0,0 +1,61 @@
1
+ import { join } from 'path';
2
+ import { stat } from 'fs/promises';
3
+ /**
4
+ * Attempts to resolve pretty URL paths by trying various fallback strategies.
5
+ * This handles common patterns like:
6
+ * - /path/ -> /path/index.html
7
+ * - /path/ -> /path.html (if no index.html exists)
8
+ * - /path -> /path.html (when original path is not found)
9
+ *
10
+ * @param outDir The output directory to serve files from
11
+ * @param requestPath The requested URL path
12
+ * @param originalFilePath The original file path that was attempted
13
+ * @returns Promise resolving to the file path to serve or null if not found
14
+ */
15
+ export async function resolvePrettyUrl(outDir, requestPath, originalFilePath) {
16
+ try {
17
+ const stats = await stat(originalFilePath);
18
+ if (stats.isDirectory()) {
19
+ // Try to serve index.html from directory
20
+ const indexPath = join(originalFilePath, 'index.html');
21
+ try {
22
+ await stat(indexPath);
23
+ return { filePath: indexPath, found: true };
24
+ }
25
+ catch {
26
+ // If no index.html in directory, try to serve corresponding .html file
27
+ // For example: /examples/ -> examples.html
28
+ const directoryName = requestPath.replace(/\/$/, ''); // Remove trailing slash
29
+ const fallbackPath = join(outDir, `${directoryName}.html`);
30
+ try {
31
+ await stat(fallbackPath);
32
+ return { filePath: fallbackPath, found: true };
33
+ }
34
+ catch {
35
+ return { filePath: null, found: false };
36
+ }
37
+ }
38
+ }
39
+ // File exists and is not a directory
40
+ return { filePath: originalFilePath, found: true };
41
+ }
42
+ catch {
43
+ // File not found, try fallback strategies for pretty URLs
44
+ if (requestPath.endsWith('/')) {
45
+ // For requests ending with /, try the corresponding .html file
46
+ const pathWithoutSlash = requestPath.slice(0, -1);
47
+ const htmlPath = join(outDir, `${pathWithoutSlash}.html`);
48
+ try {
49
+ const stats = await stat(htmlPath);
50
+ if (stats.isFile()) {
51
+ return { filePath: htmlPath, found: true };
52
+ }
53
+ }
54
+ catch {
55
+ // Continue to not found
56
+ }
57
+ }
58
+ // No fallback worked
59
+ return { filePath: null, found: false };
60
+ }
61
+ }
@@ -0,0 +1,28 @@
1
+ import type { ErrorDetails } from './error-overlay.js';
2
+ /**
3
+ * Enhanced template error that includes file context and suggestions.
4
+ */
5
+ export declare class TemplateError extends Error {
6
+ readonly filePath?: string;
7
+ readonly line?: number;
8
+ readonly column?: number;
9
+ readonly template?: string;
10
+ readonly context?: {
11
+ before?: string[];
12
+ after?: string[];
13
+ };
14
+ constructor(message: string, filePath?: string, line?: number, column?: number, template?: string);
15
+ /**
16
+ * Converts this template error to ErrorDetails for the overlay.
17
+ */
18
+ toErrorDetails(): Promise<ErrorDetails>;
19
+ }
20
+ /**
21
+ * Parses Eta template errors to extract file location information.
22
+ */
23
+ export declare function parseEtaError(error: Error, templatePath?: string): TemplateError;
24
+ /**
25
+ * Enhances a generic error with template-specific context.
26
+ */
27
+ export declare function createTemplateError(error: Error, templatePath?: string, _line?: number, _column?: number): TemplateError;
28
+ //# sourceMappingURL=template-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-errors.d.ts","sourceRoot":"","sources":["../../../src/core/utils/template-errors.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;GAEG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClC,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAgB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChC,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClC,SAAgB,OAAO,CAAC,EAAE;QACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;gBAGA,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM;IAUnB;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,YAAY,CAAC;CAoE9C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CA8BhF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,KAAK,EACZ,YAAY,CAAC,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,CAMf"}
@@ -0,0 +1,128 @@
1
+ import { readFile } from 'fs/promises';
2
+ import { pathExists } from './fs.js';
3
+ /**
4
+ * Enhanced template error that includes file context and suggestions.
5
+ */
6
+ export class TemplateError extends Error {
7
+ filePath;
8
+ line;
9
+ column;
10
+ template;
11
+ context;
12
+ constructor(message, filePath, line, column, template) {
13
+ super(message);
14
+ this.name = 'TemplateError';
15
+ if (filePath !== undefined)
16
+ this.filePath = filePath;
17
+ if (line !== undefined)
18
+ this.line = line;
19
+ if (column !== undefined)
20
+ this.column = column;
21
+ if (template !== undefined)
22
+ this.template = template;
23
+ }
24
+ /**
25
+ * Converts this template error to ErrorDetails for the overlay.
26
+ */
27
+ async toErrorDetails() {
28
+ const suggestions = [];
29
+ const message = this.message.toLowerCase();
30
+ // Add specific suggestions based on error type
31
+ if (message.includes('not found') || message.includes('cannot resolve')) {
32
+ suggestions.push('Check if the template file exists and has the correct path');
33
+ suggestions.push('Verify the template reference in your layout or include statement');
34
+ suggestions.push('Ensure the template file has the .eta extension');
35
+ }
36
+ else if (message.includes('syntax') || message.includes('unexpected')) {
37
+ suggestions.push('Check for unmatched brackets, quotes, or parentheses');
38
+ suggestions.push('Verify Eta template syntax is correct');
39
+ suggestions.push('Look for unclosed template tags');
40
+ }
41
+ else if (message.includes('undefined') || message.includes('null')) {
42
+ suggestions.push('Check if all required data is available in template context');
43
+ suggestions.push('Add conditional checks for optional template variables');
44
+ suggestions.push('Verify page frontMatter and data structure');
45
+ }
46
+ // Try to read file context if available
47
+ let context;
48
+ let code;
49
+ if (this.filePath && this.line && (await pathExists(this.filePath))) {
50
+ try {
51
+ const fileContent = await readFile(this.filePath, 'utf-8');
52
+ const lines = fileContent.split('\n');
53
+ const errorLineIndex = this.line - 1;
54
+ if (errorLineIndex >= 0 && errorLineIndex < lines.length) {
55
+ code = lines[errorLineIndex];
56
+ // Get surrounding context
57
+ const contextLines = 3;
58
+ const beforeLines = lines.slice(Math.max(0, errorLineIndex - contextLines), errorLineIndex);
59
+ const afterLines = lines.slice(errorLineIndex + 1, Math.min(lines.length, errorLineIndex + contextLines + 1));
60
+ context = {
61
+ before: beforeLines,
62
+ after: afterLines,
63
+ };
64
+ }
65
+ }
66
+ catch {
67
+ // Ignore file read errors
68
+ }
69
+ }
70
+ const errorDetails = {
71
+ type: 'template',
72
+ message: this.message,
73
+ suggestions,
74
+ };
75
+ if (this.stack !== undefined)
76
+ errorDetails.stack = this.stack;
77
+ if (this.filePath !== undefined)
78
+ errorDetails.file = this.filePath;
79
+ if (this.line !== undefined)
80
+ errorDetails.line = this.line;
81
+ if (this.column !== undefined)
82
+ errorDetails.column = this.column;
83
+ if (code !== undefined)
84
+ errorDetails.code = code;
85
+ if (context !== undefined)
86
+ errorDetails.context = context;
87
+ return errorDetails;
88
+ }
89
+ }
90
+ /**
91
+ * Parses Eta template errors to extract file location information.
92
+ */
93
+ export function parseEtaError(error, templatePath) {
94
+ let filePath = templatePath;
95
+ let line;
96
+ let column;
97
+ // Try to parse error location from Eta error messages
98
+ const message = error.message;
99
+ // Eta syntax errors often include line/column info
100
+ const locationMatch = message.match(/at line (\d+), column (\d+)/i);
101
+ if (locationMatch && locationMatch[1] && locationMatch[2]) {
102
+ line = parseInt(locationMatch[1], 10);
103
+ column = parseInt(locationMatch[2], 10);
104
+ }
105
+ // Try to extract file path from stack trace if not provided
106
+ if (!filePath && error.stack) {
107
+ const stackLines = error.stack.split('\n');
108
+ for (const stackLine of stackLines) {
109
+ const fileMatch = stackLine.match(/at.*\(([^)]+\.eta):(\d+):(\d+)\)/);
110
+ if (fileMatch && fileMatch[1] && fileMatch[2] && fileMatch[3]) {
111
+ filePath = fileMatch[1];
112
+ line = parseInt(fileMatch[2], 10);
113
+ column = parseInt(fileMatch[3], 10);
114
+ break;
115
+ }
116
+ }
117
+ }
118
+ return new TemplateError(message, filePath, line, column);
119
+ }
120
+ /**
121
+ * Enhances a generic error with template-specific context.
122
+ */
123
+ export function createTemplateError(error, templatePath, _line, _column) {
124
+ if (error instanceof TemplateError) {
125
+ return error;
126
+ }
127
+ return parseEtaError(error, templatePath);
128
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Utility functions for Eta templates
3
+ */
4
+ type PropValueArg = string | number | boolean | null | undefined | Record<string, boolean | string | number | null | undefined> | PropValueArg[];
5
+ /**
6
+ * Builds a property value from various inputs, similar to classnames but for any property.
7
+ * Accepts strings, arrays, and objects. Filters out falsy values.
8
+ *
9
+ * @param args - Values to combine
10
+ * @returns Combined property value string
11
+ *
12
+ * @example
13
+ * propValue('class1', 'class2') // 'class1 class2'
14
+ * propValue(['class1', 'class2']) // 'class1 class2'
15
+ * propValue({ 'class1': true, 'class2': false }) // 'class1'
16
+ * propValue('class1', ['class2', 'class3'], { 'class4': true }) // 'class1 class2 class3 class4'
17
+ */
18
+ export declare function propValue(...args: PropValueArg[]): string;
19
+ export {};
20
+ //# sourceMappingURL=template-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-utils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/template-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,KAAK,YAAY,GACb,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,GACT,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAC5D,YAAY,EAAE,CAAC;AAEnB;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,GAAG,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,CAwBzD"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Utility functions for Eta templates
3
+ */
4
+ /**
5
+ * Builds a property value from various inputs, similar to classnames but for any property.
6
+ * Accepts strings, arrays, and objects. Filters out falsy values.
7
+ *
8
+ * @param args - Values to combine
9
+ * @returns Combined property value string
10
+ *
11
+ * @example
12
+ * propValue('class1', 'class2') // 'class1 class2'
13
+ * propValue(['class1', 'class2']) // 'class1 class2'
14
+ * propValue({ 'class1': true, 'class2': false }) // 'class1'
15
+ * propValue('class1', ['class2', 'class3'], { 'class4': true }) // 'class1 class2 class3 class4'
16
+ */
17
+ export function propValue(...args) {
18
+ const classes = [];
19
+ for (const arg of args) {
20
+ if (!arg)
21
+ continue;
22
+ if (typeof arg === 'string' || typeof arg === 'number') {
23
+ classes.push(String(arg));
24
+ }
25
+ else if (Array.isArray(arg)) {
26
+ classes.push(...arg
27
+ .filter((item) => item && (typeof item === 'string' || typeof item === 'number'))
28
+ .map(String));
29
+ }
30
+ else if (typeof arg === 'object') {
31
+ for (const [key, value] of Object.entries(arg)) {
32
+ if (value) {
33
+ classes.push(key);
34
+ }
35
+ }
36
+ }
37
+ }
38
+ return classes.join(' ');
39
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Gets the current version of Stati core from package.json
3
+ * @returns The version string
4
+ */
5
+ export declare function getStatiVersion(): string;
6
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/core/utils/version.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAWxC"}
@@ -0,0 +1,20 @@
1
+ import { readFileSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ /**
5
+ * Gets the current version of Stati core from package.json
6
+ * @returns The version string
7
+ */
8
+ export function getStatiVersion() {
9
+ try {
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+ const packageJsonPath = join(__dirname, '../../package.json');
13
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
14
+ return packageJson.version;
15
+ }
16
+ catch {
17
+ // Fallback for cases where package.json can't be read
18
+ return '1.0.0';
19
+ }
20
+ }
package/dist/env.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export declare function setEnv(env: 'development' | 'production' | 'test'): void;
2
+ export declare function getEnv(): string;
3
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,GAAG,MAAM,QAEhE;AAED,wBAAgB,MAAM,WAErB"}
package/dist/env.js ADDED
@@ -0,0 +1,7 @@
1
+ let currentEnv = process.env.NODE_ENV || 'development';
2
+ export function setEnv(env) {
3
+ currentEnv = env;
4
+ }
5
+ export function getEnv() {
6
+ return currentEnv;
7
+ }
package/dist/index.d.ts CHANGED
@@ -29,6 +29,7 @@ export { createDevServer } from './core/dev.js';
29
29
  export { createPreviewServer } from './core/preview.js';
30
30
  export { loadConfig } from './config/loader.js';
31
31
  export { invalidate } from './core/invalidate.js';
32
+ export { setEnv, getEnv } from './env.js';
32
33
  import type { StatiConfig } from './types/index.js';
33
34
  /**
34
35
  * Helper function for defining Stati configuration with TypeScript IntelliSense.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,YAAY,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAE7D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,YAAY,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAG1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAE7D"}
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ export { createDevServer } from './core/dev.js';
24
24
  export { createPreviewServer } from './core/preview.js';
25
25
  export { loadConfig } from './config/loader.js';
26
26
  export { invalidate } from './core/invalidate.js';
27
+ export { setEnv, getEnv } from './env.js';
27
28
  /**
28
29
  * Helper function for defining Stati configuration with TypeScript IntelliSense.
29
30
  * Provides type checking and autocompletion for configuration options.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stati/core",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",