@visulima/fmt 1.0.0 → 1.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/CHANGELOG.md +8 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## @visulima/fmt [1.0.1](https://github.com/visulima/visulima/compare/@visulima/fmt@1.0.0...@visulima/fmt@1.0.1) (2024-01-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* changed wrong typing ([e11089e](https://github.com/visulima/visulima/commit/e11089eba1045f0db46866a5093df3bd8b111aaf))
|
|
7
|
+
* updated all deps, updated test based on eslint errors ([909f8f3](https://github.com/visulima/visulima/commit/909f8f384804d7ef140354ab44f867532dbc9847))
|
|
8
|
+
|
|
1
9
|
## @visulima/fmt 1.0.0 (2023-12-13)
|
|
2
10
|
|
|
3
11
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const format: (fmt:
|
|
1
|
+
declare const format: (fmt: Record<string, any> | string, arguments_?: any[], options?: Options) => string;
|
|
2
2
|
declare const build: (options?: Options) => (f: NonNullable<Record<string, any> | string>, arguments_?: any[], formatOptions?: Omit<Options, "formatters">) => string;
|
|
3
3
|
type FormatterFunction = (argument: any) => string;
|
|
4
4
|
type FormatterMap = Record<number, FormatterFunction>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const format: (fmt:
|
|
1
|
+
declare const format: (fmt: Record<string, any> | string, arguments_?: any[], options?: Options) => string;
|
|
2
2
|
declare const build: (options?: Options) => (f: NonNullable<Record<string, any> | string>, arguments_?: any[], formatOptions?: Omit<Options, "formatters">) => string;
|
|
3
3
|
type FormatterFunction = (argument: any) => string;
|
|
4
4
|
type FormatterMap = Record<number, FormatterFunction>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
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,
|
|
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,r=[],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=r.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(r[a-f]);return l.join(" ")}if(r.length===0)return e;let i="",n=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){++n;break}switch(l){case d:case h:{if(n>=r.length||r[n]==null)break;o<t&&(i+=e.slice(o,t)),i+=Number(r[n]).toString(),o=t+2,t++;break}case b:{if(n>=r.length||r[n]==null)break;o<t&&(i+=e.slice(o,t)),i+=Math.floor(Number(r[n])).toString(),o=t+2,t++;break}case A:case k:case F:{if(n>=r.length||r[n]===void 0)break;o<t&&(i+=e.slice(o,t));let a=r[n],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(n>=r.length)break;o<t&&(i+=e.slice(o,t)),i+=typeof r[n]=="object"?c(r[n]):String(r[n]),o=t+2,t++;break}case u:{o<t&&(i+=e.slice(o,t)),i+="%",o=t+2,t++,n--;break}}typeof s.formatters?.[l]=="function"&&(i+=s.formatters[l](r[n]),o=t+2),++n;}++t;}return o===-1?e:(o<e.length&&(i+=e.slice(o)),i)},O=(e={})=>{let r={};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`);r[f]=c;}),(s,c=[],f={})=>P(s,c,{...f,formatters:r})};
|
|
4
4
|
|
|
5
5
|
exports.build = O;
|
|
6
6
|
exports.format = P;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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"]}
|
|
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: 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
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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,
|
|
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,r=[],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=r.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(r[a-f]);return l.join(" ")}if(r.length===0)return e;let i="",n=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){++n;break}switch(l){case d:case h:{if(n>=r.length||r[n]==null)break;o<t&&(i+=e.slice(o,t)),i+=Number(r[n]).toString(),o=t+2,t++;break}case b:{if(n>=r.length||r[n]==null)break;o<t&&(i+=e.slice(o,t)),i+=Math.floor(Number(r[n])).toString(),o=t+2,t++;break}case A:case k:case F:{if(n>=r.length||r[n]===void 0)break;o<t&&(i+=e.slice(o,t));let a=r[n],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(n>=r.length)break;o<t&&(i+=e.slice(o,t)),i+=typeof r[n]=="object"?c(r[n]):String(r[n]),o=t+2,t++;break}case u:{o<t&&(i+=e.slice(o,t)),i+="%",o=t+2,t++,n--;break}}typeof s.formatters?.[l]=="function"&&(i+=s.formatters[l](r[n]),o=t+2),++n;}++t;}return o===-1?e:(o<e.length&&(i+=e.slice(o)),i)},w=(e={})=>{let r={};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`);r[f]=c;}),(s,c=[],f={})=>P(s,c,{...f,formatters:r})};
|
|
2
2
|
|
|
3
3
|
export { w as build, P as format };
|
|
4
4
|
//# sourceMappingURL=out.js.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +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"]}
|
|
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: 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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/fmt",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Util.format-like string formatting utility.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"visulima",
|
|
@@ -77,30 +77,30 @@
|
|
|
77
77
|
"test:watch": "vitest"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
|
-
"@anolilab/eslint-config": "^15.0.
|
|
81
|
-
"@anolilab/prettier-config": "^5.0.
|
|
82
|
-
"@anolilab/semantic-release-preset": "^8.0.
|
|
83
|
-
"@babel/core": "^7.23.
|
|
84
|
-
"@rushstack/eslint-plugin-security": "^0.
|
|
80
|
+
"@anolilab/eslint-config": "^15.0.3",
|
|
81
|
+
"@anolilab/prettier-config": "^5.0.14",
|
|
82
|
+
"@anolilab/semantic-release-preset": "^8.0.3",
|
|
83
|
+
"@babel/core": "^7.23.7",
|
|
84
|
+
"@rushstack/eslint-plugin-security": "^0.8.0",
|
|
85
85
|
"@types/node": "18.18.8",
|
|
86
|
-
"@vitest/coverage-v8": "^1.
|
|
87
|
-
"@vitest/ui": "^1.
|
|
86
|
+
"@vitest/coverage-v8": "^1.2.1",
|
|
87
|
+
"@vitest/ui": "^1.2.1",
|
|
88
88
|
"cross-env": "^7.0.3",
|
|
89
|
-
"eslint": "^8.
|
|
89
|
+
"eslint": "^8.56.0",
|
|
90
90
|
"eslint-plugin-deprecation": "^2.0.0",
|
|
91
91
|
"eslint-plugin-etc": "^2.0.3",
|
|
92
|
-
"eslint-plugin-import": "npm:eslint-plugin-i@^2.29.
|
|
93
|
-
"eslint-plugin-mdx": "^
|
|
94
|
-
"eslint-plugin-vitest": "^0.3.
|
|
92
|
+
"eslint-plugin-import": "npm:eslint-plugin-i@^2.29.1",
|
|
93
|
+
"eslint-plugin-mdx": "^3.1.5",
|
|
94
|
+
"eslint-plugin-vitest": "^0.3.20",
|
|
95
95
|
"eslint-plugin-vitest-globals": "^1.4.0",
|
|
96
|
-
"prettier": "^3.
|
|
96
|
+
"prettier": "^3.2.4",
|
|
97
97
|
"quick-format-unescaped": "^4.0.4",
|
|
98
98
|
"rimraf": "^5.0.5",
|
|
99
|
-
"semantic-release": "^
|
|
99
|
+
"semantic-release": "^23.0.0",
|
|
100
100
|
"sort-package-json": "^2.6.0",
|
|
101
101
|
"tsup": "^8.0.1",
|
|
102
102
|
"typescript": "^5.3.3",
|
|
103
|
-
"vitest": "^1.
|
|
103
|
+
"vitest": "^1.2.1"
|
|
104
104
|
},
|
|
105
105
|
"engines": {
|
|
106
106
|
"node": ">=18.* <=21.*"
|