spooder 4.2.5 → 4.2.7

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 CHANGED
@@ -432,7 +432,7 @@ In addition to the information provided by the developer, `spooder` also include
432
432
  - [`panic(err_message_or_obj: string | object, ...err: object[]): Promise<void>`](#api-error-handling-panic)
433
433
  - [`safe(fn: Callable): Promise<void>`](#api-error-handling-safe)
434
434
  - [API > Content](#api-content)
435
- - [`parse_template(template: string, replacements: Record<string, string>): string`](#api-content-parse-template)
435
+ - [`parse_template(template: string, replacements: Record<string, string>, drop_missing: boolean): string`](#api-content-parse-template)
436
436
  - [`generate_hash_subs(length: number, prefix: string): Promise<Record<string, string>>`](#api-content-generate-hash-subs)
437
437
  - [`apply_range(file: BunFile, request: Request): HandlerReturnType`](#api-content-apply-range)
438
438
  - [API > State Management](#api-state-management)
@@ -901,13 +901,10 @@ await safe(() => {
901
901
  ## API > Content
902
902
 
903
903
  <a id="api-content-parse-template"></a>
904
- ### 🔧 `parse_template(template: string, replacements: Record<string, string>): string`
904
+ ### 🔧 `parse_template(template: string, replacements: Record<string, string>, drop_missing: boolean): string`
905
905
 
906
906
  Replace placeholders in a template string with values from a replacement object.
907
907
 
908
- > [!NOTE]
909
- > Placeholders that do not appear in the replacement object will be left as-is. See `ignored` in below example.
910
-
911
908
  ```ts
912
909
  const template = `
913
910
  <html>
@@ -943,6 +940,25 @@ const html = parse_template(template, replacements);
943
940
  </html>
944
941
  ```
945
942
 
943
+ By default, placeholders that do not appear in the replacement object will be left as-is. Set `drop_missing` to `true` to remove them.
944
+
945
+ ```ts
946
+ parse_template(template, replacements, true);
947
+ ```
948
+
949
+ ```html
950
+ <html>
951
+ <head>
952
+ <title>Hello, world!</title>
953
+ </head>
954
+ <body>
955
+ <h1>Hello, world!</h1>
956
+ <p>This is a test.</p>
957
+ <p></p>
958
+ </body>
959
+ </html>
960
+ ```
961
+
946
962
  `parse_template` supports looping arrays with the following syntax.
947
963
 
948
964
  ```html
@@ -970,8 +986,25 @@ const html = parse_template(template, replacements);
970
986
  </ul>
971
987
  ```
972
988
 
973
- > [!WARNING]
974
- > Nested loops are not supported.
989
+ All placeholders inside a `{$for:}` loop are substituted, but only if the loop variable exists.
990
+
991
+ In the following example, `missing` does not exist, so `test` is not substituted inside the loop, but `test` is still substituted outside the loop.
992
+
993
+ ```html
994
+ <div>Hello {$test}!</div>
995
+ {$for:missing}<div>Loop {$test}</div>{/for}
996
+ ```
997
+
998
+ ```ts
999
+ parse_template(..., {
1000
+ test: 'world'
1001
+ });
1002
+ ```
1003
+
1004
+ ```html
1005
+ <div>Hello world!</div>
1006
+ {$for}Loop <div>{$test}</div>{/for}
1007
+ ```
975
1008
 
976
1009
  <a id="api-content-generate-hash-subs"></a>
977
1010
  ### 🔧 `generate_hash_subs(prefix: string): Promise<Record<string, string>>`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "spooder",
3
3
  "type": "module",
4
- "version": "4.2.5",
4
+ "version": "4.2.7",
5
5
  "exports": {
6
6
  ".": {
7
7
  "bun": "./src/api.ts",
package/src/api.d.ts CHANGED
@@ -18,7 +18,7 @@ export declare function caution(err_message_or_obj: string | object, ...err: obj
18
18
  type CallableFunction = (...args: any[]) => any;
19
19
  type Callable = Promise<any> | CallableFunction;
20
20
  export declare function safe(target_fn: Callable): Promise<void>;
21
- export declare function parse_template(template: string, replacements: Record<string, string | Array<string>>): string;
21
+ export declare function parse_template(template: string, replacements: Record<string, string | Array<string>>, drop_missing?: boolean): string;
22
22
  export declare function generate_hash_subs(length?: number, prefix?: string): Promise<Record<string, string>>;
23
23
  type CookieOptions = {
24
24
  same_site?: 'Strict' | 'Lax' | 'None';
package/src/api.ts CHANGED
@@ -103,7 +103,7 @@ export async function safe(target_fn: Callable) {
103
103
  }
104
104
  }
105
105
 
106
- export function parse_template(template: string, replacements: Record<string, string | Array<string>>): string {
106
+ export function parse_template(template: string, replacements: Record<string, string | Array<string>>, drop_missing = false): string {
107
107
  let result = '';
108
108
  let buffer = '';
109
109
  let buffer_active = false;
@@ -127,19 +127,27 @@ export function parse_template(template: string, replacements: Record<string, st
127
127
  const loop_close_index = template.indexOf('{/for}', loop_content_start_index);
128
128
 
129
129
  if (loop_close_index === -1) {
130
- result += '{$' + buffer + '}';
130
+ if (!drop_missing)
131
+ result += '{$' + buffer + '}';
131
132
  } else {
132
133
  const loop_content = template.substring(loop_content_start_index, loop_close_index);
133
134
  if (loop_entries !== undefined) {
134
- for (const loop_entry of loop_entries)
135
- result += loop_content.replaceAll('%s', loop_entry);
135
+ for (const loop_entry of loop_entries) {
136
+ const inner_content = loop_content.replaceAll('%s', loop_entry);
137
+ result += parse_template(inner_content, replacements, drop_missing);
138
+ }
136
139
  } else {
137
- result += '{$' + buffer + '}' + loop_content + '{/for}';
140
+ if (!drop_missing)
141
+ result += '{$' + buffer + '}' + loop_content + '{/for}';
138
142
  }
139
143
  i += loop_content.length + 6;
140
144
  }
141
145
  } else {
142
- result += replacements[buffer] ?? '{$' + buffer + '}';
146
+ const replacement = replacements[buffer];
147
+ if (replacement !== undefined)
148
+ result += replacement;
149
+ else if (!drop_missing)
150
+ result += '{$' + buffer + '}';
143
151
  }
144
152
  buffer = '';
145
153
  } else if (buffer_active) {