zig-pug 0.4.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/binding.c +70 -1
- package/binding.gyp +21 -2
- package/include/zigpug.h +48 -0
- package/index.d.ts +294 -0
- package/index.mjs +48 -2
- package/package.json +16 -4
- package/prebuild-fix.js +24 -0
- package/prebuilt-binaries/linux-arm64/zigpug.node +0 -0
- package/prebuilts/darwin-arm64/libzig-pug.a +0 -0
- package/prebuilts/darwin-x64/libzig-pug.a +0 -0
- package/prebuilts/linux-arm64/libzig-pug.a +0 -0
- package/prebuilts/linux-x64/libzig-pug.a +0 -0
- package/prebuilts/win32-x64/zig-pug.lib +0 -0
- package/prebuilt-binaries/linux-x64/zigpug.node +0 -0
package/README.md
CHANGED
|
@@ -14,7 +14,9 @@ High-performance Pug template engine powered by Zig and mujs.
|
|
|
14
14
|
- ✅ **Conditionals** - if/else/unless
|
|
15
15
|
- ✅ **Mixins** - Reusable components
|
|
16
16
|
- ✅ **Dual package** - CommonJS (`require`) and ES Modules (`import`)
|
|
17
|
+
- ✅ **TypeScript support** - Full type definitions included
|
|
17
18
|
- ✅ **Bun.js compatible** - 2-5x faster than Node.js
|
|
19
|
+
- ✅ **Structured errors** - Detailed error messages with line numbers, hints, and context
|
|
18
20
|
- ⚡ **Native performance** - Written in Zig, compiled to native code
|
|
19
21
|
- 🔋 **Zero dependencies** - Only Zig and embedded mujs
|
|
20
22
|
- 🌍 **i18n ready** - Spanish, Portuguese, French, German, and more
|
|
@@ -122,6 +124,59 @@ bun run app.js
|
|
|
122
124
|
|
|
123
125
|
See [examples/bun/](https://github.com/carlos-sweb/zig-pug/tree/main/examples/bun) for complete examples.
|
|
124
126
|
|
|
127
|
+
## TypeScript Support
|
|
128
|
+
|
|
129
|
+
zig-pug includes full TypeScript definitions for enhanced development experience with IntelliSense and type safety.
|
|
130
|
+
|
|
131
|
+
### Basic Usage
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
import { compile, PugCompiler, ZigPugCompilationError } from 'zig-pug';
|
|
135
|
+
|
|
136
|
+
// Simple compilation with type inference
|
|
137
|
+
const html: string = compile('p Hello #{name}', { name: 'TypeScript' });
|
|
138
|
+
|
|
139
|
+
// Using PugCompiler class
|
|
140
|
+
const compiler: PugCompiler = new PugCompiler();
|
|
141
|
+
compiler
|
|
142
|
+
.setString('title', 'My Page')
|
|
143
|
+
.setNumber('count', 42)
|
|
144
|
+
.setBool('active', true);
|
|
145
|
+
|
|
146
|
+
const result: string = compiler.compile('h1= title');
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Error Handling with Types
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
try {
|
|
153
|
+
const html = compile(template, variables);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
const err = error as ZigPugCompilationError;
|
|
156
|
+
|
|
157
|
+
if (err.compilationErrors) {
|
|
158
|
+
const { errorCount, errors } = err.compilationErrors;
|
|
159
|
+
|
|
160
|
+
errors.forEach(e => {
|
|
161
|
+
console.error(`Line ${e.line}: ${e.message}`);
|
|
162
|
+
if (e.detail) console.error(` Detail: ${e.detail}`);
|
|
163
|
+
if (e.hint) console.error(` Hint: ${e.hint}`);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Available Types
|
|
170
|
+
|
|
171
|
+
- `PugCompiler` - Main compiler class
|
|
172
|
+
- `PugVariables` - Type for template variables
|
|
173
|
+
- `CompilationErrorInfo` - Individual error information
|
|
174
|
+
- `CompilationErrors` - Collection of compilation errors
|
|
175
|
+
- `ZigPugCompilationError` - Extended Error with compilation details
|
|
176
|
+
- `ErrorType` - Error type classification enum
|
|
177
|
+
|
|
178
|
+
See [examples/nodejs/08-typescript-example.ts](https://github.com/carlos-sweb/zig-pug/tree/main/examples/nodejs/08-typescript-example.ts) for complete TypeScript examples.
|
|
179
|
+
|
|
125
180
|
## Pug Syntax
|
|
126
181
|
|
|
127
182
|
### Tags and Attributes
|
package/binding.c
CHANGED
|
@@ -21,6 +21,8 @@ extern int zigpug_set_array_json(ZigPugContext* ctx, const char* key, const char
|
|
|
21
21
|
extern int zigpug_set_object_json(ZigPugContext* ctx, const char* key, const char* json_str);
|
|
22
22
|
extern void zigpug_free_string(char* str);
|
|
23
23
|
extern const char* zigpug_version(void);
|
|
24
|
+
extern size_t zigpug_get_error_count(ZigPugContext* ctx);
|
|
25
|
+
extern int zigpug_get_error(ZigPugContext* ctx, size_t index, size_t* line_out, const char** message_out, const char** detail_out, const char** hint_out);
|
|
24
26
|
|
|
25
27
|
// Wrapper for ZigPugContext to store in JavaScript
|
|
26
28
|
typedef struct {
|
|
@@ -295,7 +297,74 @@ static napi_value Compile(napi_env env, napi_callback_info info) {
|
|
|
295
297
|
free(template);
|
|
296
298
|
|
|
297
299
|
if (!html) {
|
|
298
|
-
|
|
300
|
+
// Get error information
|
|
301
|
+
size_t error_count = zigpug_get_error_count(wrapper->ctx);
|
|
302
|
+
|
|
303
|
+
if (error_count > 0) {
|
|
304
|
+
// Create structured error object
|
|
305
|
+
napi_value error_obj;
|
|
306
|
+
napi_create_object(env, &error_obj);
|
|
307
|
+
|
|
308
|
+
// Add error count
|
|
309
|
+
napi_value count_value;
|
|
310
|
+
napi_create_uint32(env, (uint32_t)error_count, &count_value);
|
|
311
|
+
napi_set_named_property(env, error_obj, "errorCount", count_value);
|
|
312
|
+
|
|
313
|
+
// Add errors array
|
|
314
|
+
napi_value errors_array;
|
|
315
|
+
napi_create_array_with_length(env, error_count, &errors_array);
|
|
316
|
+
|
|
317
|
+
for (size_t i = 0; i < error_count; i++) {
|
|
318
|
+
size_t line;
|
|
319
|
+
const char* message;
|
|
320
|
+
const char* detail;
|
|
321
|
+
const char* hint;
|
|
322
|
+
|
|
323
|
+
if (zigpug_get_error(wrapper->ctx, i, &line, &message, &detail, &hint)) {
|
|
324
|
+
napi_value err_obj;
|
|
325
|
+
napi_create_object(env, &err_obj);
|
|
326
|
+
|
|
327
|
+
// Add line number
|
|
328
|
+
napi_value line_value;
|
|
329
|
+
napi_create_uint32(env, (uint32_t)line, &line_value);
|
|
330
|
+
napi_set_named_property(env, err_obj, "line", line_value);
|
|
331
|
+
|
|
332
|
+
// Add message
|
|
333
|
+
napi_value message_value;
|
|
334
|
+
napi_create_string_utf8(env, message, NAPI_AUTO_LENGTH, &message_value);
|
|
335
|
+
napi_set_named_property(env, err_obj, "message", message_value);
|
|
336
|
+
|
|
337
|
+
// Add detail if present
|
|
338
|
+
if (detail) {
|
|
339
|
+
napi_value detail_value;
|
|
340
|
+
napi_create_string_utf8(env, detail, NAPI_AUTO_LENGTH, &detail_value);
|
|
341
|
+
napi_set_named_property(env, err_obj, "detail", detail_value);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Add hint if present
|
|
345
|
+
if (hint) {
|
|
346
|
+
napi_value hint_value;
|
|
347
|
+
napi_create_string_utf8(env, hint, NAPI_AUTO_LENGTH, &hint_value);
|
|
348
|
+
napi_set_named_property(env, err_obj, "hint", hint_value);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
napi_set_element(env, errors_array, (uint32_t)i, err_obj);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
napi_set_named_property(env, error_obj, "errors", errors_array);
|
|
356
|
+
|
|
357
|
+
// Throw the structured error
|
|
358
|
+
napi_throw_error(env, NULL, "Template compilation failed");
|
|
359
|
+
napi_value error_instance;
|
|
360
|
+
napi_get_and_clear_last_exception(env, &error_instance);
|
|
361
|
+
|
|
362
|
+
// Add our structured error data to the error object
|
|
363
|
+
napi_set_named_property(env, error_instance, "compilationErrors", error_obj);
|
|
364
|
+
napi_throw(env, error_instance);
|
|
365
|
+
} else {
|
|
366
|
+
napi_throw_error(env, NULL, "Failed to compile template");
|
|
367
|
+
}
|
|
299
368
|
return NULL;
|
|
300
369
|
}
|
|
301
370
|
|
package/binding.gyp
CHANGED
|
@@ -13,10 +13,29 @@
|
|
|
13
13
|
"libraries": [
|
|
14
14
|
"<(module_root_dir)/prebuilts/win32-<(target_arch)/zig-pug.lib"
|
|
15
15
|
]
|
|
16
|
-
},
|
|
16
|
+
}],
|
|
17
|
+
["OS=='mac'", {
|
|
17
18
|
"libraries": [
|
|
18
19
|
"-lm",
|
|
19
|
-
"
|
|
20
|
+
"../prebuilts/darwin-<(target_arch)/libzig-pug.a"
|
|
21
|
+
],
|
|
22
|
+
"cflags": [
|
|
23
|
+
"-std=c99"
|
|
24
|
+
]
|
|
25
|
+
}],
|
|
26
|
+
["OS=='android'", {
|
|
27
|
+
"libraries": [
|
|
28
|
+
"-lm",
|
|
29
|
+
"../prebuilts/linux-<(target_arch)/libzig-pug.a"
|
|
30
|
+
],
|
|
31
|
+
"cflags": [
|
|
32
|
+
"-std=c99"
|
|
33
|
+
]
|
|
34
|
+
}],
|
|
35
|
+
["OS=='linux'", {
|
|
36
|
+
"libraries": [
|
|
37
|
+
"-lm",
|
|
38
|
+
"../prebuilts/linux-<(target_arch)/libzig-pug.a"
|
|
20
39
|
],
|
|
21
40
|
"cflags": [
|
|
22
41
|
"-std=c99"
|
package/include/zigpug.h
CHANGED
|
@@ -106,6 +106,54 @@ bool zigpug_set_int(ZigPugContext* ctx, const char* key, int64_t value);
|
|
|
106
106
|
*/
|
|
107
107
|
bool zigpug_set_bool(ZigPugContext* ctx, const char* key, bool value);
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Get the number of compilation errors from the last compile call
|
|
111
|
+
*
|
|
112
|
+
* @param ctx Context handle
|
|
113
|
+
* @return Number of errors, or 0 if no errors or no compilation done
|
|
114
|
+
*
|
|
115
|
+
* Example:
|
|
116
|
+
* char* html = zigpug_compile(ctx, pug);
|
|
117
|
+
* if (!html) {
|
|
118
|
+
* size_t error_count = zigpug_get_error_count(ctx);
|
|
119
|
+
* printf("Compilation failed with %zu error(s)\n", error_count);
|
|
120
|
+
* }
|
|
121
|
+
*/
|
|
122
|
+
size_t zigpug_get_error_count(ZigPugContext* ctx);
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get a specific compilation error by index
|
|
126
|
+
*
|
|
127
|
+
* @param ctx Context handle
|
|
128
|
+
* @param index Error index (0 to error_count-1)
|
|
129
|
+
* @param line_out Output parameter for line number (can be NULL)
|
|
130
|
+
* @param message_out Output parameter for error message (can be NULL, do not free)
|
|
131
|
+
* @param detail_out Output parameter for detail (can be NULL, do not free, may be null)
|
|
132
|
+
* @param hint_out Output parameter for hint (can be NULL, do not free, may be null)
|
|
133
|
+
* @return true if error exists at index, false otherwise
|
|
134
|
+
*
|
|
135
|
+
* Example:
|
|
136
|
+
* for (size_t i = 0; i < error_count; i++) {
|
|
137
|
+
* size_t line;
|
|
138
|
+
* const char* message;
|
|
139
|
+
* const char* detail;
|
|
140
|
+
* const char* hint;
|
|
141
|
+
* if (zigpug_get_error(ctx, i, &line, &message, &detail, &hint)) {
|
|
142
|
+
* printf("Line %zu: %s\n", line, message);
|
|
143
|
+
* if (detail) printf(" %s\n", detail);
|
|
144
|
+
* if (hint) printf(" Hint: %s\n", hint);
|
|
145
|
+
* }
|
|
146
|
+
* }
|
|
147
|
+
*/
|
|
148
|
+
bool zigpug_get_error(
|
|
149
|
+
ZigPugContext* ctx,
|
|
150
|
+
size_t index,
|
|
151
|
+
size_t* line_out,
|
|
152
|
+
const char** message_out,
|
|
153
|
+
const char** detail_out,
|
|
154
|
+
const char** hint_out
|
|
155
|
+
);
|
|
156
|
+
|
|
109
157
|
/**
|
|
110
158
|
* Free a string returned by zig-pug
|
|
111
159
|
*
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zig-pug TypeScript definitions
|
|
3
|
+
* Pug template engine powered by Zig
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Error type classification
|
|
8
|
+
*/
|
|
9
|
+
export type ErrorType =
|
|
10
|
+
| 'LoopIterableEvalFailed'
|
|
11
|
+
| 'ConditionalEvalFailed'
|
|
12
|
+
| 'InterpolationEvalFailed'
|
|
13
|
+
| 'AttributeEvalFailed'
|
|
14
|
+
| 'CodeExecutionFailed'
|
|
15
|
+
| 'CaseEvalFailed'
|
|
16
|
+
| 'MixinNotFound'
|
|
17
|
+
| 'IncludeFileNotFound'
|
|
18
|
+
| 'IncludeParseError'
|
|
19
|
+
| 'ExtendsFileNotFound'
|
|
20
|
+
| 'ExtendsParseError';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Structured compilation error information
|
|
24
|
+
*/
|
|
25
|
+
export interface CompilationErrorInfo {
|
|
26
|
+
/** Error type classification */
|
|
27
|
+
type?: ErrorType;
|
|
28
|
+
/** Line number where the error occurred */
|
|
29
|
+
line: number;
|
|
30
|
+
/** Error message */
|
|
31
|
+
message: string;
|
|
32
|
+
/** Additional detail/context (e.g., expression, variable name) */
|
|
33
|
+
detail?: string;
|
|
34
|
+
/** Hint to help fix the error */
|
|
35
|
+
hint?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Compilation errors container
|
|
40
|
+
*/
|
|
41
|
+
export interface CompilationErrors {
|
|
42
|
+
/** Total number of errors */
|
|
43
|
+
errorCount: number;
|
|
44
|
+
/** Array of individual error details */
|
|
45
|
+
errors: CompilationErrorInfo[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Extended Error with compilation details
|
|
50
|
+
*/
|
|
51
|
+
export interface ZigPugCompilationError extends Error {
|
|
52
|
+
/** Structured compilation error information */
|
|
53
|
+
compilationErrors?: CompilationErrors;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Supported variable types
|
|
58
|
+
*/
|
|
59
|
+
export type PugVariable = string | number | boolean | any[] | Record<string, any>;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Variables object for template compilation
|
|
63
|
+
*/
|
|
64
|
+
export interface PugVariables {
|
|
65
|
+
[key: string]: PugVariable;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* PugCompiler class for advanced usage with reusable context
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const compiler = new PugCompiler();
|
|
74
|
+
* compiler.set('title', 'My Page');
|
|
75
|
+
* compiler.setArray('items', ['a', 'b', 'c']);
|
|
76
|
+
* const html = compiler.compile('h1= title');
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export class PugCompiler {
|
|
80
|
+
/**
|
|
81
|
+
* Create a new PugCompiler instance
|
|
82
|
+
* @throws {Error} If context creation fails
|
|
83
|
+
*/
|
|
84
|
+
constructor();
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Set a variable (auto-detects type)
|
|
88
|
+
* @param key - Variable name
|
|
89
|
+
* @param value - Variable value (string, number, boolean, array, or object)
|
|
90
|
+
* @returns This compiler instance for chaining
|
|
91
|
+
* @throws {TypeError} If value type is not supported
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* compiler.set('name', 'John');
|
|
96
|
+
* compiler.set('age', 30);
|
|
97
|
+
* compiler.set('active', true);
|
|
98
|
+
* compiler.set('tags', ['a', 'b']);
|
|
99
|
+
* compiler.set('user', { id: 1, name: 'John' });
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
set(key: string, value: PugVariable): this;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Set a string variable
|
|
106
|
+
* @param key - Variable name
|
|
107
|
+
* @param value - String value
|
|
108
|
+
* @returns This compiler instance for chaining
|
|
109
|
+
* @throws {TypeError} If key or value is not a string
|
|
110
|
+
* @throws {Error} If setting the variable fails
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* compiler.setString('title', 'Hello World');
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
setString(key: string, value: string): this;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Set a number variable
|
|
121
|
+
* @param key - Variable name
|
|
122
|
+
* @param value - Number value
|
|
123
|
+
* @returns This compiler instance for chaining
|
|
124
|
+
* @throws {TypeError} If key is not a string or value is not a number
|
|
125
|
+
* @throws {Error} If setting the variable fails
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* compiler.setNumber('count', 42);
|
|
130
|
+
* compiler.setNumber('price', 19.99);
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
setNumber(key: string, value: number): this;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Set a boolean variable
|
|
137
|
+
* @param key - Variable name
|
|
138
|
+
* @param value - Boolean value
|
|
139
|
+
* @returns This compiler instance for chaining
|
|
140
|
+
* @throws {TypeError} If key is not a string or value is not a boolean
|
|
141
|
+
* @throws {Error} If setting the variable fails
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* compiler.setBool('isActive', true);
|
|
146
|
+
* compiler.setBool('hasPermission', false);
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
setBool(key: string, value: boolean): this;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Set an array variable
|
|
153
|
+
* @param key - Variable name
|
|
154
|
+
* @param value - Array value
|
|
155
|
+
* @returns This compiler instance for chaining
|
|
156
|
+
* @throws {TypeError} If key is not a string or value is not an array
|
|
157
|
+
* @throws {Error} If setting the variable fails
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* compiler.setArray('items', ['Apple', 'Banana', 'Cherry']);
|
|
162
|
+
* compiler.setArray('numbers', [1, 2, 3, 4, 5]);
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
setArray(key: string, value: any[]): this;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Set an object variable
|
|
169
|
+
* @param key - Variable name
|
|
170
|
+
* @param value - Plain object (not array)
|
|
171
|
+
* @returns This compiler instance for chaining
|
|
172
|
+
* @throws {TypeError} If key is not a string or value is not a plain object
|
|
173
|
+
* @throws {Error} If setting the variable fails
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* compiler.setObject('user', {
|
|
178
|
+
* name: 'John',
|
|
179
|
+
* age: 30,
|
|
180
|
+
* email: 'john@example.com'
|
|
181
|
+
* });
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
setObject(key: string, value: Record<string, any>): this;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Set multiple variables from an object
|
|
188
|
+
* @param variables - Object with key-value pairs
|
|
189
|
+
* @returns This compiler instance for chaining
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* compiler.setVariables({
|
|
194
|
+
* title: 'My Page',
|
|
195
|
+
* count: 10,
|
|
196
|
+
* active: true,
|
|
197
|
+
* items: ['a', 'b']
|
|
198
|
+
* });
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
setVariables(variables: PugVariables): this;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Compile a Pug template to HTML
|
|
205
|
+
* @param template - Pug template string
|
|
206
|
+
* @returns Compiled HTML string
|
|
207
|
+
* @throws {TypeError} If template is not a string
|
|
208
|
+
* @throws {ZigPugCompilationError} If compilation fails with structured error info
|
|
209
|
+
* @throws {Error} If compilation fails for other reasons
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* try {
|
|
214
|
+
* const html = compiler.compile('h1= title');
|
|
215
|
+
* console.log(html);
|
|
216
|
+
* } catch (error) {
|
|
217
|
+
* if ((error as ZigPugCompilationError).compilationErrors) {
|
|
218
|
+
* const { errors } = (error as ZigPugCompilationError).compilationErrors!;
|
|
219
|
+
* errors.forEach(err => {
|
|
220
|
+
* console.error(`Line ${err.line}: ${err.message}`);
|
|
221
|
+
* });
|
|
222
|
+
* }
|
|
223
|
+
* }
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
compile(template: string): string;
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Compile a template with variables in one call
|
|
230
|
+
* @param template - Pug template string
|
|
231
|
+
* @param variables - Variables to set before compiling
|
|
232
|
+
* @returns Compiled HTML string
|
|
233
|
+
* @throws {TypeError} If template is not a string
|
|
234
|
+
* @throws {ZigPugCompilationError} If compilation fails
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* const html = compiler.render('h1= title', { title: 'Hello' });
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
render(template: string, variables?: PugVariables): string;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Compile a Pug template string to HTML (simple API)
|
|
246
|
+
* @param template - Pug template string
|
|
247
|
+
* @param variables - Optional variables for interpolation
|
|
248
|
+
* @returns Compiled HTML string
|
|
249
|
+
* @throws {ZigPugCompilationError} If compilation fails
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* ```typescript
|
|
253
|
+
* const html = compile('p Hello #{name}!', { name: 'World' });
|
|
254
|
+
* console.log(html); // <p>Hello World!</p>
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
export function compile(template: string, variables?: PugVariables): string;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Compile a Pug template from a file
|
|
261
|
+
* @param filename - Path to .pug file
|
|
262
|
+
* @param variables - Optional variables for interpolation
|
|
263
|
+
* @returns Compiled HTML string
|
|
264
|
+
* @throws {Error} If file cannot be read
|
|
265
|
+
* @throws {ZigPugCompilationError} If compilation fails
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```typescript
|
|
269
|
+
* const html = compileFile('./views/index.pug', {
|
|
270
|
+
* title: 'Home',
|
|
271
|
+
* user: { name: 'John' }
|
|
272
|
+
* });
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
export function compileFile(filename: string, variables?: PugVariables): string;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Get zig-pug version string
|
|
279
|
+
* @returns Version string (e.g., "0.4.0")
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```typescript
|
|
283
|
+
* console.log(`Using zig-pug v${version()}`);
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
export function version(): string;
|
|
287
|
+
|
|
288
|
+
// Default export
|
|
289
|
+
export default {
|
|
290
|
+
PugCompiler,
|
|
291
|
+
compile,
|
|
292
|
+
compileFile,
|
|
293
|
+
version
|
|
294
|
+
};
|
package/index.mjs
CHANGED
|
@@ -121,14 +121,60 @@ export class PugCompiler {
|
|
|
121
121
|
return this;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Set an array variable in the template context
|
|
126
|
+
* @param {string} key - Variable name
|
|
127
|
+
* @param {Array} value - Array value
|
|
128
|
+
* @returns {PugCompiler} - Returns this for chaining
|
|
129
|
+
*/
|
|
130
|
+
setArray(key, value) {
|
|
131
|
+
if (typeof key !== 'string') {
|
|
132
|
+
throw new TypeError('Key must be a string');
|
|
133
|
+
}
|
|
134
|
+
if (!Array.isArray(value)) {
|
|
135
|
+
throw new TypeError('Value must be an array');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const success = binding.setArray(this.context, key, value);
|
|
139
|
+
if (!success) {
|
|
140
|
+
throw new Error(`Failed to set array variable: ${key}`);
|
|
141
|
+
}
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Set an object variable in the template context
|
|
147
|
+
* @param {string} key - Variable name
|
|
148
|
+
* @param {Object} value - Object value (plain object, not array)
|
|
149
|
+
* @returns {PugCompiler} - Returns this for chaining
|
|
150
|
+
*/
|
|
151
|
+
setObject(key, value) {
|
|
152
|
+
if (typeof key !== 'string') {
|
|
153
|
+
throw new TypeError('Key must be a string');
|
|
154
|
+
}
|
|
155
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
156
|
+
throw new TypeError('Value must be a plain object');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const success = binding.setObject(this.context, key, value);
|
|
160
|
+
if (!success) {
|
|
161
|
+
throw new Error(`Failed to set object variable: ${key}`);
|
|
162
|
+
}
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
165
|
+
|
|
124
166
|
/**
|
|
125
167
|
* Set a variable (automatically detects type)
|
|
126
168
|
* @param {string} key - Variable name
|
|
127
|
-
* @param {string|number|boolean} value - Value of any supported type
|
|
169
|
+
* @param {string|number|boolean|Array|Object} value - Value of any supported type
|
|
128
170
|
* @returns {PugCompiler} - Returns this for chaining
|
|
129
171
|
*/
|
|
130
172
|
set(key, value) {
|
|
131
|
-
if (
|
|
173
|
+
if (Array.isArray(value)) {
|
|
174
|
+
return this.setArray(key, value);
|
|
175
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
176
|
+
return this.setObject(key, value);
|
|
177
|
+
} else if (typeof value === 'string') {
|
|
132
178
|
return this.setString(key, value);
|
|
133
179
|
} else if (typeof value === 'number') {
|
|
134
180
|
return this.setNumber(key, value);
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zig-pug",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "High-performance Pug template engine powered by Zig and mujs. Native N-API addon with ES5.1 JavaScript support, full UTF-8 (emoji, accents),
|
|
3
|
+
"version": "4.0.1",
|
|
4
|
+
"description": "High-performance Pug template engine powered by Zig and mujs. Native N-API addon with ES5.1 JavaScript support, full UTF-8 (emoji, accents), Builder API for dynamic data construction, comprehensive C/C++ API, and fast compilation. Compatible with Node.js and Bun.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
7
8
|
"exports": {
|
|
8
9
|
".": {
|
|
10
|
+
"types": "./index.d.ts",
|
|
9
11
|
"import": "./index.mjs",
|
|
10
12
|
"require": "./index.js"
|
|
11
13
|
}
|
|
@@ -14,7 +16,8 @@
|
|
|
14
16
|
"install": "node install.js",
|
|
15
17
|
"postinstall": "node install.js",
|
|
16
18
|
"build": "node-gyp configure build",
|
|
17
|
-
"rebuild": "node-gyp rebuild",
|
|
19
|
+
"rebuild": "npm run prebuild-fix && node-gyp rebuild",
|
|
20
|
+
"prebuild-fix": "node prebuild-fix.js",
|
|
18
21
|
"clean": "node-gyp clean",
|
|
19
22
|
"test": "node test/test.js",
|
|
20
23
|
"build-prebuilts": "./build-prebuilts.sh",
|
|
@@ -55,7 +58,14 @@
|
|
|
55
58
|
"spanish",
|
|
56
59
|
"portuguese",
|
|
57
60
|
"french",
|
|
58
|
-
"german"
|
|
61
|
+
"german",
|
|
62
|
+
"c-api",
|
|
63
|
+
"c++",
|
|
64
|
+
"cpp",
|
|
65
|
+
"ffi",
|
|
66
|
+
"builder-api",
|
|
67
|
+
"dynamic-data",
|
|
68
|
+
"type-safe"
|
|
59
69
|
],
|
|
60
70
|
"author": {
|
|
61
71
|
"name": "zig-pug contributors",
|
|
@@ -87,7 +97,9 @@
|
|
|
87
97
|
"files": [
|
|
88
98
|
"index.js",
|
|
89
99
|
"index.mjs",
|
|
100
|
+
"index.d.ts",
|
|
90
101
|
"install.js",
|
|
102
|
+
"prebuild-fix.js",
|
|
91
103
|
"binding.c",
|
|
92
104
|
"binding.gyp",
|
|
93
105
|
"common.gypi",
|
package/prebuild-fix.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Fix for node-gyp build issues in Termux/Android
|
|
3
|
+
// Creates necessary directories and files that make expects to exist
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
const depsDir = path.join(__dirname, 'build', 'Release', '.deps', 'Release', 'obj.target', 'zigpug');
|
|
9
|
+
const depsFile = path.join(depsDir, 'binding.o.d.raw');
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
// Create directory structure
|
|
13
|
+
fs.mkdirSync(depsDir, { recursive: true });
|
|
14
|
+
|
|
15
|
+
// Create empty file if it doesn't exist
|
|
16
|
+
if (!fs.existsSync(depsFile)) {
|
|
17
|
+
fs.writeFileSync(depsFile, '');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
console.log('✓ Pre-build fix applied for Termux/Android compatibility');
|
|
21
|
+
} catch (err) {
|
|
22
|
+
// Ignore errors - this is just a workaround
|
|
23
|
+
console.log('⚠ Pre-build fix skipped:', err.message);
|
|
24
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|