@lucasbernardosn/ts-utils 0.3.0 → 0.5.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/README.md +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/utils/get-highlight-chunks.d.ts +38 -0
- package/dist/utils/get-highlight-chunks.js +107 -0
- package/dist/utils/get-highlight-chunks.js.map +1 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +2 -1
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ import { getInitials, isDeepEqual, type DeepPartial } from '@lucasbernardosn/ts-
|
|
|
24
24
|
| ------ | -------- |
|
|
25
25
|
| `composeEventHandlers` | Junta vários handlers num só, chamados em sequência com os mesmos argumentos; os `undefined` são ignorados |
|
|
26
26
|
| `createSplitProps` | Separa um objeto de props em dois pela lista de chaves, que precisa cobrir todas as chaves do tipo pedido |
|
|
27
|
+
| `getHighlightChunks` | Divide um texto em trechos que casam ou não com a busca (sem acento nem caixa), no formato `{ text, match }`, para destacar o que casou |
|
|
27
28
|
| `getInitials` | As iniciais de um nome, em maiúsculas: a do primeiro e a do último nome |
|
|
28
29
|
| `isDeepEqual` | Igualdade estrutural, inclusive de `Map`, `Set`, `Date`, `RegExp` e arrays tipados |
|
|
29
30
|
| `isNotNullish` | Guard que tira `null` e `undefined` do tipo, para usar no `filter` |
|
package/dist/index.d.ts
CHANGED
|
@@ -21,9 +21,10 @@ import { UnknownArray, UnknownFunction, UnknownLooseValue, UnknownObject, Unknow
|
|
|
21
21
|
import { ValueOf } from "./types/value-of.js";
|
|
22
22
|
import { composeEventHandlers } from "./utils/compose-event-handlers.js";
|
|
23
23
|
import { createSplitProps } from "./utils/create-split-props.js";
|
|
24
|
+
import { GetHighlightChunksOptions, HighlightChunk, getHighlightChunks } from "./utils/get-highlight-chunks.js";
|
|
24
25
|
import { getInitials } from "./utils/get-initials.js";
|
|
25
26
|
import { isDeepEqual } from "./utils/is-deep-equal.js";
|
|
26
27
|
import { isNotNullish } from "./utils/is-not-nullish.js";
|
|
27
28
|
import { mergeBooleansAnd, mergeBooleansOr } from "./utils/merge-booleans.js";
|
|
28
29
|
import { PascalCase, toPascalCase } from "./utils/to-pascal-case.js";
|
|
29
|
-
export { AnyArray, AnyFunction, AnyLooseValue, AnyObject, AnyType, ArrayElement, DeepKeys, DeepKeysFlat, DeepPartial, DeepReadonly, DeepValue, EnsureString, KeysOfType, MergeOverride, NonEmptyArray, Nullish, OmitByValue, Optional, PascalCase, PickByValue, Recompose, RequiredExcept, SerializableValue, StrictEmptyObject, UnknownArray, UnknownFunction, UnknownLooseValue, UnknownObject, UnknownType, ValueOf, composeEventHandlers, createSplitProps, getInitials, isDeepEqual, isNotNullish, mergeBooleansAnd, mergeBooleansOr, sleep, toPascalCase };
|
|
30
|
+
export { AnyArray, AnyFunction, AnyLooseValue, AnyObject, AnyType, ArrayElement, DeepKeys, DeepKeysFlat, DeepPartial, DeepReadonly, DeepValue, EnsureString, GetHighlightChunksOptions, HighlightChunk, KeysOfType, MergeOverride, NonEmptyArray, Nullish, OmitByValue, Optional, PascalCase, PickByValue, Recompose, RequiredExcept, SerializableValue, StrictEmptyObject, UnknownArray, UnknownFunction, UnknownLooseValue, UnknownObject, UnknownType, ValueOf, composeEventHandlers, createSplitProps, getHighlightChunks, getInitials, isDeepEqual, isNotNullish, mergeBooleansAnd, mergeBooleansOr, sleep, toPascalCase };
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { sleep } from "./dev/sleep.js";
|
|
2
2
|
import { composeEventHandlers } from "./utils/compose-event-handlers.js";
|
|
3
3
|
import { createSplitProps } from "./utils/create-split-props.js";
|
|
4
|
+
import { getHighlightChunks } from "./utils/get-highlight-chunks.js";
|
|
4
5
|
import { getInitials } from "./utils/get-initials.js";
|
|
5
6
|
import { isDeepEqual } from "./utils/is-deep-equal.js";
|
|
6
7
|
import { isNotNullish } from "./utils/is-not-nullish.js";
|
|
7
8
|
import { mergeBooleansAnd, mergeBooleansOr } from "./utils/merge-booleans.js";
|
|
8
9
|
import { toPascalCase } from "./utils/to-pascal-case.js";
|
|
9
|
-
export { composeEventHandlers, createSplitProps, getInitials, isDeepEqual, isNotNullish, mergeBooleansAnd, mergeBooleansOr, sleep, toPascalCase };
|
|
10
|
+
export { composeEventHandlers, createSplitProps, getHighlightChunks, getInitials, isDeepEqual, isNotNullish, mergeBooleansAnd, mergeBooleansOr, sleep, toPascalCase };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/utils/get-highlight-chunks.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Trecho de um texto: `match` diz se ele casou com a busca.
|
|
4
|
+
*/
|
|
5
|
+
export type HighlightChunk = {
|
|
6
|
+
text: string;
|
|
7
|
+
match: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type GetHighlightChunksOptions = {
|
|
10
|
+
/** Texto original, que é fatiado em trechos. */
|
|
11
|
+
text: string;
|
|
12
|
+
/** Um termo ou uma lista de termos. Cada um é buscado inteiro, como um trecho contínuo. */
|
|
13
|
+
query: string | readonly string[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Divide o texto em trechos que casam ou não com a busca, para destacar os que casam.
|
|
17
|
+
*
|
|
18
|
+
* A regra é a do filtro do `Command` e do `useFilter` do Base UI: a busca inteira é um trecho
|
|
19
|
+
* contínuo (não é quebrada em palavras), sem diferenciar acento nem caixa. Os trechos saem do texto
|
|
20
|
+
* original, com o acento e a caixa que ele tem: `comissao` em `Comissão de vendas` marca
|
|
21
|
+
* `Comissão`. Comparar o texto cru marcaria nada, e normalizar o texto antes de fatiar devolveria
|
|
22
|
+
* o texto sem acento.
|
|
23
|
+
*
|
|
24
|
+
* Com uma lista, as ocorrências de todos os termos são juntas, e as que se sobrepõem ou encostam
|
|
25
|
+
* viram um trecho só. Busca vazia (ou só espaços) devolve o texto inteiro, sem destaque. Não há
|
|
26
|
+
* trecho vazio, e trechos vizinhos nunca têm o mesmo `match`. O formato é o do
|
|
27
|
+
* `@zag-js/highlight-word`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* getHighlightChunks({ text: 'Comissão de vendas', query: 'comissao' })
|
|
31
|
+
* // [{ text: 'Comissão', match: true }, { text: ' de vendas', match: false }]
|
|
32
|
+
*/
|
|
33
|
+
export declare const getHighlightChunks: (options: GetHighlightChunksOptions) => {
|
|
34
|
+
text: string;
|
|
35
|
+
match: boolean;
|
|
36
|
+
}[];
|
|
37
|
+
//#endregion
|
|
38
|
+
//# sourceMappingURL=get-highlight-chunks.d.ts.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
//#region src/utils/get-highlight-chunks.ts
|
|
2
|
+
const COMBINING_MARKS = /\p{M}/gu;
|
|
3
|
+
const normalizeCharacter = (character) => character.normalize("NFD").replace(COMBINING_MARKS, "").toLocaleLowerCase("pt-BR");
|
|
4
|
+
/**
|
|
5
|
+
* Normaliza o texto caractere a caractere e guarda, para cada posição do texto normalizado, onde o
|
|
6
|
+
* caractere de origem começa e termina no texto original.
|
|
7
|
+
*/
|
|
8
|
+
const normalizeWithMap = (text) => {
|
|
9
|
+
const starts = [];
|
|
10
|
+
const ends = [];
|
|
11
|
+
let normalized = "";
|
|
12
|
+
let index = 0;
|
|
13
|
+
for (const character of text) {
|
|
14
|
+
const end = index + character.length;
|
|
15
|
+
const normalizedCharacter = normalizeCharacter(character);
|
|
16
|
+
if (normalizedCharacter === "") {
|
|
17
|
+
const previousStart = starts.at(-1);
|
|
18
|
+
for (let position = ends.length - 1; position >= 0; position -= 1) {
|
|
19
|
+
if (starts[position] !== previousStart) break;
|
|
20
|
+
ends[position] = end;
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
/** Uma entrada por unidade UTF-16, porque o `indexOf` devolve posições assim. */
|
|
24
|
+
starts.push(...new Array(normalizedCharacter.length).fill(index));
|
|
25
|
+
ends.push(...new Array(normalizedCharacter.length).fill(end));
|
|
26
|
+
normalized += normalizedCharacter;
|
|
27
|
+
}
|
|
28
|
+
index = end;
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
normalized,
|
|
32
|
+
starts,
|
|
33
|
+
ends
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
const normalizeQuery = (term) => Array.from(term.trim(), normalizeCharacter).join("");
|
|
37
|
+
/**
|
|
38
|
+
* Divide o texto em trechos que casam ou não com a busca, para destacar os que casam.
|
|
39
|
+
*
|
|
40
|
+
* A regra é a do filtro do `Command` e do `useFilter` do Base UI: a busca inteira é um trecho
|
|
41
|
+
* contínuo (não é quebrada em palavras), sem diferenciar acento nem caixa. Os trechos saem do texto
|
|
42
|
+
* original, com o acento e a caixa que ele tem: `comissao` em `Comissão de vendas` marca
|
|
43
|
+
* `Comissão`. Comparar o texto cru marcaria nada, e normalizar o texto antes de fatiar devolveria
|
|
44
|
+
* o texto sem acento.
|
|
45
|
+
*
|
|
46
|
+
* Com uma lista, as ocorrências de todos os termos são juntas, e as que se sobrepõem ou encostam
|
|
47
|
+
* viram um trecho só. Busca vazia (ou só espaços) devolve o texto inteiro, sem destaque. Não há
|
|
48
|
+
* trecho vazio, e trechos vizinhos nunca têm o mesmo `match`. O formato é o do
|
|
49
|
+
* `@zag-js/highlight-word`.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* getHighlightChunks({ text: 'Comissão de vendas', query: 'comissao' })
|
|
53
|
+
* // [{ text: 'Comissão', match: true }, { text: ' de vendas', match: false }]
|
|
54
|
+
*/
|
|
55
|
+
const getHighlightChunks = (options) => {
|
|
56
|
+
const { text, query } = options;
|
|
57
|
+
const terms = (typeof query === "string" ? [query] : query).map(normalizeQuery).filter((term) => term !== "");
|
|
58
|
+
if (text === "" || terms.length === 0) return text === "" ? [] : [{
|
|
59
|
+
text,
|
|
60
|
+
match: false
|
|
61
|
+
}];
|
|
62
|
+
const { normalized, starts, ends } = normalizeWithMap(text);
|
|
63
|
+
const ranges = [];
|
|
64
|
+
for (const term of terms) {
|
|
65
|
+
let from = 0;
|
|
66
|
+
while (from <= normalized.length - term.length) {
|
|
67
|
+
const found = normalized.indexOf(term, from);
|
|
68
|
+
if (found === -1) break;
|
|
69
|
+
const start = starts[found];
|
|
70
|
+
const end = ends[found + term.length - 1];
|
|
71
|
+
if (start !== void 0 && end !== void 0) ranges.push({
|
|
72
|
+
start,
|
|
73
|
+
end
|
|
74
|
+
});
|
|
75
|
+
from = found + term.length;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
ranges.sort((a, b) => a.start - b.start || a.end - b.end);
|
|
79
|
+
const merged = [];
|
|
80
|
+
for (const range of ranges) {
|
|
81
|
+
const last = merged.at(-1);
|
|
82
|
+
if (last !== void 0 && range.start <= last.end) last.end = Math.max(last.end, range.end);
|
|
83
|
+
else merged.push({ ...range });
|
|
84
|
+
}
|
|
85
|
+
const chunks = [];
|
|
86
|
+
let cursor = 0;
|
|
87
|
+
for (const range of merged) {
|
|
88
|
+
if (range.start > cursor) chunks.push({
|
|
89
|
+
text: text.slice(cursor, range.start),
|
|
90
|
+
match: false
|
|
91
|
+
});
|
|
92
|
+
chunks.push({
|
|
93
|
+
text: text.slice(range.start, range.end),
|
|
94
|
+
match: true
|
|
95
|
+
});
|
|
96
|
+
cursor = range.end;
|
|
97
|
+
}
|
|
98
|
+
if (cursor < text.length) chunks.push({
|
|
99
|
+
text: text.slice(cursor),
|
|
100
|
+
match: false
|
|
101
|
+
});
|
|
102
|
+
return chunks;
|
|
103
|
+
};
|
|
104
|
+
//#endregion
|
|
105
|
+
export { getHighlightChunks };
|
|
106
|
+
|
|
107
|
+
//# sourceMappingURL=get-highlight-chunks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-highlight-chunks.js","names":[],"sources":["../../src/utils/get-highlight-chunks.ts"],"sourcesContent":["/**\n * Trecho de um texto: `match` diz se ele casou com a busca.\n */\nexport type HighlightChunk = {\n text: string;\n match: boolean;\n};\n\nexport type GetHighlightChunksOptions = {\n /** Texto original, que é fatiado em trechos. */\n text: string;\n /** Um termo ou uma lista de termos. Cada um é buscado inteiro, como um trecho contínuo. */\n query: string | readonly string[];\n};\n\ntype Range = { start: number; end: number };\n\nconst COMBINING_MARKS = /\\p{M}/gu;\n\nconst normalizeCharacter = (character: string) =>\n character\n .normalize('NFD')\n .replace(COMBINING_MARKS, '')\n .toLocaleLowerCase('pt-BR');\n\n/**\n * Normaliza o texto caractere a caractere e guarda, para cada posição do texto normalizado, onde o\n * caractere de origem começa e termina no texto original.\n */\nconst normalizeWithMap = (text: string) => {\n const starts: number[] = [];\n const ends: number[] = [];\n let normalized = '';\n let index = 0;\n\n for (const character of text) {\n const end = index + character.length;\n const normalizedCharacter = normalizeCharacter(character);\n\n if (normalizedCharacter === '') {\n // Marca combinante solta (texto em NFD): gruda no caractere anterior.\n const previousStart = starts.at(-1);\n\n for (let position = ends.length - 1; position >= 0; position -= 1) {\n if (starts[position] !== previousStart) {\n break;\n }\n\n ends[position] = end;\n }\n } else {\n /** Uma entrada por unidade UTF-16, porque o `indexOf` devolve posições assim. */\n starts.push(...new Array<number>(normalizedCharacter.length).fill(index));\n ends.push(...new Array<number>(normalizedCharacter.length).fill(end));\n normalized += normalizedCharacter;\n }\n\n index = end;\n }\n\n return { normalized, starts, ends };\n};\n\nconst normalizeQuery = (term: string) =>\n Array.from(term.trim(), normalizeCharacter).join('');\n\n/**\n * Divide o texto em trechos que casam ou não com a busca, para destacar os que casam.\n *\n * A regra é a do filtro do `Command` e do `useFilter` do Base UI: a busca inteira é um trecho\n * contínuo (não é quebrada em palavras), sem diferenciar acento nem caixa. Os trechos saem do texto\n * original, com o acento e a caixa que ele tem: `comissao` em `Comissão de vendas` marca\n * `Comissão`. Comparar o texto cru marcaria nada, e normalizar o texto antes de fatiar devolveria\n * o texto sem acento.\n *\n * Com uma lista, as ocorrências de todos os termos são juntas, e as que se sobrepõem ou encostam\n * viram um trecho só. Busca vazia (ou só espaços) devolve o texto inteiro, sem destaque. Não há\n * trecho vazio, e trechos vizinhos nunca têm o mesmo `match`. O formato é o do\n * `@zag-js/highlight-word`.\n *\n * @example\n * getHighlightChunks({ text: 'Comissão de vendas', query: 'comissao' })\n * // [{ text: 'Comissão', match: true }, { text: ' de vendas', match: false }]\n */\nexport const getHighlightChunks = (options: GetHighlightChunksOptions) => {\n const { text, query } = options;\n\n const terms = (typeof query === 'string' ? [query] : query)\n .map(normalizeQuery)\n .filter((term) => term !== '');\n\n if (text === '' || terms.length === 0) {\n return text === '' ? [] : [{ text, match: false }];\n }\n\n const { normalized, starts, ends } = normalizeWithMap(text);\n\n const ranges: Range[] = [];\n\n for (const term of terms) {\n let from = 0;\n\n while (from <= normalized.length - term.length) {\n const found = normalized.indexOf(term, from);\n\n if (found === -1) {\n break;\n }\n\n const start = starts[found];\n const end = ends[found + term.length - 1];\n\n if (start !== undefined && end !== undefined) {\n ranges.push({ start, end });\n }\n\n from = found + term.length;\n }\n }\n\n ranges.sort((a, b) => a.start - b.start || a.end - b.end);\n\n const merged: Range[] = [];\n\n for (const range of ranges) {\n const last = merged.at(-1);\n\n if (last !== undefined && range.start <= last.end) {\n last.end = Math.max(last.end, range.end);\n } else {\n merged.push({ ...range });\n }\n }\n\n const chunks: HighlightChunk[] = [];\n let cursor = 0;\n\n for (const range of merged) {\n if (range.start > cursor) {\n chunks.push({ text: text.slice(cursor, range.start), match: false });\n }\n\n chunks.push({ text: text.slice(range.start, range.end), match: true });\n cursor = range.end;\n }\n\n if (cursor < text.length) {\n chunks.push({ text: text.slice(cursor), match: false });\n }\n\n return chunks;\n};\n"],"mappings":";AAiBA,MAAM,kBAAkB;AAExB,MAAM,sBAAsB,cAC1B,UACG,UAAU,KAAK,CAAC,CAChB,QAAQ,iBAAiB,EAAE,CAAC,CAC5B,kBAAkB,OAAO;;;;;AAM9B,MAAM,oBAAoB,SAAiB;CACzC,MAAM,SAAmB,CAAC;CAC1B,MAAM,OAAiB,CAAC;CACxB,IAAI,aAAa;CACjB,IAAI,QAAQ;CAEZ,KAAK,MAAM,aAAa,MAAM;EAC5B,MAAM,MAAM,QAAQ,UAAU;EAC9B,MAAM,sBAAsB,mBAAmB,SAAS;EAExD,IAAI,wBAAwB,IAAI;GAE9B,MAAM,gBAAgB,OAAO,GAAG,EAAE;GAElC,KAAK,IAAI,WAAW,KAAK,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG;IACjE,IAAI,OAAO,cAAc,eACvB;IAGF,KAAK,YAAY;GACnB;EACF,OAAO;;GAEL,OAAO,KAAK,GAAG,IAAI,MAAc,oBAAoB,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC;GACxE,KAAK,KAAK,GAAG,IAAI,MAAc,oBAAoB,MAAM,CAAC,CAAC,KAAK,GAAG,CAAC;GACpE,cAAc;EAChB;EAEA,QAAQ;CACV;CAEA,OAAO;EAAE;EAAY;EAAQ;CAAK;AACpC;AAEA,MAAM,kBAAkB,SACtB,MAAM,KAAK,KAAK,KAAK,GAAG,kBAAkB,CAAC,CAAC,KAAK,EAAE;;;;;;;;;;;;;;;;;;;AAoBrD,MAAa,sBAAsB,YAAuC;CACxE,MAAM,EAAE,MAAM,UAAU;CAExB,MAAM,SAAS,OAAO,UAAU,WAAW,CAAC,KAAK,IAAI,MAAA,CAClD,IAAI,cAAc,CAAC,CACnB,QAAQ,SAAS,SAAS,EAAE;CAE/B,IAAI,SAAS,MAAM,MAAM,WAAW,GAClC,OAAO,SAAS,KAAK,CAAC,IAAI,CAAC;EAAE;EAAM,OAAO;CAAM,CAAC;CAGnD,MAAM,EAAE,YAAY,QAAQ,SAAS,iBAAiB,IAAI;CAE1D,MAAM,SAAkB,CAAC;CAEzB,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,OAAO;EAEX,OAAO,QAAQ,WAAW,SAAS,KAAK,QAAQ;GAC9C,MAAM,QAAQ,WAAW,QAAQ,MAAM,IAAI;GAE3C,IAAI,UAAU,IACZ;GAGF,MAAM,QAAQ,OAAO;GACrB,MAAM,MAAM,KAAK,QAAQ,KAAK,SAAS;GAEvC,IAAI,UAAU,KAAA,KAAa,QAAQ,KAAA,GACjC,OAAO,KAAK;IAAE;IAAO;GAAI,CAAC;GAG5B,OAAO,QAAQ,KAAK;EACtB;CACF;CAEA,OAAO,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG;CAExD,MAAM,SAAkB,CAAC;CAEzB,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,OAAO,OAAO,GAAG,EAAE;EAEzB,IAAI,SAAS,KAAA,KAAa,MAAM,SAAS,KAAK,KAC5C,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG;OAEvC,OAAO,KAAK,EAAE,GAAG,MAAM,CAAC;CAE5B;CAEA,MAAM,SAA2B,CAAC;CAClC,IAAI,SAAS;CAEb,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,MAAM,QAAQ,QAChB,OAAO,KAAK;GAAE,MAAM,KAAK,MAAM,QAAQ,MAAM,KAAK;GAAG,OAAO;EAAM,CAAC;EAGrE,OAAO,KAAK;GAAE,MAAM,KAAK,MAAM,MAAM,OAAO,MAAM,GAAG;GAAG,OAAO;EAAK,CAAC;EACrE,SAAS,MAAM;CACjB;CAEA,IAAI,SAAS,KAAK,QAChB,OAAO,KAAK;EAAE,MAAM,KAAK,MAAM,MAAM;EAAG,OAAO;CAAM,CAAC;CAGxD,OAAO;AACT"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { composeEventHandlers } from "./compose-event-handlers.js";
|
|
2
2
|
import { createSplitProps } from "./create-split-props.js";
|
|
3
|
+
import { GetHighlightChunksOptions, HighlightChunk, getHighlightChunks } from "./get-highlight-chunks.js";
|
|
3
4
|
import { getInitials } from "./get-initials.js";
|
|
4
5
|
import { isDeepEqual } from "./is-deep-equal.js";
|
|
5
6
|
import { isNotNullish } from "./is-not-nullish.js";
|
|
6
7
|
import { mergeBooleansAnd, mergeBooleansOr } from "./merge-booleans.js";
|
|
7
8
|
import { PascalCase, toPascalCase } from "./to-pascal-case.js";
|
|
8
|
-
export { PascalCase, composeEventHandlers, createSplitProps, getInitials, isDeepEqual, isNotNullish, mergeBooleansAnd, mergeBooleansOr, toPascalCase };
|
|
9
|
+
export { GetHighlightChunksOptions, HighlightChunk, PascalCase, composeEventHandlers, createSplitProps, getHighlightChunks, getInitials, isDeepEqual, isNotNullish, mergeBooleansAnd, mergeBooleansOr, toPascalCase };
|
package/dist/utils/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { composeEventHandlers } from "./compose-event-handlers.js";
|
|
2
2
|
import { createSplitProps } from "./create-split-props.js";
|
|
3
|
+
import { getHighlightChunks } from "./get-highlight-chunks.js";
|
|
3
4
|
import { getInitials } from "./get-initials.js";
|
|
4
5
|
import { isDeepEqual } from "./is-deep-equal.js";
|
|
5
6
|
import { isNotNullish } from "./is-not-nullish.js";
|
|
6
7
|
import { mergeBooleansAnd, mergeBooleansOr } from "./merge-booleans.js";
|
|
7
8
|
import { toPascalCase } from "./to-pascal-case.js";
|
|
8
|
-
export { composeEventHandlers, createSplitProps, getInitials, isDeepEqual, isNotNullish, mergeBooleansAnd, mergeBooleansOr, toPascalCase };
|
|
9
|
+
export { composeEventHandlers, createSplitProps, getHighlightChunks, getInitials, isDeepEqual, isNotNullish, mergeBooleansAnd, mergeBooleansOr, toPascalCase };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lucasbernardosn/ts-utils",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Funções e helpers de tipo em TypeScript puro, sem React e sem dependências.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"sideEffects": false,
|
|
25
|
+
"keywords": [
|
|
26
|
+
"typescript",
|
|
27
|
+
"utils",
|
|
28
|
+
"type-helpers"
|
|
29
|
+
],
|
|
25
30
|
"license": "MIT",
|
|
26
31
|
"publishConfig": {
|
|
27
32
|
"access": "public"
|