@visulima/fmt 1.0.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.
- package/CHANGELOG.md +6 -0
- package/LICENSE.md +21 -0
- package/README.md +150 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +5 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +124 -0
package/CHANGELOG.md
ADDED
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 visulima
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h3>Visulima fmt (util.format)</h3>
|
|
3
|
+
<p>
|
|
4
|
+
Util.format-like unescaped string formatting utility based on <a href="https://github.com/pinojs/quick-format-unescaped">quick-format-unescaped</a>.
|
|
5
|
+
</p>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<br />
|
|
9
|
+
|
|
10
|
+
<div align="center">
|
|
11
|
+
|
|
12
|
+
[![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url]
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
<div align="center">
|
|
19
|
+
<p>
|
|
20
|
+
<sup>
|
|
21
|
+
Daniel Bannert's open source work is supported by the community on <a href="https://github.com/sponsors/prisis">GitHub Sponsors</a>
|
|
22
|
+
</sup>
|
|
23
|
+
</p>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
npm install @visulima/fmt
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
yarn add @visulima/fmt
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
pnpm add @visulima/fmt
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { format } from "@visulima/fmt";
|
|
46
|
+
|
|
47
|
+
const formatted = format("hello %s %j %d", ["world", [{ obj: true }, 4, { another: "obj" }]]);
|
|
48
|
+
|
|
49
|
+
console.log(formatted); // hello world [{"obj":true},4,{"another":"obj"}] NaN
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### format(fmt, parameters, [options])
|
|
53
|
+
|
|
54
|
+
#### fmt
|
|
55
|
+
|
|
56
|
+
A `printf`-like format string. Example: `'hello %s %j %d'`
|
|
57
|
+
|
|
58
|
+
#### parameters
|
|
59
|
+
|
|
60
|
+
Array of values to be inserted into the `format` string. Example: `['world', {obj:true}]`
|
|
61
|
+
|
|
62
|
+
#### options.stringify
|
|
63
|
+
|
|
64
|
+
Passing an options object as the third parameter with a `stringify` will mean
|
|
65
|
+
any objects will be passed to the supplied function instead of an the
|
|
66
|
+
internal `tryStringify` function. This can be useful when using augmented
|
|
67
|
+
capability serializers such as [`fast-safe-stringify`](http://github.com/davidmarkclements/fast-safe-stringify) or [`fast-redact`](http://github.com/davidmarkclements/fast-redact).
|
|
68
|
+
|
|
69
|
+
> uses `JSON.stringify` instead of `util.inspect`, this means functions _will not be serialized_.
|
|
70
|
+
|
|
71
|
+
### build
|
|
72
|
+
|
|
73
|
+
With the `build` function you can generate a `format` function that is optimized for your use case.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { build } from "@visulima/fmt";
|
|
77
|
+
|
|
78
|
+
const format = build({
|
|
79
|
+
formatters: {
|
|
80
|
+
// Pass in whatever % interpolator you want, as long as it's a single character;
|
|
81
|
+
// in this case, it's `t`.
|
|
82
|
+
// The formatter should be a function that takes in a value and returns the formatted value.
|
|
83
|
+
t: (time) => new Date(time).toLocaleString(),
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const formatted = format("hello %s at %t", ["world", Date.now()]);
|
|
88
|
+
|
|
89
|
+
console.log(formatted); // hello world at 1/1/1970, 1:00:00 AM
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Format Specifiers
|
|
93
|
+
|
|
94
|
+
Format specifiers are dependent on the type of data-elements that are to be added to the string.
|
|
95
|
+
The most commonly used format specifiers supported are:
|
|
96
|
+
|
|
97
|
+
| Specifier | Description |
|
|
98
|
+
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
99
|
+
| %s | Converts all values except for `BigInt`, `-0` and `Object` to a string. |
|
|
100
|
+
| %d | Used to convert any value to `Number` of any type other than `BigInt` and `Symbol`. |
|
|
101
|
+
| %i | Used for all values except `BigInt` and `Symbol`. |
|
|
102
|
+
| %f | Used to convert a value to type `Float`. It does not support conversion of values of type `Symbol`. |
|
|
103
|
+
| %j | Used to add JSON data. If a circular reference is present, the string ‘[Circular]’ is added instead. |
|
|
104
|
+
| %o | Adds the string representation of an object. Note that it does not contain non-enumerable characteristics of the object. |
|
|
105
|
+
| %O | Adds the string representation of an object. Note that it will contain all characteristics of the object, including non-enumerable ones. |
|
|
106
|
+
| %% | Used to add the % sign. |
|
|
107
|
+
|
|
108
|
+
## Benchmark
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
✓ format simple (3) 4209ms
|
|
112
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
113
|
+
· util.format 2,443,716.24 0.0003 0.8279 0.0004 0.0004 0.0007 0.0008 0.0013 ±0.35% 1221859 fastest
|
|
114
|
+
· @visulima/fmt 2,425,903.43 0.0004 0.1525 0.0004 0.0004 0.0005 0.0006 0.0008 ±0.25% 1212952
|
|
115
|
+
· quick-format-unescaped 1,770,792.34 0.0005 0.3075 0.0006 0.0006 0.0006 0.0006 0.0009 ±0.30% 885397 slowest
|
|
116
|
+
|
|
117
|
+
✓ format tail object (3) 4922ms
|
|
118
|
+
name hz min max mean p75 p99 p995 p999 rme samples
|
|
119
|
+
· util.format 1,005,974.84 0.0009 0.1501 0.0010 0.0010 0.0013 0.0018 0.0022 ±0.28% 502988 slowest
|
|
120
|
+
· @visulima/fmt 3,082,590.54 0.0003 0.1489 0.0003 0.0003 0.0004 0.0005 0.0006 ±0.30% 1541296 fastest
|
|
121
|
+
· quick-format-unescaped 2,164,780.43 0.0004 0.1654 0.0005 0.0005 0.0005 0.0006 0.0008 ±0.25% 1082391
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Supported Node.js Versions
|
|
125
|
+
|
|
126
|
+
Libraries in this ecosystem make the best effort to track [Node.js’ release schedule](https://github.com/nodejs/release#release-schedule).
|
|
127
|
+
Here’s [a post on why we think this is important](https://medium.com/the-node-js-collection/maintainers-should-consider-following-node-js-release-schedule-ab08ed4de71a).
|
|
128
|
+
|
|
129
|
+
## Contributing
|
|
130
|
+
|
|
131
|
+
If you would like to help take a look at the [list of issues](https://github.com/visulima/visulima/issues) and check our [Contributing](.github/CONTRIBUTING.md) guild.
|
|
132
|
+
|
|
133
|
+
> **Note:** please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
|
|
134
|
+
|
|
135
|
+
## Credits
|
|
136
|
+
|
|
137
|
+
- [quick-format-unescaped](https://github.com/pinojs/quick-format-unescaped)
|
|
138
|
+
- [Daniel Bannert](https://github.com/prisis)
|
|
139
|
+
- [All Contributors](https://github.com/visulima/visulima/graphs/contributors)
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
The visulima fmt is open-sourced software licensed under the [MIT][license-url]
|
|
144
|
+
|
|
145
|
+
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
|
|
146
|
+
[typescript-url]: "typescript"
|
|
147
|
+
[license-image]: https://img.shields.io/npm/l/@visulima/fmt?color=blueviolet&style=for-the-badge
|
|
148
|
+
[license-url]: LICENSE.md "license"
|
|
149
|
+
[npm-image]: https://img.shields.io/npm/v/@visulima/fmt/latest.svg?style=for-the-badge&logo=npm
|
|
150
|
+
[npm-url]: https://www.npmjs.com/package/@visulima/fmt/v/latest "npm"
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare const format: (fmt: NonNullable<Record<string, any> | string>, arguments_?: any[], options?: Options) => string;
|
|
2
|
+
declare const build: (options?: Options) => (f: NonNullable<Record<string, any> | string>, arguments_?: any[], formatOptions?: Omit<Options, "formatters">) => string;
|
|
3
|
+
type FormatterFunction = (argument: any) => string;
|
|
4
|
+
type FormatterMap = Record<number, FormatterFunction>;
|
|
5
|
+
interface Options {
|
|
6
|
+
formatters?: Record<string, FormatterFunction>;
|
|
7
|
+
stringify?: (o: any) => string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { type FormatterFunction, type FormatterMap, type Options, build, format };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare const format: (fmt: NonNullable<Record<string, any> | string>, arguments_?: any[], options?: Options) => string;
|
|
2
|
+
declare const build: (options?: Options) => (f: NonNullable<Record<string, any> | string>, arguments_?: any[], formatOptions?: Omit<Options, "formatters">) => string;
|
|
3
|
+
type FormatterFunction = (argument: any) => string;
|
|
4
|
+
type FormatterMap = Record<number, FormatterFunction>;
|
|
5
|
+
interface Options {
|
|
6
|
+
formatters?: Record<string, FormatterFunction>;
|
|
7
|
+
stringify?: (o: any) => string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { type FormatterFunction, type FormatterMap, type Options, build, format };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var p=e=>{try{return JSON.stringify(e)}catch{return '"[Circular]"'}},u="%".codePointAt(0),g="s".codePointAt(0),d="d".codePointAt(0),h="f".codePointAt(0),b="i".codePointAt(0),A="O".codePointAt(0),k="o".codePointAt(0),F="j".codePointAt(0),P=(e,n=[],s={})=>{if(typeof e!="string"&&typeof e!="object"||e===null)throw new TypeError(`fmt must be a string or object, got ${e===null?"null":typeof e}`);let c=s.stringify??p,f=1;if(typeof e=="object"){let t=n.length+f;if(t===1)return "{}";let l=Array.from({length:t});l[0]=c(e);for(let a=1;a<t;a++)l[a]=c(n[a-f]);return l.join(" ")}if(n.length===0)return e;let i="",r=1-f,o=-1;for(let t=0;t<e.length;){if(e.codePointAt(t)===u&&t+1<e.length){o=o>-1?o:0;let l=e.codePointAt(t+1);if(l===void 0){++r;break}switch(l){case d:case h:{if(r>=n.length||n[r]==null)break;o<t&&(i+=e.slice(o,t)),i+=Number(n[r]).toString(),o=t+2,t++;break}case b:{if(r>=n.length||n[r]==null)break;o<t&&(i+=e.slice(o,t)),i+=Math.floor(Number(n[r])).toString(),o=t+2,t++;break}case A:case k:case F:{if(r>=n.length||n[r]===void 0)break;o<t&&(i+=e.slice(o,t));let a=n[r],y=typeof a;if(y==="string"){i+=`'${a}'`,o=t+2;break}if(y==="function"){i+=a.name?`[Function: ${a.name}]`:"[Function: <anonymous>]",o=t+2;break}i+=c(a),o=t+2,t++;break}case g:{if(r>=n.length)break;o<t&&(i+=e.slice(o,t)),i+=typeof n[r]=="object"?c(n[r]):String(n[r]),o=t+2,t++;break}case u:{o<t&&(i+=e.slice(o,t)),i+="%",o=t+2,t++,r--;break}}typeof s.formatters?.[l]=="function"&&(i+=s.formatters[l](n[r]),o=t+2),++r;}++t;}return o===-1?e:(o<e.length&&(i+=e.slice(o)),i)},O=(e={})=>{let n={};return typeof e.formatters=="object"&&Object.entries(e.formatters).forEach(([s,c])=>{if(s.length===0)throw new Error(`Formatter %${s} has no characters`);if(s.length>1)throw new Error(`Formatter %${s} has more than one character`);if(typeof c!="function")throw new TypeError(`Formatter for %${s} is not a function`);let f=s.codePointAt(0);if(f===void 0)throw new Error(`${s}.codePointAt(0) failed to return a value, please report this issue`);n[f]=c;}),(s,c=[],f={})=>P(s,c,{...f,formatters:n})};
|
|
4
|
+
|
|
5
|
+
exports.build = O;
|
|
6
|
+
exports.format = P;
|
|
7
|
+
//# sourceMappingURL=out.js.map
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["tryStringify","o","CHAR_PERCENT","CHAR_s","CHAR_d","CHAR_f","CHAR_i","CHAR_O","CHAR_o","CHAR_j","format","fmt","arguments_","options","stringify","offset","argumentsLength","objects","index","result","a","lastPosition","c","temporaryArgument","type","build","formatters","key","formatterFunction","f","formatOptions"],"mappings":"AACA,IAAMA,EAAgBC,GAAmB,CACrC,GAAI,CACA,OAAO,KAAK,UAAUA,CAAC,CAC3B,MAAQ,CACJ,MAAO,cACX,CACJ,EAEMC,EAAe,IAAI,YAAY,CAAC,EAEhCC,EAAS,IAAI,YAAY,CAAC,EAE1BC,EAAS,IAAI,YAAY,CAAC,EAE1BC,EAAS,IAAI,YAAY,CAAC,EAE1BC,EAAS,IAAI,YAAY,CAAC,EAC1BC,EAAS,IAAI,YAAY,CAAC,EAE1BC,EAAS,IAAI,YAAY,CAAC,EAE1BC,EAAS,IAAI,YAAY,CAAC,EAGnBC,EAAS,CAACC,EAAgDC,EAAoB,CAAC,EAAGC,EAAmB,CAAC,IAAc,CAE7H,GAAK,OAAOF,GAAQ,UAAY,OAAOA,GAAQ,UAAaA,IAAQ,KAEhE,MAAM,IAAI,UAAU,uCAAuCA,IAAQ,KAAO,OAAS,OAAOA,CAAG,EAAE,EAGnG,IAAMG,EAAYD,EAAQ,WAAab,EACjCe,EAAS,EAEf,GAAI,OAAOJ,GAAQ,SAAU,CACzB,IAAMK,EAAkBJ,EAAW,OAASG,EAE5C,GAAIC,IAAoB,EACpB,MAAO,KAGX,IAAMC,EAAU,MAAM,KAAK,CAAE,OAAQD,CAAgB,CAAC,EAEtDC,EAAQ,CAAC,EAAIH,EAAUH,CAAG,EAE1B,QAASO,EAAQ,EAAGA,EAAQF,EAAiBE,IAEzCD,EAAQC,CAAK,EAAIJ,EAAUF,EAAWM,EAAQH,CAAM,CAAC,EAGzD,OAAOE,EAAQ,KAAK,GAAG,CAC3B,CAEA,GAAIL,EAAW,SAAW,EACtB,OAAOD,EAGX,IAAIQ,EAAS,GACTC,EAAI,EAAIL,EACRM,EAAe,GAEnB,QAASH,EAAQ,EAAGA,EAAQP,EAAI,QAAU,CACtC,GAAIA,EAAI,YAAYO,CAAK,IAAMhB,GAAgBgB,EAAQ,EAAIP,EAAI,OAAQ,CACnEU,EAAeA,EAAe,GAAKA,EAAe,EAElD,IAAMC,EAAIX,EAAI,YAAYO,EAAQ,CAAC,EAEnC,GAAII,IAAM,OAAW,CACjB,EAAEF,EACF,KACJ,CAGA,OAAQE,EAAG,CACP,KAAKlB,EACL,KAAKC,EAAQ,CACT,GAAIe,GAAKR,EAAW,QAAUA,EAAWQ,CAA4B,GAAK,KACtE,MAGAC,EAAeH,IACfC,GAAUR,EAAI,MAAMU,EAAcH,CAAK,GAG3CC,GAAU,OAAOP,EAAWQ,CAA4B,CAAC,EAAE,SAAS,EACpEC,EAAeH,EAAQ,EAEvBA,IACA,KACJ,CACA,KAAKZ,EAAQ,CACT,GAAIc,GAAKR,EAAW,QAAUA,EAAWQ,CAA4B,GAAK,KACtE,MAGAC,EAAeH,IACfC,GAAUR,EAAI,MAAMU,EAAcH,CAAK,GAG3CC,GAAU,KAAK,MAAM,OAAOP,EAAWQ,CAA4B,CAAC,CAAC,EAAE,SAAS,EAChFC,EAAeH,EAAQ,EAEvBA,IACA,KACJ,CACA,KAAKX,EACL,KAAKC,EACL,KAAKC,EAAQ,CACT,GAAIW,GAAKR,EAAW,QAAUA,EAAWQ,CAA4B,IAAM,OACvE,MAGAC,EAAeH,IACfC,GAAUR,EAAI,MAAMU,EAAcH,CAAK,GAI3C,IAAMK,EAAoBX,EAAWQ,CAA4B,EAC3DI,EAAO,OAAOD,EAEpB,GAAIC,IAAS,SAAU,CACnBL,GAAU,IAAII,CAAiB,IAC/BF,EAAeH,EAAQ,EACvB,KACJ,CAEA,GAAIM,IAAS,WAAY,CAErBL,GAAWI,EAA+B,KAAO,cAAeA,EAA+B,IAAI,IAAM,0BACzGF,EAAeH,EAAQ,EACvB,KACJ,CAEAC,GAAUL,EAAUS,CAAiB,EACrCF,EAAeH,EAAQ,EAEvBA,IACA,KACJ,CACA,KAAKf,EAAQ,CACT,GAAIiB,GAAKR,EAAW,OAChB,MAGAS,EAAeH,IACfC,GAAUR,EAAI,MAAMU,EAAcH,CAAK,GAG3CC,GACI,OAAOP,EAAWQ,CAA4B,GAAM,SAC9CN,EAAUF,EAAWQ,CAA4B,CAAC,EAClD,OAAOR,EAAWQ,CAA4B,CAAC,EACzDC,EAAeH,EAAQ,EAEvBA,IACA,KACJ,CACA,KAAKhB,EAAc,CACXmB,EAAeH,IACfC,GAAUR,EAAI,MAAMU,EAAcH,CAAK,GAG3CC,GAAU,IACVE,EAAeH,EAAQ,EAEvBA,IACAE,IACA,KACJ,CACJ,CAGI,OAAOP,EAAQ,aAAaS,CAAC,GAAM,aAEnCH,GAAWN,EAAQ,WAAWS,CAAC,EAAwBV,EAAWQ,CAA4B,CAAC,EAC/FC,EAAeH,EAAQ,GAG3B,EAAEE,CACN,CAEA,EAAEF,CACN,CAEA,OAAIG,IAAiB,GACVV,GAGPU,EAAeV,EAAI,SACnBQ,GAAUR,EAAI,MAAMU,CAAY,GAG7BF,EACX,EAEaM,EAAQ,CACjBZ,EAAmB,CAAC,IAE0G,CAC9H,IAAMa,EAA2B,CAAC,EAElC,OAAI,OAAOb,EAAQ,YAAe,UAC9B,OAAO,QAAQA,EAAQ,UAAU,EAAE,QAAQ,CAAC,CAACc,EAAKC,CAAiB,IAAM,CACrE,GAAID,EAAI,SAAW,EACf,MAAM,IAAI,MAAM,cAAcA,CAAG,oBAAoB,EAGzD,GAAIA,EAAI,OAAS,EACb,MAAM,IAAI,MAAM,cAAcA,CAAG,8BAA8B,EAGnE,GAAI,OAAOC,GAAsB,WAC7B,MAAM,IAAI,UAAU,kBAAkBD,CAAG,oBAAoB,EAGjE,IAAML,EAAIK,EAAI,YAAY,CAAC,EAE3B,GAAIL,IAAM,OACN,MAAM,IAAI,MAAM,GAAGK,CAAG,oEAAoE,EAI9FD,EAAWJ,CAAC,EAAIM,CACpB,CAAC,EAIE,CAACC,EAA8CjB,EAAoB,CAAC,EAAGkB,EAA6C,CAAC,IACxHpB,EAAOmB,EAAGjB,EAAY,CAAE,GAAGkB,EAAe,WAAAJ,CAAW,CAAC,CAC9D","sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst tryStringify = (o: any): string => {\n try {\n return JSON.stringify(o);\n } catch {\n return '\"[Circular]\"';\n }\n};\n\nconst CHAR_PERCENT = \"%\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst CHAR_s = \"s\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst CHAR_d = \"d\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst CHAR_f = \"f\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention,unicorn/prevent-abbreviations\nconst CHAR_i = \"i\".codePointAt(0);\nconst CHAR_O = \"O\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst CHAR_o = \"o\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention,unicorn/prevent-abbreviations\nconst CHAR_j = \"j\".codePointAt(0);\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any,sonarjs/cognitive-complexity\nexport const format = (fmt: NonNullable<Record<string, any> | string>, arguments_: any[] = [], options: Options = {}): string => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if ((typeof fmt !== \"string\" && typeof fmt !== \"object\") || fmt === null) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n throw new TypeError(`fmt must be a string or object, got ${fmt === null ? \"null\" : typeof fmt}`);\n }\n\n const stringify = options.stringify ?? tryStringify;\n const offset = 1;\n\n if (typeof fmt === \"object\") {\n const argumentsLength = arguments_.length + offset;\n\n if (argumentsLength === 1) {\n return \"{}\";\n }\n\n const objects = Array.from({ length: argumentsLength });\n\n objects[0] = stringify(fmt);\n\n for (let index = 1; index < argumentsLength; index++) {\n // eslint-disable-next-line security/detect-object-injection\n objects[index] = stringify(arguments_[index - offset]);\n }\n\n return objects.join(\" \");\n }\n\n if (arguments_.length === 0) {\n return fmt;\n }\n\n let result = \"\";\n let a = 1 - offset;\n let lastPosition = -1;\n\n for (let index = 0; index < fmt.length; ) {\n if (fmt.codePointAt(index) === CHAR_PERCENT && index + 1 < fmt.length) {\n lastPosition = lastPosition > -1 ? lastPosition : 0;\n\n const c = fmt.codePointAt(index + 1);\n\n if (c === undefined) {\n ++a;\n break;\n }\n\n // eslint-disable-next-line default-case\n switch (c) {\n case CHAR_d:\n case CHAR_f: {\n if (a >= arguments_.length || arguments_[a as keyof typeof arguments_] == null) {\n break;\n }\n\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n result += Number(arguments_[a as keyof typeof arguments_]).toString();\n lastPosition = index + 2;\n\n index++;\n break;\n }\n case CHAR_i: {\n if (a >= arguments_.length || arguments_[a as keyof typeof arguments_] == null) {\n break;\n }\n\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n result += Math.floor(Number(arguments_[a as keyof typeof arguments_])).toString();\n lastPosition = index + 2;\n\n index++;\n break;\n }\n case CHAR_O:\n case CHAR_o:\n case CHAR_j: {\n if (a >= arguments_.length || arguments_[a as keyof typeof arguments_] === undefined) {\n break;\n }\n\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const temporaryArgument = arguments_[a as keyof typeof arguments_];\n const type = typeof temporaryArgument;\n\n if (type === \"string\") {\n result += `'${temporaryArgument}'`;\n lastPosition = index + 2;\n break;\n }\n\n if (type === \"function\") {\n // eslint-disable-next-line @typescript-eslint/ban-types\n result += (temporaryArgument as Function).name ? `[Function: ${(temporaryArgument as Function).name}]` : \"[Function: <anonymous>]\";\n lastPosition = index + 2;\n break;\n }\n\n result += stringify(temporaryArgument);\n lastPosition = index + 2;\n\n index++;\n break;\n }\n case CHAR_s: {\n if (a >= arguments_.length) {\n break;\n }\n\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n result +=\n typeof arguments_[a as keyof typeof arguments_] === \"object\"\n ? stringify(arguments_[a as keyof typeof arguments_])\n : String(arguments_[a as keyof typeof arguments_]);\n lastPosition = index + 2;\n\n index++;\n break;\n }\n case CHAR_PERCENT: {\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n result += \"%\";\n lastPosition = index + 2;\n\n index++;\n a--;\n break;\n }\n }\n\n // eslint-disable-next-line security/detect-object-injection\n if (typeof options.formatters?.[c] === \"function\") {\n // eslint-disable-next-line security/detect-object-injection\n result += (options.formatters[c] as FormatterFunction)(arguments_[a as keyof typeof arguments_]);\n lastPosition = index + 2;\n }\n\n ++a;\n }\n\n ++index;\n }\n\n if (lastPosition === -1) {\n return fmt;\n }\n\n if (lastPosition < fmt.length) {\n result += fmt.slice(lastPosition);\n }\n\n return result;\n};\n\nexport const build = (\n options: Options = {},\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ((f: NonNullable<Record<string, any> | string>, arguments_?: any[], formatOptions?: Omit<Options, \"formatters\">) => string) => {\n const formatters: FormatterMap = {};\n\n if (typeof options.formatters === \"object\") {\n Object.entries(options.formatters).forEach(([key, formatterFunction]) => {\n if (key.length === 0) {\n throw new Error(`Formatter %${key} has no characters`);\n }\n\n if (key.length > 1) {\n throw new Error(`Formatter %${key} has more than one character`);\n }\n\n if (typeof formatterFunction !== \"function\") {\n throw new TypeError(`Formatter for %${key} is not a function`);\n }\n\n const c = key.codePointAt(0);\n\n if (c === undefined) {\n throw new Error(`${key}.codePointAt(0) failed to return a value, please report this issue`);\n }\n\n // eslint-disable-next-line security/detect-object-injection\n formatters[c] = formatterFunction;\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (f: NonNullable<Record<string, any> | string>, arguments_: any[] = [], formatOptions: Omit<Options, \"formatters\"> = {}) =>\n format(f, arguments_, { ...formatOptions, formatters });\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type FormatterFunction = (argument: any) => string;\nexport type FormatterMap = Record<number, FormatterFunction>;\n\nexport interface Options {\n formatters?: Record<string, FormatterFunction>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stringify?: (o: any) => string;\n}\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
var p=e=>{try{return JSON.stringify(e)}catch{return '"[Circular]"'}},u="%".codePointAt(0),g="s".codePointAt(0),d="d".codePointAt(0),h="f".codePointAt(0),b="i".codePointAt(0),A="O".codePointAt(0),k="o".codePointAt(0),F="j".codePointAt(0),P=(e,n=[],s={})=>{if(typeof e!="string"&&typeof e!="object"||e===null)throw new TypeError(`fmt must be a string or object, got ${e===null?"null":typeof e}`);let c=s.stringify??p,f=1;if(typeof e=="object"){let t=n.length+f;if(t===1)return "{}";let l=Array.from({length:t});l[0]=c(e);for(let a=1;a<t;a++)l[a]=c(n[a-f]);return l.join(" ")}if(n.length===0)return e;let i="",r=1-f,o=-1;for(let t=0;t<e.length;){if(e.codePointAt(t)===u&&t+1<e.length){o=o>-1?o:0;let l=e.codePointAt(t+1);if(l===void 0){++r;break}switch(l){case d:case h:{if(r>=n.length||n[r]==null)break;o<t&&(i+=e.slice(o,t)),i+=Number(n[r]).toString(),o=t+2,t++;break}case b:{if(r>=n.length||n[r]==null)break;o<t&&(i+=e.slice(o,t)),i+=Math.floor(Number(n[r])).toString(),o=t+2,t++;break}case A:case k:case F:{if(r>=n.length||n[r]===void 0)break;o<t&&(i+=e.slice(o,t));let a=n[r],y=typeof a;if(y==="string"){i+=`'${a}'`,o=t+2;break}if(y==="function"){i+=a.name?`[Function: ${a.name}]`:"[Function: <anonymous>]",o=t+2;break}i+=c(a),o=t+2,t++;break}case g:{if(r>=n.length)break;o<t&&(i+=e.slice(o,t)),i+=typeof n[r]=="object"?c(n[r]):String(n[r]),o=t+2,t++;break}case u:{o<t&&(i+=e.slice(o,t)),i+="%",o=t+2,t++,r--;break}}typeof s.formatters?.[l]=="function"&&(i+=s.formatters[l](n[r]),o=t+2),++r;}++t;}return o===-1?e:(o<e.length&&(i+=e.slice(o)),i)},w=(e={})=>{let n={};return typeof e.formatters=="object"&&Object.entries(e.formatters).forEach(([s,c])=>{if(s.length===0)throw new Error(`Formatter %${s} has no characters`);if(s.length>1)throw new Error(`Formatter %${s} has more than one character`);if(typeof c!="function")throw new TypeError(`Formatter for %${s} is not a function`);let f=s.codePointAt(0);if(f===void 0)throw new Error(`${s}.codePointAt(0) failed to return a value, please report this issue`);n[f]=c;}),(s,c=[],f={})=>P(s,c,{...f,formatters:n})};
|
|
2
|
+
|
|
3
|
+
export { w as build, P as format };
|
|
4
|
+
//# sourceMappingURL=out.js.map
|
|
5
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["tryStringify","o","CHAR_PERCENT","CHAR_s","CHAR_d","CHAR_f","CHAR_i","CHAR_O","CHAR_o","CHAR_j","format","fmt","arguments_","options","stringify","offset","argumentsLength","objects","index","result","a","lastPosition","c","temporaryArgument","type","build","formatters","key","formatterFunction","f","formatOptions"],"mappings":"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","sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst tryStringify = (o: any): string => {\n try {\n return JSON.stringify(o);\n } catch {\n return '\"[Circular]\"';\n }\n};\n\nconst CHAR_PERCENT = \"%\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst CHAR_s = \"s\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst CHAR_d = \"d\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst CHAR_f = \"f\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention,unicorn/prevent-abbreviations\nconst CHAR_i = \"i\".codePointAt(0);\nconst CHAR_O = \"O\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst CHAR_o = \"o\".codePointAt(0);\n// eslint-disable-next-line @typescript-eslint/naming-convention,unicorn/prevent-abbreviations\nconst CHAR_j = \"j\".codePointAt(0);\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any,sonarjs/cognitive-complexity\nexport const format = (fmt: NonNullable<Record<string, any> | string>, arguments_: any[] = [], options: Options = {}): string => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if ((typeof fmt !== \"string\" && typeof fmt !== \"object\") || fmt === null) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n throw new TypeError(`fmt must be a string or object, got ${fmt === null ? \"null\" : typeof fmt}`);\n }\n\n const stringify = options.stringify ?? tryStringify;\n const offset = 1;\n\n if (typeof fmt === \"object\") {\n const argumentsLength = arguments_.length + offset;\n\n if (argumentsLength === 1) {\n return \"{}\";\n }\n\n const objects = Array.from({ length: argumentsLength });\n\n objects[0] = stringify(fmt);\n\n for (let index = 1; index < argumentsLength; index++) {\n // eslint-disable-next-line security/detect-object-injection\n objects[index] = stringify(arguments_[index - offset]);\n }\n\n return objects.join(\" \");\n }\n\n if (arguments_.length === 0) {\n return fmt;\n }\n\n let result = \"\";\n let a = 1 - offset;\n let lastPosition = -1;\n\n for (let index = 0; index < fmt.length; ) {\n if (fmt.codePointAt(index) === CHAR_PERCENT && index + 1 < fmt.length) {\n lastPosition = lastPosition > -1 ? lastPosition : 0;\n\n const c = fmt.codePointAt(index + 1);\n\n if (c === undefined) {\n ++a;\n break;\n }\n\n // eslint-disable-next-line default-case\n switch (c) {\n case CHAR_d:\n case CHAR_f: {\n if (a >= arguments_.length || arguments_[a as keyof typeof arguments_] == null) {\n break;\n }\n\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n result += Number(arguments_[a as keyof typeof arguments_]).toString();\n lastPosition = index + 2;\n\n index++;\n break;\n }\n case CHAR_i: {\n if (a >= arguments_.length || arguments_[a as keyof typeof arguments_] == null) {\n break;\n }\n\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n result += Math.floor(Number(arguments_[a as keyof typeof arguments_])).toString();\n lastPosition = index + 2;\n\n index++;\n break;\n }\n case CHAR_O:\n case CHAR_o:\n case CHAR_j: {\n if (a >= arguments_.length || arguments_[a as keyof typeof arguments_] === undefined) {\n break;\n }\n\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const temporaryArgument = arguments_[a as keyof typeof arguments_];\n const type = typeof temporaryArgument;\n\n if (type === \"string\") {\n result += `'${temporaryArgument}'`;\n lastPosition = index + 2;\n break;\n }\n\n if (type === \"function\") {\n // eslint-disable-next-line @typescript-eslint/ban-types\n result += (temporaryArgument as Function).name ? `[Function: ${(temporaryArgument as Function).name}]` : \"[Function: <anonymous>]\";\n lastPosition = index + 2;\n break;\n }\n\n result += stringify(temporaryArgument);\n lastPosition = index + 2;\n\n index++;\n break;\n }\n case CHAR_s: {\n if (a >= arguments_.length) {\n break;\n }\n\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n result +=\n typeof arguments_[a as keyof typeof arguments_] === \"object\"\n ? stringify(arguments_[a as keyof typeof arguments_])\n : String(arguments_[a as keyof typeof arguments_]);\n lastPosition = index + 2;\n\n index++;\n break;\n }\n case CHAR_PERCENT: {\n if (lastPosition < index) {\n result += fmt.slice(lastPosition, index);\n }\n\n result += \"%\";\n lastPosition = index + 2;\n\n index++;\n a--;\n break;\n }\n }\n\n // eslint-disable-next-line security/detect-object-injection\n if (typeof options.formatters?.[c] === \"function\") {\n // eslint-disable-next-line security/detect-object-injection\n result += (options.formatters[c] as FormatterFunction)(arguments_[a as keyof typeof arguments_]);\n lastPosition = index + 2;\n }\n\n ++a;\n }\n\n ++index;\n }\n\n if (lastPosition === -1) {\n return fmt;\n }\n\n if (lastPosition < fmt.length) {\n result += fmt.slice(lastPosition);\n }\n\n return result;\n};\n\nexport const build = (\n options: Options = {},\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ((f: NonNullable<Record<string, any> | string>, arguments_?: any[], formatOptions?: Omit<Options, \"formatters\">) => string) => {\n const formatters: FormatterMap = {};\n\n if (typeof options.formatters === \"object\") {\n Object.entries(options.formatters).forEach(([key, formatterFunction]) => {\n if (key.length === 0) {\n throw new Error(`Formatter %${key} has no characters`);\n }\n\n if (key.length > 1) {\n throw new Error(`Formatter %${key} has more than one character`);\n }\n\n if (typeof formatterFunction !== \"function\") {\n throw new TypeError(`Formatter for %${key} is not a function`);\n }\n\n const c = key.codePointAt(0);\n\n if (c === undefined) {\n throw new Error(`${key}.codePointAt(0) failed to return a value, please report this issue`);\n }\n\n // eslint-disable-next-line security/detect-object-injection\n formatters[c] = formatterFunction;\n });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (f: NonNullable<Record<string, any> | string>, arguments_: any[] = [], formatOptions: Omit<Options, \"formatters\"> = {}) =>\n format(f, arguments_, { ...formatOptions, formatters });\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type FormatterFunction = (argument: any) => string;\nexport type FormatterMap = Record<number, FormatterFunction>;\n\nexport interface Options {\n formatters?: Record<string, FormatterFunction>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stringify?: (o: any) => string;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@visulima/fmt",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Util.format-like string formatting utility.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"visulima",
|
|
7
|
+
"anolilab",
|
|
8
|
+
"fmt",
|
|
9
|
+
"util",
|
|
10
|
+
"util.format",
|
|
11
|
+
"format",
|
|
12
|
+
"string",
|
|
13
|
+
"formatting",
|
|
14
|
+
"string-format",
|
|
15
|
+
"quick-format-unescaped"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://www.visulima.com/docs/package/fmt",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/visulima/visulima.git",
|
|
21
|
+
"directory": "packages/fmt"
|
|
22
|
+
},
|
|
23
|
+
"funding": [
|
|
24
|
+
{
|
|
25
|
+
"type": "github",
|
|
26
|
+
"url": "https://github.com/sponsors/prisis"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "consulting",
|
|
30
|
+
"url": "https://anolilab.com/support"
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"author": {
|
|
35
|
+
"name": "Daniel Bannert",
|
|
36
|
+
"email": "d.bannert@anolilab.de"
|
|
37
|
+
},
|
|
38
|
+
"sideEffects": false,
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"require": {
|
|
42
|
+
"types": "./dist/index.d.ts",
|
|
43
|
+
"default": "./dist/index.js"
|
|
44
|
+
},
|
|
45
|
+
"import": {
|
|
46
|
+
"types": "./dist/index.d.mts",
|
|
47
|
+
"default": "./dist/index.mjs"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"./package.json": "./package.json"
|
|
51
|
+
},
|
|
52
|
+
"main": "dist/index.js",
|
|
53
|
+
"module": "dist/index.mjs",
|
|
54
|
+
"source": "src/index.ts",
|
|
55
|
+
"types": "dist/index.d.ts",
|
|
56
|
+
"files": [
|
|
57
|
+
"dist/**",
|
|
58
|
+
"README.md",
|
|
59
|
+
"CHANGELOG.md",
|
|
60
|
+
"LICENSE.md"
|
|
61
|
+
],
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "cross-env NODE_ENV=development tsup",
|
|
64
|
+
"build:prod": "cross-env NODE_ENV=production tsup",
|
|
65
|
+
"clean": "rimraf node_modules dist .eslintcache",
|
|
66
|
+
"dev": "pnpm run build --watch",
|
|
67
|
+
"lint:eslint": "eslint . --ext js,cjs,mjs,jsx,ts,tsx,json,yaml,yml,md,mdx --max-warnings=0 --config .eslintrc.js",
|
|
68
|
+
"lint:eslint:fix": "eslint . --ext js,cjs,mjs,jsx,ts,tsx,json,yaml,yml,md,mdx --max-warnings=0 --config .eslintrc.js --fix",
|
|
69
|
+
"lint:packagejson": "publint --strict",
|
|
70
|
+
"lint:prettier": "prettier --config=.prettierrc.js --check .",
|
|
71
|
+
"lint:prettier:fix": "prettier --config=.prettierrc.js --write .",
|
|
72
|
+
"lint:types": "tsc --noEmit",
|
|
73
|
+
"test": "vitest run",
|
|
74
|
+
"test:bench": "vitest bench",
|
|
75
|
+
"test:coverage": "vitest run --coverage",
|
|
76
|
+
"test:ui": "vitest --ui --coverage.enabled=true",
|
|
77
|
+
"test:watch": "vitest"
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@anolilab/eslint-config": "^15.0.2",
|
|
81
|
+
"@anolilab/prettier-config": "^5.0.13",
|
|
82
|
+
"@anolilab/semantic-release-preset": "^8.0.2",
|
|
83
|
+
"@babel/core": "^7.23.5",
|
|
84
|
+
"@rushstack/eslint-plugin-security": "^0.7.1",
|
|
85
|
+
"@types/node": "18.18.8",
|
|
86
|
+
"@vitest/coverage-v8": "^1.0.2",
|
|
87
|
+
"@vitest/ui": "^1.0.2",
|
|
88
|
+
"cross-env": "^7.0.3",
|
|
89
|
+
"eslint": "^8.55.0",
|
|
90
|
+
"eslint-plugin-deprecation": "^2.0.0",
|
|
91
|
+
"eslint-plugin-etc": "^2.0.3",
|
|
92
|
+
"eslint-plugin-import": "npm:eslint-plugin-i@^2.29.0",
|
|
93
|
+
"eslint-plugin-mdx": "^2.2.0",
|
|
94
|
+
"eslint-plugin-vitest": "^0.3.10",
|
|
95
|
+
"eslint-plugin-vitest-globals": "^1.4.0",
|
|
96
|
+
"prettier": "^3.1.0",
|
|
97
|
+
"quick-format-unescaped": "^4.0.4",
|
|
98
|
+
"rimraf": "^5.0.5",
|
|
99
|
+
"semantic-release": "^22.0.10",
|
|
100
|
+
"sort-package-json": "^2.6.0",
|
|
101
|
+
"tsup": "^8.0.1",
|
|
102
|
+
"typescript": "^5.3.3",
|
|
103
|
+
"vitest": "^1.0.2"
|
|
104
|
+
},
|
|
105
|
+
"engines": {
|
|
106
|
+
"node": ">=18.* <=21.*"
|
|
107
|
+
},
|
|
108
|
+
"publishConfig": {
|
|
109
|
+
"access": "public",
|
|
110
|
+
"provenance": true
|
|
111
|
+
},
|
|
112
|
+
"anolilab": {
|
|
113
|
+
"eslint-config": {
|
|
114
|
+
"plugin": {
|
|
115
|
+
"tsdoc": false
|
|
116
|
+
},
|
|
117
|
+
"warn_on_unsupported_typescript_version": false,
|
|
118
|
+
"info_on_disabling_jsx_react_rule": false,
|
|
119
|
+
"info_on_disabling_prettier_conflict_rule": false,
|
|
120
|
+
"info_on_disabling_jsonc_sort_keys_rule": false,
|
|
121
|
+
"info_on_disabling_etc_no_deprecated": false
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|