@netlify/plugin-nextjs 4.40.1 → 4.40.2

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 (161) hide show
  1. package/lib/helpers/edge.js +1 -0
  2. package/lib/templates/vendor.js +20 -0
  3. package/package.json +7 -4
  4. package/src/templates/edge/next-dev.js +3 -3
  5. package/src/templates/edge/shims.js +6 -6
  6. package/src/templates/edge-shared/next-utils.ts +3 -3
  7. package/src/templates/edge-shared/utils.ts +1 -1
  8. package/src/templates/vendor/deno.land/std@0.134.0/fmt/colors.ts +536 -0
  9. package/src/templates/vendor/deno.land/std@0.134.0/testing/_diff.ts +360 -0
  10. package/src/templates/vendor/deno.land/std@0.134.0/testing/asserts.ts +866 -0
  11. package/src/templates/vendor/deno.land/std@0.175.0/_util/asserts.ts +25 -0
  12. package/src/templates/vendor/deno.land/std@0.175.0/_util/os.ts +23 -0
  13. package/src/templates/vendor/deno.land/std@0.175.0/async/abortable.ts +149 -0
  14. package/src/templates/vendor/deno.land/std@0.175.0/async/deadline.ts +30 -0
  15. package/src/templates/vendor/deno.land/std@0.175.0/async/debounce.ts +79 -0
  16. package/src/templates/vendor/deno.land/std@0.175.0/async/deferred.ts +48 -0
  17. package/src/templates/vendor/deno.land/std@0.175.0/async/delay.ts +67 -0
  18. package/src/templates/vendor/deno.land/std@0.175.0/async/mod.ts +18 -0
  19. package/src/templates/vendor/deno.land/std@0.175.0/async/mux_async_iterator.ts +97 -0
  20. package/src/templates/vendor/deno.land/std@0.175.0/async/pool.ts +95 -0
  21. package/src/templates/vendor/deno.land/std@0.175.0/async/retry.ts +81 -0
  22. package/src/templates/vendor/deno.land/std@0.175.0/async/tee.ts +100 -0
  23. package/src/templates/vendor/deno.land/std@0.175.0/bytes/index_of_needle.ts +49 -0
  24. package/src/templates/vendor/deno.land/std@0.175.0/crypto/timing_safe_equal.ts +29 -0
  25. package/src/templates/vendor/deno.land/std@0.175.0/datetime/to_imf.ts +45 -0
  26. package/src/templates/vendor/deno.land/std@0.175.0/encoding/base64.ts +144 -0
  27. package/src/templates/vendor/deno.land/std@0.175.0/encoding/base64url.ts +70 -0
  28. package/src/templates/vendor/deno.land/std@0.175.0/flags/mod.ts +785 -0
  29. package/src/templates/vendor/deno.land/std@0.175.0/fmt/colors.ts +569 -0
  30. package/src/templates/vendor/deno.land/std@0.175.0/fmt/printf.ts +939 -0
  31. package/src/templates/vendor/deno.land/std@0.175.0/http/cookie.ts +403 -0
  32. package/src/templates/vendor/deno.land/std@0.175.0/node/_core.ts +77 -0
  33. package/src/templates/vendor/deno.land/std@0.175.0/node/_events.d.ts +848 -0
  34. package/src/templates/vendor/deno.land/std@0.175.0/node/_events.mjs +1033 -0
  35. package/src/templates/vendor/deno.land/std@0.175.0/node/_global.d.ts +66 -0
  36. package/src/templates/vendor/deno.land/std@0.175.0/node/_next_tick.ts +173 -0
  37. package/src/templates/vendor/deno.land/std@0.175.0/node/_process/exiting.ts +4 -0
  38. package/src/templates/vendor/deno.land/std@0.175.0/node/_process/process.ts +131 -0
  39. package/src/templates/vendor/deno.land/std@0.175.0/node/_process/stdio.mjs +7 -0
  40. package/src/templates/vendor/deno.land/std@0.175.0/node/_process/streams.mjs +146 -0
  41. package/src/templates/vendor/deno.land/std@0.175.0/node/_stream.d.ts +1488 -0
  42. package/src/templates/vendor/deno.land/std@0.175.0/node/_stream.mjs +746 -0
  43. package/src/templates/vendor/deno.land/std@0.175.0/node/_util/_util_callbackify.ts +129 -0
  44. package/src/templates/vendor/deno.land/std@0.175.0/node/_utils.ts +206 -0
  45. package/src/templates/vendor/deno.land/std@0.175.0/node/assert.ts +940 -0
  46. package/src/templates/vendor/deno.land/std@0.175.0/node/assertion_error.ts +579 -0
  47. package/src/templates/vendor/deno.land/std@0.175.0/node/async_hooks.ts +331 -0
  48. package/src/templates/vendor/deno.land/std@0.175.0/node/buffer.ts +13 -0
  49. package/src/templates/vendor/deno.land/std@0.175.0/node/events.ts +14 -0
  50. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/buffer.d.ts +2074 -0
  51. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/buffer.mjs +2607 -0
  52. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/crypto/_keys.ts +16 -0
  53. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/crypto/constants.ts +5 -0
  54. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/error_codes.ts +7 -0
  55. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/errors.ts +2867 -0
  56. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/fixed_queue.ts +123 -0
  57. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/hide_stack_frames.ts +16 -0
  58. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/net.ts +95 -0
  59. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/normalize_encoding.mjs +72 -0
  60. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/options.ts +45 -0
  61. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/primordials.mjs +30 -0
  62. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/process/per_thread.mjs +272 -0
  63. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/readline/callbacks.mjs +137 -0
  64. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/readline/utils.mjs +580 -0
  65. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/streams/destroy.mjs +320 -0
  66. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/streams/end-of-stream.mjs +229 -0
  67. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/streams/utils.mjs +242 -0
  68. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util/comparisons.ts +669 -0
  69. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util/debuglog.ts +118 -0
  70. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util/inspect.mjs +2237 -0
  71. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util/types.ts +113 -0
  72. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/util.mjs +143 -0
  73. package/src/templates/vendor/deno.land/std@0.175.0/node/internal/validators.mjs +317 -0
  74. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_libuv_winerror.ts +229 -0
  75. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_listen.ts +16 -0
  76. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_node.ts +18 -0
  77. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_timingSafeEqual.ts +12 -0
  78. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_utils.ts +86 -0
  79. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/_winerror.ts +16873 -0
  80. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/ares.ts +66 -0
  81. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/async_wrap.ts +152 -0
  82. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/buffer.ts +130 -0
  83. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/cares_wrap.ts +541 -0
  84. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/config.ts +3 -0
  85. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/connection_wrap.ts +80 -0
  86. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/constants.ts +900 -0
  87. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/contextify.ts +3 -0
  88. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/credentials.ts +3 -0
  89. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/crypto.ts +14 -0
  90. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/errors.ts +3 -0
  91. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/fs.ts +3 -0
  92. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/fs_dir.ts +3 -0
  93. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/fs_event_wrap.ts +3 -0
  94. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/handle_wrap.ts +50 -0
  95. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/heap_utils.ts +3 -0
  96. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/http_parser.ts +3 -0
  97. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/icu.ts +3 -0
  98. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/inspector.ts +3 -0
  99. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/js_stream.ts +3 -0
  100. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/messaging.ts +3 -0
  101. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/mod.ts +108 -0
  102. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/module_wrap.ts +3 -0
  103. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/native_module.ts +3 -0
  104. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/natives.ts +3 -0
  105. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/node_file.ts +84 -0
  106. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/node_options.ts +39 -0
  107. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/options.ts +3 -0
  108. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/os.ts +3 -0
  109. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/performance.ts +3 -0
  110. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/pipe_wrap.ts +392 -0
  111. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/process_methods.ts +3 -0
  112. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/report.ts +3 -0
  113. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/serdes.ts +3 -0
  114. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/signal_wrap.ts +3 -0
  115. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/spawn_sync.ts +3 -0
  116. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/stream_wrap.ts +354 -0
  117. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/string_decoder.ts +15 -0
  118. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/symbols.ts +27 -0
  119. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/task_queue.ts +3 -0
  120. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/tcp_wrap.ts +488 -0
  121. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/timers.ts +3 -0
  122. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/tls_wrap.ts +3 -0
  123. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/trace_events.ts +3 -0
  124. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/tty_wrap.ts +3 -0
  125. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/types.ts +186 -0
  126. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/udp_wrap.ts +496 -0
  127. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/url.ts +3 -0
  128. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/util.ts +126 -0
  129. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/uv.ts +437 -0
  130. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/v8.ts +3 -0
  131. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/worker.ts +3 -0
  132. package/src/templates/vendor/deno.land/std@0.175.0/node/internal_binding/zlib.ts +3 -0
  133. package/src/templates/vendor/deno.land/std@0.175.0/node/process.ts +705 -0
  134. package/src/templates/vendor/deno.land/std@0.175.0/node/stream.ts +37 -0
  135. package/src/templates/vendor/deno.land/std@0.175.0/node/string_decoder.ts +337 -0
  136. package/src/templates/vendor/deno.land/std@0.175.0/node/util/types.ts +4 -0
  137. package/src/templates/vendor/deno.land/std@0.175.0/node/util.ts +289 -0
  138. package/src/templates/vendor/deno.land/std@0.175.0/path/_constants.ts +49 -0
  139. package/src/templates/vendor/deno.land/std@0.175.0/path/_interface.ts +30 -0
  140. package/src/templates/vendor/deno.land/std@0.175.0/path/_util.ts +194 -0
  141. package/src/templates/vendor/deno.land/std@0.175.0/path/common.ts +40 -0
  142. package/src/templates/vendor/deno.land/std@0.175.0/path/glob.ts +418 -0
  143. package/src/templates/vendor/deno.land/std@0.175.0/path/mod.ts +53 -0
  144. package/src/templates/vendor/deno.land/std@0.175.0/path/posix.ts +487 -0
  145. package/src/templates/vendor/deno.land/std@0.175.0/path/separator.ts +7 -0
  146. package/src/templates/vendor/deno.land/std@0.175.0/path/win32.ts +962 -0
  147. package/src/templates/vendor/deno.land/std@0.175.0/streams/write_all.ts +64 -0
  148. package/src/templates/vendor/deno.land/std@0.175.0/testing/_diff.ts +440 -0
  149. package/src/templates/vendor/deno.land/std@0.175.0/testing/_format.ts +23 -0
  150. package/src/templates/vendor/deno.land/std@0.175.0/testing/asserts.ts +906 -0
  151. package/src/templates/vendor/deno.land/std@0.175.0/types.d.ts +89 -0
  152. package/src/templates/vendor/deno.land/x/html_rewriter@v0.1.0-pre.17/index.ts +133 -0
  153. package/src/templates/vendor/deno.land/x/html_rewriter@v0.1.0-pre.17/vendor/asyncify.js +112 -0
  154. package/src/templates/vendor/deno.land/x/html_rewriter@v0.1.0-pre.17/vendor/html_rewriter.d.ts +88 -0
  155. package/src/templates/vendor/deno.land/x/html_rewriter@v0.1.0-pre.17/vendor/html_rewriter.js +974 -0
  156. package/src/templates/vendor/deno.land/x/path_to_regexp@v6.2.1/index.ts +621 -0
  157. package/src/templates/vendor/esm.sh/v91/next@12.2.5/deno/dist/compiled/cookie.js +13 -0
  158. package/src/templates/vendor/esm.sh/v91/next@12.2.5/deno/dist/server/web/spec-extension/request.js +12 -0
  159. package/src/templates/vendor/esm.sh/v91/next@12.2.5/deno/dist/server/web/spec-extension/response.js +5 -0
  160. package/src/templates/vendor/import_map.json +13 -0
  161. package/src/templates/vendor/raw.githubusercontent.com/worker-tools/resolvable-promise/master/index.ts +50 -0
@@ -0,0 +1,939 @@
1
+ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
2
+
3
+ /**
4
+ * {@linkcode sprintf} and {@linkcode printf} for printing formatted strings to
5
+ * stdout.
6
+ *
7
+ * This implementation is inspired by POSIX and Golang but does not port
8
+ * implementation code.
9
+ *
10
+ * sprintf converts and formats a variable number of arguments as is specified
11
+ * by a `format string`. In it's basic form, a format string may just be a
12
+ * literal. In case arguments are meant to be formatted, a `directive` is
13
+ * contained in the format string, preceded by a '%' character:
14
+ *
15
+ * %<verb>
16
+ *
17
+ * E.g. the verb `s` indicates the directive should be replaced by the string
18
+ * representation of the argument in the corresponding position of the argument
19
+ * list. E.g.:
20
+ *
21
+ * Hello %s!
22
+ *
23
+ * applied to the arguments "World" yields "Hello World!".
24
+ *
25
+ * The meaning of the format string is modelled after [POSIX][1] format strings
26
+ * as well as well as [Golang format strings][2]. Both contain elements specific
27
+ * to the respective programming language that don't apply to JavaScript, so
28
+ * they can not be fully supported. Furthermore we implement some functionality
29
+ * that is specific to JS.
30
+ *
31
+ * ## Verbs
32
+ *
33
+ * The following verbs are supported:
34
+ *
35
+ * | Verb | Meaning |
36
+ * | ----- | -------------------------------------------------------------- |
37
+ * | `%` | print a literal percent |
38
+ * | `t` | evaluate arg as boolean, print `true` or `false` |
39
+ * | `b` | eval as number, print binary |
40
+ * | `c` | eval as number, print character corresponding to the codePoint |
41
+ * | `o` | eval as number, print octal |
42
+ * | `x X` | print as hex (ff FF), treat string as list of bytes |
43
+ * | `e E` | print number in scientific/exponent format 1.123123e+01 |
44
+ * | `f F` | print number as float with decimal point and no exponent |
45
+ * | `g G` | use %e %E or %f %F depending on size of argument |
46
+ * | `s` | interpolate string |
47
+ * | `T` | type of arg, as returned by `typeof` |
48
+ * | `v` | value of argument in 'default' format (see below) |
49
+ * | `j` | argument as formatted by `JSON.stringify` |
50
+ * | `i` | argument as formatted by `Deno.inspect` |
51
+ * | `I` | argument as formatted by `Deno.inspect` in compact format |
52
+ *
53
+ * ## Width and Precision
54
+ *
55
+ * Verbs may be modified by providing them with width and precision, either or
56
+ * both may be omitted:
57
+ *
58
+ * %9f width 9, default precision
59
+ * %.9f default width, precision 9
60
+ * %8.9f width 8, precision 9
61
+ * %8.f width 9, precision 0
62
+ *
63
+ * In general, 'width' describes the minimum length of the output, while
64
+ * 'precision' limits the output.
65
+ *
66
+ * | verb | precision |
67
+ * | --------- | --------------------------------------------------------------- |
68
+ * | `t` | n/a |
69
+ * | `b c o` | n/a |
70
+ * | `x X` | n/a for number, strings are truncated to p bytes(!) |
71
+ * | `e E f F` | number of places after decimal, default 6 |
72
+ * | `g G` | set maximum number of digits |
73
+ * | `s` | truncate input |
74
+ * | `T` | truncate |
75
+ * | `v` | truncate, or depth if used with # see "'default' format", below |
76
+ * | `j` | n/a |
77
+ *
78
+ * Numerical values for width and precision can be substituted for the `*` char,
79
+ * in which case the values are obtained from the next args, e.g.:
80
+ *
81
+ * sprintf("%*.*f", 9, 8, 456.0)
82
+ *
83
+ * is equivalent to:
84
+ *
85
+ * sprintf("%9.8f", 456.0)
86
+ *
87
+ * ## Flags
88
+ *
89
+ * The effects of the verb may be further influenced by using flags to modify
90
+ * the directive:
91
+ *
92
+ * | Flag | Verb | Meaning |
93
+ * | ----- | --------- | -------------------------------------------------------------------------- |
94
+ * | `+` | numeric | always print sign |
95
+ * | `-` | all | pad to the right (left justify) |
96
+ * | `#` | | alternate format |
97
+ * | `#` | `b o x X` | prefix with `0b 0 0x` |
98
+ * | `#` | `g G` | don't remove trailing zeros |
99
+ * | `#` | `v` | ues output of `inspect` instead of `toString` |
100
+ * | `' '` | | space character |
101
+ * | `' '` | `x X` | leave spaces between bytes when printing string |
102
+ * | `' '` | `d` | insert space for missing `+` sign character |
103
+ * | `0` | all | pad with zero, `-` takes precedence, sign is appended in front of padding |
104
+ * | `<` | all | format elements of the passed array according to the directive (extension) |
105
+ *
106
+ * ## 'default' format
107
+ *
108
+ * The default format used by `%v` is the result of calling `toString()` on the
109
+ * relevant argument. If the `#` flags is used, the result of calling `inspect()`
110
+ * is interpolated. In this case, the precision, if set is passed to `inspect()`
111
+ * as the 'depth' config parameter.
112
+ *
113
+ * ## Positional arguments
114
+ *
115
+ * Arguments do not need to be consumed in the order they are provided and may
116
+ * be consumed more than once. E.g.:
117
+ *
118
+ * sprintf("%[2]s %[1]s", "World", "Hello")
119
+ *
120
+ * returns "Hello World". The presence of a positional indicator resets the arg
121
+ * counter allowing args to be reused:
122
+ *
123
+ * sprintf("dec[%d]=%d hex[%[1]d]=%x oct[%[1]d]=%#o %s", 1, 255, "Third")
124
+ *
125
+ * returns `dec[1]=255 hex[1]=0xff oct[1]=0377 Third`
126
+ *
127
+ * Width and precision my also use positionals:
128
+ *
129
+ * "%[2]*.[1]*d", 1, 2
130
+ *
131
+ * This follows the golang conventions and not POSIX.
132
+ *
133
+ * ## Errors
134
+ *
135
+ * The following errors are handled:
136
+ *
137
+ * Incorrect verb:
138
+ *
139
+ * S("%h", "") %!(BAD VERB 'h')
140
+ *
141
+ * Too few arguments:
142
+ *
143
+ * S("%d") %!(MISSING 'd')"
144
+ *
145
+ * [1]: https://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
146
+ * [2]: https://golang.org/pkg/fmt/
147
+ *
148
+ * @module
149
+ */
150
+
151
+ enum State {
152
+ PASSTHROUGH,
153
+ PERCENT,
154
+ POSITIONAL,
155
+ PRECISION,
156
+ WIDTH,
157
+ }
158
+
159
+ enum WorP {
160
+ WIDTH,
161
+ PRECISION,
162
+ }
163
+
164
+ class Flags {
165
+ plus?: boolean;
166
+ dash?: boolean;
167
+ sharp?: boolean;
168
+ space?: boolean;
169
+ zero?: boolean;
170
+ lessthan?: boolean;
171
+ width = -1;
172
+ precision = -1;
173
+ }
174
+
175
+ const min = Math.min;
176
+ const UNICODE_REPLACEMENT_CHARACTER = "\ufffd";
177
+ const DEFAULT_PRECISION = 6;
178
+ const FLOAT_REGEXP = /(-?)(\d)\.?(\d*)e([+-])(\d+)/;
179
+
180
+ enum F {
181
+ sign = 1,
182
+ mantissa,
183
+ fractional,
184
+ esign,
185
+ exponent,
186
+ }
187
+
188
+ class Printf {
189
+ format: string;
190
+ args: unknown[];
191
+ i: number;
192
+
193
+ state: State = State.PASSTHROUGH;
194
+ verb = "";
195
+ buf = "";
196
+ argNum = 0;
197
+ flags: Flags = new Flags();
198
+
199
+ haveSeen: boolean[];
200
+
201
+ // barf, store precision and width errors for later processing ...
202
+ tmpError?: string;
203
+
204
+ constructor(format: string, ...args: unknown[]) {
205
+ this.format = format;
206
+ this.args = args;
207
+ this.haveSeen = Array.from({ length: args.length });
208
+ this.i = 0;
209
+ }
210
+
211
+ doPrintf(): string {
212
+ for (; this.i < this.format.length; ++this.i) {
213
+ const c = this.format[this.i];
214
+ switch (this.state) {
215
+ case State.PASSTHROUGH:
216
+ if (c === "%") {
217
+ this.state = State.PERCENT;
218
+ } else {
219
+ this.buf += c;
220
+ }
221
+ break;
222
+ case State.PERCENT:
223
+ if (c === "%") {
224
+ this.buf += c;
225
+ this.state = State.PASSTHROUGH;
226
+ } else {
227
+ this.handleFormat();
228
+ }
229
+ break;
230
+ default:
231
+ throw Error("Should be unreachable, certainly a bug in the lib.");
232
+ }
233
+ }
234
+ // check for unhandled args
235
+ let extras = false;
236
+ let err = "%!(EXTRA";
237
+ for (let i = 0; i !== this.haveSeen.length; ++i) {
238
+ if (!this.haveSeen[i]) {
239
+ extras = true;
240
+ err += ` '${Deno.inspect(this.args[i])}'`;
241
+ }
242
+ }
243
+ err += ")";
244
+ if (extras) {
245
+ this.buf += err;
246
+ }
247
+ return this.buf;
248
+ }
249
+
250
+ // %[<positional>]<flag>...<verb>
251
+ handleFormat() {
252
+ this.flags = new Flags();
253
+ const flags = this.flags;
254
+ for (; this.i < this.format.length; ++this.i) {
255
+ const c = this.format[this.i];
256
+ switch (this.state) {
257
+ case State.PERCENT:
258
+ switch (c) {
259
+ case "[":
260
+ this.handlePositional();
261
+ this.state = State.POSITIONAL;
262
+ break;
263
+ case "+":
264
+ flags.plus = true;
265
+ break;
266
+ case "<":
267
+ flags.lessthan = true;
268
+ break;
269
+ case "-":
270
+ flags.dash = true;
271
+ flags.zero = false; // only left pad zeros, dash takes precedence
272
+ break;
273
+ case "#":
274
+ flags.sharp = true;
275
+ break;
276
+ case " ":
277
+ flags.space = true;
278
+ break;
279
+ case "0":
280
+ // only left pad zeros, dash takes precedence
281
+ flags.zero = !flags.dash;
282
+ break;
283
+ default:
284
+ if (("1" <= c && c <= "9") || c === "." || c === "*") {
285
+ if (c === ".") {
286
+ this.flags.precision = 0;
287
+ this.state = State.PRECISION;
288
+ this.i++;
289
+ } else {
290
+ this.state = State.WIDTH;
291
+ }
292
+ this.handleWidthAndPrecision(flags);
293
+ } else {
294
+ this.handleVerb();
295
+ return; // always end in verb
296
+ }
297
+ } // switch c
298
+ break;
299
+ case State.POSITIONAL:
300
+ // TODO(bartlomieju): either a verb or * only verb for now
301
+ if (c === "*") {
302
+ const worp = this.flags.precision === -1
303
+ ? WorP.WIDTH
304
+ : WorP.PRECISION;
305
+ this.handleWidthOrPrecisionRef(worp);
306
+ this.state = State.PERCENT;
307
+ break;
308
+ } else {
309
+ this.handleVerb();
310
+ return; // always end in verb
311
+ }
312
+ default:
313
+ throw new Error(`Should not be here ${this.state}, library bug!`);
314
+ } // switch state
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Handle width or precision
320
+ * @param wOrP
321
+ */
322
+ handleWidthOrPrecisionRef(wOrP: WorP) {
323
+ if (this.argNum >= this.args.length) {
324
+ // handle Positional should have already taken care of it...
325
+ return;
326
+ }
327
+ const arg = this.args[this.argNum];
328
+ this.haveSeen[this.argNum] = true;
329
+ if (typeof arg === "number") {
330
+ switch (wOrP) {
331
+ case WorP.WIDTH:
332
+ this.flags.width = arg;
333
+ break;
334
+ default:
335
+ this.flags.precision = arg;
336
+ }
337
+ } else {
338
+ const tmp = wOrP === WorP.WIDTH ? "WIDTH" : "PREC";
339
+ this.tmpError = `%!(BAD ${tmp} '${this.args[this.argNum]}')`;
340
+ }
341
+ this.argNum++;
342
+ }
343
+
344
+ /**
345
+ * Handle width and precision
346
+ * @param flags
347
+ */
348
+ handleWidthAndPrecision(flags: Flags) {
349
+ const fmt = this.format;
350
+ for (; this.i !== this.format.length; ++this.i) {
351
+ const c = fmt[this.i];
352
+ switch (this.state) {
353
+ case State.WIDTH:
354
+ switch (c) {
355
+ case ".":
356
+ // initialize precision, %9.f -> precision=0
357
+ this.flags.precision = 0;
358
+ this.state = State.PRECISION;
359
+ break;
360
+ case "*":
361
+ this.handleWidthOrPrecisionRef(WorP.WIDTH);
362
+ // force . or flag at this point
363
+ break;
364
+ default: {
365
+ const val = parseInt(c);
366
+ // most likely parseInt does something stupid that makes
367
+ // it unusable for this scenario ...
368
+ // if we encounter a non (number|*|.) we're done with prec & wid
369
+ if (isNaN(val)) {
370
+ this.i--;
371
+ this.state = State.PERCENT;
372
+ return;
373
+ }
374
+ flags.width = flags.width == -1 ? 0 : flags.width;
375
+ flags.width *= 10;
376
+ flags.width += val;
377
+ }
378
+ } // switch c
379
+ break;
380
+ case State.PRECISION: {
381
+ if (c === "*") {
382
+ this.handleWidthOrPrecisionRef(WorP.PRECISION);
383
+ break;
384
+ }
385
+ const val = parseInt(c);
386
+ if (isNaN(val)) {
387
+ // one too far, rewind
388
+ this.i--;
389
+ this.state = State.PERCENT;
390
+ return;
391
+ }
392
+ flags.precision *= 10;
393
+ flags.precision += val;
394
+ break;
395
+ }
396
+ default:
397
+ throw new Error("can't be here. bug.");
398
+ } // switch state
399
+ }
400
+ }
401
+
402
+ /** Handle positional */
403
+ handlePositional() {
404
+ if (this.format[this.i] !== "[") {
405
+ // sanity only
406
+ throw new Error("Can't happen? Bug.");
407
+ }
408
+ let positional = 0;
409
+ const format = this.format;
410
+ this.i++;
411
+ let err = false;
412
+ for (; this.i !== this.format.length; ++this.i) {
413
+ if (format[this.i] === "]") {
414
+ break;
415
+ }
416
+ positional *= 10;
417
+ const val = parseInt(format[this.i]);
418
+ if (isNaN(val)) {
419
+ //throw new Error(
420
+ // `invalid character in positional: ${format}[${format[this.i]}]`
421
+ //);
422
+ this.tmpError = "%!(BAD INDEX)";
423
+ err = true;
424
+ }
425
+ positional += val;
426
+ }
427
+ if (positional - 1 >= this.args.length) {
428
+ this.tmpError = "%!(BAD INDEX)";
429
+ err = true;
430
+ }
431
+ this.argNum = err ? this.argNum : positional - 1;
432
+ }
433
+
434
+ /** Handle less than */
435
+ handleLessThan(): string {
436
+ // deno-lint-ignore no-explicit-any
437
+ const arg = this.args[this.argNum] as any;
438
+ if ((arg || {}).constructor.name !== "Array") {
439
+ throw new Error(`arg ${arg} is not an array. Todo better error handling`);
440
+ }
441
+ let str = "[ ";
442
+ for (let i = 0; i !== arg.length; ++i) {
443
+ if (i !== 0) str += ", ";
444
+ str += this._handleVerb(arg[i]);
445
+ }
446
+ return str + " ]";
447
+ }
448
+
449
+ /** Handle verb */
450
+ handleVerb() {
451
+ const verb = this.format[this.i];
452
+ this.verb = verb;
453
+ if (this.tmpError) {
454
+ this.buf += this.tmpError;
455
+ this.tmpError = undefined;
456
+ if (this.argNum < this.haveSeen.length) {
457
+ this.haveSeen[this.argNum] = true; // keep track of used args
458
+ }
459
+ } else if (this.args.length <= this.argNum) {
460
+ this.buf += `%!(MISSING '${verb}')`;
461
+ } else {
462
+ const arg = this.args[this.argNum]; // check out of range
463
+ this.haveSeen[this.argNum] = true; // keep track of used args
464
+ if (this.flags.lessthan) {
465
+ this.buf += this.handleLessThan();
466
+ } else {
467
+ this.buf += this._handleVerb(arg);
468
+ }
469
+ }
470
+ this.argNum++; // if there is a further positional, it will reset.
471
+ this.state = State.PASSTHROUGH;
472
+ }
473
+
474
+ // deno-lint-ignore no-explicit-any
475
+ _handleVerb(arg: any): string {
476
+ switch (this.verb) {
477
+ case "t":
478
+ return this.pad(arg.toString());
479
+ case "b":
480
+ return this.fmtNumber(arg as number, 2);
481
+ case "c":
482
+ return this.fmtNumberCodePoint(arg as number);
483
+ case "d":
484
+ return this.fmtNumber(arg as number, 10);
485
+ case "o":
486
+ return this.fmtNumber(arg as number, 8);
487
+ case "x":
488
+ return this.fmtHex(arg);
489
+ case "X":
490
+ return this.fmtHex(arg, true);
491
+ case "e":
492
+ return this.fmtFloatE(arg as number);
493
+ case "E":
494
+ return this.fmtFloatE(arg as number, true);
495
+ case "f":
496
+ case "F":
497
+ return this.fmtFloatF(arg as number);
498
+ case "g":
499
+ return this.fmtFloatG(arg as number);
500
+ case "G":
501
+ return this.fmtFloatG(arg as number, true);
502
+ case "s":
503
+ return this.fmtString(arg as string);
504
+ case "T":
505
+ return this.fmtString(typeof arg);
506
+ case "v":
507
+ return this.fmtV(arg);
508
+ case "j":
509
+ return this.fmtJ(arg);
510
+ case "i":
511
+ return this.fmtI(arg, false);
512
+ case "I":
513
+ return this.fmtI(arg, true);
514
+ default:
515
+ return `%!(BAD VERB '${this.verb}')`;
516
+ }
517
+ }
518
+
519
+ /**
520
+ * Pad a string
521
+ * @param s text to pad
522
+ */
523
+ pad(s: string): string {
524
+ const padding = this.flags.zero ? "0" : " ";
525
+
526
+ if (this.flags.dash) {
527
+ return s.padEnd(this.flags.width, padding);
528
+ }
529
+
530
+ return s.padStart(this.flags.width, padding);
531
+ }
532
+
533
+ /**
534
+ * Pad a number
535
+ * @param nStr
536
+ * @param neg
537
+ */
538
+ padNum(nStr: string, neg: boolean): string {
539
+ let sign: string;
540
+ if (neg) {
541
+ sign = "-";
542
+ } else if (this.flags.plus || this.flags.space) {
543
+ sign = this.flags.plus ? "+" : " ";
544
+ } else {
545
+ sign = "";
546
+ }
547
+ const zero = this.flags.zero;
548
+ if (!zero) {
549
+ // sign comes in front of padding when padding w/ zero,
550
+ // in from of value if padding with spaces.
551
+ nStr = sign + nStr;
552
+ }
553
+
554
+ const pad = zero ? "0" : " ";
555
+ const len = zero ? this.flags.width - sign.length : this.flags.width;
556
+
557
+ if (this.flags.dash) {
558
+ nStr = nStr.padEnd(len, pad);
559
+ } else {
560
+ nStr = nStr.padStart(len, pad);
561
+ }
562
+
563
+ if (zero) {
564
+ // see above
565
+ nStr = sign + nStr;
566
+ }
567
+ return nStr;
568
+ }
569
+
570
+ /**
571
+ * Format a number
572
+ * @param n
573
+ * @param radix
574
+ * @param upcase
575
+ */
576
+ fmtNumber(n: number, radix: number, upcase = false): string {
577
+ let num = Math.abs(n).toString(radix);
578
+ const prec = this.flags.precision;
579
+ if (prec !== -1) {
580
+ this.flags.zero = false;
581
+ num = n === 0 && prec === 0 ? "" : num;
582
+ while (num.length < prec) {
583
+ num = "0" + num;
584
+ }
585
+ }
586
+ let prefix = "";
587
+ if (this.flags.sharp) {
588
+ switch (radix) {
589
+ case 2:
590
+ prefix += "0b";
591
+ break;
592
+ case 8:
593
+ // don't annotate octal 0 with 0...
594
+ prefix += num.startsWith("0") ? "" : "0";
595
+ break;
596
+ case 16:
597
+ prefix += "0x";
598
+ break;
599
+ default:
600
+ throw new Error("cannot handle base: " + radix);
601
+ }
602
+ }
603
+ // don't add prefix in front of value truncated by precision=0, val=0
604
+ num = num.length === 0 ? num : prefix + num;
605
+ if (upcase) {
606
+ num = num.toUpperCase();
607
+ }
608
+ return this.padNum(num, n < 0);
609
+ }
610
+
611
+ /**
612
+ * Format number with code points
613
+ * @param n
614
+ */
615
+ fmtNumberCodePoint(n: number): string {
616
+ let s = "";
617
+ try {
618
+ s = String.fromCodePoint(n);
619
+ } catch {
620
+ s = UNICODE_REPLACEMENT_CHARACTER;
621
+ }
622
+ return this.pad(s);
623
+ }
624
+
625
+ /**
626
+ * Format special float
627
+ * @param n
628
+ */
629
+ fmtFloatSpecial(n: number): string {
630
+ // formatting of NaN and Inf are pants-on-head
631
+ // stupid and more or less arbitrary.
632
+
633
+ if (isNaN(n)) {
634
+ this.flags.zero = false;
635
+ return this.padNum("NaN", false);
636
+ }
637
+ if (n === Number.POSITIVE_INFINITY) {
638
+ this.flags.zero = false;
639
+ this.flags.plus = true;
640
+ return this.padNum("Inf", false);
641
+ }
642
+ if (n === Number.NEGATIVE_INFINITY) {
643
+ this.flags.zero = false;
644
+ return this.padNum("Inf", true);
645
+ }
646
+ return "";
647
+ }
648
+
649
+ /**
650
+ * Round fraction to precision
651
+ * @param fractional
652
+ * @param precision
653
+ * @returns tuple of fractional and round
654
+ */
655
+ roundFractionToPrecision(
656
+ fractional: string,
657
+ precision: number,
658
+ ): [string, boolean] {
659
+ let round = false;
660
+ if (fractional.length > precision) {
661
+ fractional = "1" + fractional; // prepend a 1 in case of leading 0
662
+ let tmp = parseInt(fractional.slice(0, precision + 2)) / 10;
663
+ tmp = Math.round(tmp);
664
+ fractional = Math.floor(tmp).toString();
665
+ round = fractional[0] === "2";
666
+ fractional = fractional.slice(1); // remove extra 1
667
+ } else {
668
+ while (fractional.length < precision) {
669
+ fractional += "0";
670
+ }
671
+ }
672
+ return [fractional, round];
673
+ }
674
+
675
+ /**
676
+ * Format float E
677
+ * @param n
678
+ * @param upcase
679
+ */
680
+ fmtFloatE(n: number, upcase = false): string {
681
+ const special = this.fmtFloatSpecial(n);
682
+ if (special !== "") {
683
+ return special;
684
+ }
685
+
686
+ const m = n.toExponential().match(FLOAT_REGEXP);
687
+ if (!m) {
688
+ throw Error("can't happen, bug");
689
+ }
690
+ let fractional = m[F.fractional];
691
+ const precision = this.flags.precision !== -1
692
+ ? this.flags.precision
693
+ : DEFAULT_PRECISION;
694
+ let rounding = false;
695
+ [fractional, rounding] = this.roundFractionToPrecision(
696
+ fractional,
697
+ precision,
698
+ );
699
+
700
+ let e = m[F.exponent];
701
+ let esign = m[F.esign];
702
+ // scientific notation output with exponent padded to minlen 2
703
+ let mantissa = parseInt(m[F.mantissa]);
704
+ if (rounding) {
705
+ mantissa += 1;
706
+ if (10 <= mantissa) {
707
+ mantissa = 1;
708
+ const r = parseInt(esign + e) + 1;
709
+ e = r.toString();
710
+ esign = r < 0 ? "-" : "+";
711
+ }
712
+ }
713
+ e = e.length == 1 ? "0" + e : e;
714
+ const val = `${mantissa}.${fractional}${upcase ? "E" : "e"}${esign}${e}`;
715
+ return this.padNum(val, n < 0);
716
+ }
717
+
718
+ /**
719
+ * Format float F
720
+ * @param n
721
+ */
722
+ fmtFloatF(n: number): string {
723
+ const special = this.fmtFloatSpecial(n);
724
+ if (special !== "") {
725
+ return special;
726
+ }
727
+
728
+ // stupid helper that turns a number into a (potentially)
729
+ // VERY long string.
730
+ function expandNumber(n: number): string {
731
+ if (Number.isSafeInteger(n)) {
732
+ return n.toString() + ".";
733
+ }
734
+
735
+ const t = n.toExponential().split("e");
736
+ let m = t[0].replace(".", "");
737
+ const e = parseInt(t[1]);
738
+ if (e < 0) {
739
+ let nStr = "0.";
740
+ for (let i = 0; i !== Math.abs(e) - 1; ++i) {
741
+ nStr += "0";
742
+ }
743
+ return (nStr += m);
744
+ } else {
745
+ const splIdx = e + 1;
746
+ while (m.length < splIdx) {
747
+ m += "0";
748
+ }
749
+ return m.slice(0, splIdx) + "." + m.slice(splIdx);
750
+ }
751
+ }
752
+ // avoiding sign makes padding easier
753
+ const val = expandNumber(Math.abs(n)) as string;
754
+ const arr = val.split(".");
755
+ let dig = arr[0];
756
+ let fractional = arr[1];
757
+
758
+ const precision = this.flags.precision !== -1
759
+ ? this.flags.precision
760
+ : DEFAULT_PRECISION;
761
+ let round = false;
762
+ [fractional, round] = this.roundFractionToPrecision(fractional, precision);
763
+ if (round) {
764
+ dig = (parseInt(dig) + 1).toString();
765
+ }
766
+ return this.padNum(`${dig}.${fractional}`, n < 0);
767
+ }
768
+
769
+ /**
770
+ * Format float G
771
+ * @param n
772
+ * @param upcase
773
+ */
774
+ fmtFloatG(n: number, upcase = false): string {
775
+ const special = this.fmtFloatSpecial(n);
776
+ if (special !== "") {
777
+ return special;
778
+ }
779
+
780
+ // The double argument representing a floating-point number shall be
781
+ // converted in the style f or e (or in the style F or E in
782
+ // the case of a G conversion specifier), depending on the
783
+ // value converted and the precision. Let P equal the
784
+ // precision if non-zero, 6 if the precision is omitted, or 1
785
+ // if the precision is zero. Then, if a conversion with style E would
786
+ // have an exponent of X:
787
+
788
+ // - If P > X>=-4, the conversion shall be with style f (or F )
789
+ // and precision P -( X+1).
790
+
791
+ // - Otherwise, the conversion shall be with style e (or E )
792
+ // and precision P -1.
793
+
794
+ // Finally, unless the '#' flag is used, any trailing zeros shall be
795
+ // removed from the fractional portion of the result and the
796
+ // decimal-point character shall be removed if there is no
797
+ // fractional portion remaining.
798
+
799
+ // A double argument representing an infinity or NaN shall be
800
+ // converted in the style of an f or F conversion specifier.
801
+ // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html
802
+
803
+ let P = this.flags.precision !== -1
804
+ ? this.flags.precision
805
+ : DEFAULT_PRECISION;
806
+ P = P === 0 ? 1 : P;
807
+
808
+ const m = n.toExponential().match(FLOAT_REGEXP);
809
+ if (!m) {
810
+ throw Error("can't happen");
811
+ }
812
+
813
+ const X = parseInt(m[F.exponent]) * (m[F.esign] === "-" ? -1 : 1);
814
+ let nStr = "";
815
+ if (P > X && X >= -4) {
816
+ this.flags.precision = P - (X + 1);
817
+ nStr = this.fmtFloatF(n);
818
+ if (!this.flags.sharp) {
819
+ nStr = nStr.replace(/\.?0*$/, "");
820
+ }
821
+ } else {
822
+ this.flags.precision = P - 1;
823
+ nStr = this.fmtFloatE(n);
824
+ if (!this.flags.sharp) {
825
+ nStr = nStr.replace(/\.?0*e/, upcase ? "E" : "e");
826
+ }
827
+ }
828
+ return nStr;
829
+ }
830
+
831
+ /**
832
+ * Format string
833
+ * @param s
834
+ */
835
+ fmtString(s: string): string {
836
+ if (this.flags.precision !== -1) {
837
+ s = s.slice(0, this.flags.precision);
838
+ }
839
+ return this.pad(s);
840
+ }
841
+
842
+ /**
843
+ * Format hex
844
+ * @param val
845
+ * @param upper
846
+ */
847
+ fmtHex(val: string | number, upper = false): string {
848
+ // allow others types ?
849
+ switch (typeof val) {
850
+ case "number":
851
+ return this.fmtNumber(val as number, 16, upper);
852
+ case "string": {
853
+ const sharp = this.flags.sharp && val.length !== 0;
854
+ let hex = sharp ? "0x" : "";
855
+ const prec = this.flags.precision;
856
+ const end = prec !== -1 ? min(prec, val.length) : val.length;
857
+ for (let i = 0; i !== end; ++i) {
858
+ if (i !== 0 && this.flags.space) {
859
+ hex += sharp ? " 0x" : " ";
860
+ }
861
+ // TODO(bartlomieju): for now only taking into account the
862
+ // lower half of the codePoint, ie. as if a string
863
+ // is a list of 8bit values instead of UCS2 runes
864
+ const c = (val.charCodeAt(i) & 0xff).toString(16);
865
+ hex += c.length === 1 ? `0${c}` : c;
866
+ }
867
+ if (upper) {
868
+ hex = hex.toUpperCase();
869
+ }
870
+ return this.pad(hex);
871
+ }
872
+ default:
873
+ throw new Error(
874
+ "currently only number and string are implemented for hex",
875
+ );
876
+ }
877
+ }
878
+
879
+ /**
880
+ * Format value
881
+ * @param val
882
+ */
883
+ fmtV(val: Record<string, unknown>): string {
884
+ if (this.flags.sharp) {
885
+ const options = this.flags.precision !== -1
886
+ ? { depth: this.flags.precision }
887
+ : {};
888
+ return this.pad(Deno.inspect(val, options));
889
+ } else {
890
+ const p = this.flags.precision;
891
+ return p === -1 ? val.toString() : val.toString().slice(0, p);
892
+ }
893
+ }
894
+
895
+ /**
896
+ * Format JSON
897
+ * @param val
898
+ */
899
+ fmtJ(val: unknown): string {
900
+ return JSON.stringify(val);
901
+ }
902
+
903
+ /**
904
+ * Format inspect
905
+ * @param val
906
+ * @param compact Whether or not the output should be compact.
907
+ */
908
+ fmtI(val: unknown, compact: boolean): string {
909
+ return Deno.inspect(val, {
910
+ colors: true,
911
+ compact,
912
+ depth: Infinity,
913
+ iterableLimit: Infinity,
914
+ });
915
+ }
916
+ }
917
+
918
+ /**
919
+ * Converts and format a variable number of `args` as is specified by `format`.
920
+ * `sprintf` returns the formatted string.
921
+ *
922
+ * @param format
923
+ * @param args
924
+ */
925
+ export function sprintf(format: string, ...args: unknown[]): string {
926
+ const printf = new Printf(format, ...args);
927
+ return printf.doPrintf();
928
+ }
929
+
930
+ /**
931
+ * Converts and format a variable number of `args` as is specified by `format`.
932
+ * `printf` writes the formatted string to standard output.
933
+ * @param format
934
+ * @param args
935
+ */
936
+ export function printf(format: string, ...args: unknown[]) {
937
+ const s = sprintf(format, ...args);
938
+ Deno.stdout.writeSync(new TextEncoder().encode(s));
939
+ }