@tstdl/base 0.93.27 → 0.93.29
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/orm/data-types/tsvector.d.ts +3 -1
- package/orm/data-types/tsvector.js +2 -0
- package/orm/decorators.d.ts +168 -18
- package/orm/decorators.js +48 -2
- package/orm/index.d.ts +1 -1
- package/orm/index.js +1 -1
- package/orm/{query.d.ts → query/base.d.ts} +14 -166
- package/orm/{query.js → query/base.js} +3 -2
- package/orm/query/index.d.ts +2 -0
- package/orm/query/index.js +2 -0
- package/orm/query/parade.d.ts +172 -0
- package/orm/query/parade.js +4 -0
- package/orm/repository.types.d.ts +27 -6
- package/orm/schemas/index.d.ts +1 -0
- package/orm/schemas/index.js +1 -0
- package/orm/schemas/tsvector.d.ts +12 -0
- package/orm/schemas/tsvector.js +20 -0
- package/orm/server/drizzle/schema-converter.js +100 -20
- package/orm/server/query-converter.d.ts +2 -2
- package/orm/server/query-converter.js +138 -91
- package/orm/server/repository.d.ts +6 -6
- package/orm/server/repository.js +34 -23
- package/orm/sqls.d.ts +19 -16
- package/orm/sqls.js +28 -38
- package/package.json +6 -6
- package/test/drizzle/0000_natural_cannonball.sql +9 -0
- package/test/drizzle/meta/0000_snapshot.json +29 -10
- package/test/drizzle/meta/_journal.json +2 -2
- package/test/test.model.js +8 -2
- package/test1.js +9 -9
- package/utils/enum.js +1 -1
- package/utils/object/object.d.ts +5 -3
- package/utils/object/object.js +17 -7
- package/utils/string/casing.d.ts +3 -0
- package/utils/string/casing.js +15 -0
- package/utils/string/index.d.ts +1 -1
- package/utils/string/index.js +1 -1
- package/test/drizzle/0000_sturdy_patch.sql +0 -9
- package/utils/string/snake-case.d.ts +0 -1
- package/utils/string/snake-case.js +0 -4
package/orm/sqls.js
CHANGED
|
@@ -10,6 +10,10 @@ import { sql, Table } from 'drizzle-orm';
|
|
|
10
10
|
export const TRANSACTION_TIMESTAMP = sql `transaction_timestamp()`;
|
|
11
11
|
/** Drizzle SQL helper for generating a random UUID (v4). Returns a Uuid string. */
|
|
12
12
|
export const RANDOM_UUID_V4 = sql `gen_random_uuid()`;
|
|
13
|
+
export function array(values) {
|
|
14
|
+
const valueString = sql.join(values, sql.raw(', '));
|
|
15
|
+
return sql `ARRAY[${valueString}]`;
|
|
16
|
+
}
|
|
13
17
|
export function autoAlias(column) {
|
|
14
18
|
return sql `${column}`.as(`${column.table[Table['Symbol']['Name']]}_${column.name}`);
|
|
15
19
|
}
|
|
@@ -98,11 +102,8 @@ export function greatest(...values) {
|
|
|
98
102
|
export function unnest(array) {
|
|
99
103
|
return sql `unnest(${array})`;
|
|
100
104
|
}
|
|
101
|
-
function getLanguageSql(language) {
|
|
102
|
-
return isString(language) ? sql `'${sql.raw(language)}'` : sql `${language}`;
|
|
103
|
-
}
|
|
104
105
|
export function toTsVector(language, text) {
|
|
105
|
-
return sql `to_tsvector(${
|
|
106
|
+
return sql `to_tsvector(${language}, ${text})`;
|
|
106
107
|
}
|
|
107
108
|
export function tsvectorToArray(tsvector) {
|
|
108
109
|
return sql `tsvector_to_array(${tsvector})`;
|
|
@@ -115,7 +116,7 @@ export function tsvectorToArray(tsvector) {
|
|
|
115
116
|
* @returns A Drizzle SQL object representing the tsquery.
|
|
116
117
|
*/
|
|
117
118
|
export function toTsQuery(language, text) {
|
|
118
|
-
return sql `to_tsquery(${
|
|
119
|
+
return sql `to_tsquery(${language}, ${text})`;
|
|
119
120
|
}
|
|
120
121
|
/**
|
|
121
122
|
* Creates a PostgreSQL `plainto_tsquery` function call.
|
|
@@ -126,7 +127,7 @@ export function toTsQuery(language, text) {
|
|
|
126
127
|
* @returns A Drizzle SQL object representing the tsquery.
|
|
127
128
|
*/
|
|
128
129
|
export function plainToTsQuery(language, text) {
|
|
129
|
-
return sql `plainto_tsquery(${
|
|
130
|
+
return sql `plainto_tsquery(${language}, ${text})`;
|
|
130
131
|
}
|
|
131
132
|
/**
|
|
132
133
|
* Creates a PostgreSQL `phraseto_tsquery` function call.
|
|
@@ -136,7 +137,7 @@ export function plainToTsQuery(language, text) {
|
|
|
136
137
|
* @returns A Drizzle SQL object representing the tsquery.
|
|
137
138
|
*/
|
|
138
139
|
export function phraseToTsQuery(language, text) {
|
|
139
|
-
return sql `phraseto_tsquery(${
|
|
140
|
+
return sql `phraseto_tsquery(${language}, ${text})`;
|
|
140
141
|
}
|
|
141
142
|
/**
|
|
142
143
|
* Creates a PostgreSQL `websearch_to_tsquery` function call.
|
|
@@ -147,7 +148,7 @@ export function phraseToTsQuery(language, text) {
|
|
|
147
148
|
* @returns A Drizzle SQL object representing the tsquery.
|
|
148
149
|
*/
|
|
149
150
|
export function websearchToTsQuery(language, text) {
|
|
150
|
-
return sql `websearch_to_tsquery(${
|
|
151
|
+
return sql `websearch_to_tsquery(${language}, ${text})`;
|
|
151
152
|
}
|
|
152
153
|
/**
|
|
153
154
|
* Creates a PostgreSQL `setweight` function call.
|
|
@@ -170,7 +171,7 @@ export function tsRankCd(tsvector, tsquery, options) {
|
|
|
170
171
|
const parameters = [];
|
|
171
172
|
if (isDefined(options?.weights)) {
|
|
172
173
|
const weightParts = options.weights.map((w) => sql.raw(String(w)));
|
|
173
|
-
parameters.push(sql
|
|
174
|
+
parameters.push(sql `${array(weightParts)}::real[]`);
|
|
174
175
|
}
|
|
175
176
|
parameters.push(tsvector, tsquery);
|
|
176
177
|
if (isDefined(options?.normalization)) {
|
|
@@ -195,9 +196,9 @@ export function tsHeadline(language, document, tsquery, options) {
|
|
|
195
196
|
const documentSql = isString(document) ? sql `${document}` : document;
|
|
196
197
|
if (isDefined(options)) {
|
|
197
198
|
const optionsString = Object.entries(options).map(([key, value]) => `${key[0].toUpperCase()}${key.slice(1)}=${String(value)}`).join(', ');
|
|
198
|
-
return sql `ts_headline(${
|
|
199
|
+
return sql `ts_headline(${language}, ${documentSql}, ${tsquery}, '${sql.raw(optionsString)}')`;
|
|
199
200
|
}
|
|
200
|
-
return sql `ts_headline(${
|
|
201
|
+
return sql `ts_headline(${language}, ${documentSql}, ${tsquery})`;
|
|
201
202
|
}
|
|
202
203
|
/**
|
|
203
204
|
* Creates a PostgreSQL `similarity` function call (from pg_trgm extension).
|
|
@@ -207,9 +208,7 @@ export function tsHeadline(language, document, tsquery, options) {
|
|
|
207
208
|
* @returns A Drizzle SQL object representing the similarity score (0 to 1).
|
|
208
209
|
*/
|
|
209
210
|
export function similarity(left, right) {
|
|
210
|
-
|
|
211
|
-
const rightSql = isString(right) ? sql `${right}` : right;
|
|
212
|
-
return sql `similarity(${leftSql}, ${rightSql})`;
|
|
211
|
+
return sql `similarity(${left}, ${right})`;
|
|
213
212
|
}
|
|
214
213
|
/**
|
|
215
214
|
* Creates a PostgreSQL `word_similarity` function call (from pg_trgm extension).
|
|
@@ -219,9 +218,7 @@ export function similarity(left, right) {
|
|
|
219
218
|
* @returns A Drizzle SQL object representing the similarity score (0 to 1).
|
|
220
219
|
*/
|
|
221
220
|
export function wordSimilarity(left, right) {
|
|
222
|
-
|
|
223
|
-
const rightSql = isString(right) ? sql `${right}` : right;
|
|
224
|
-
return sql `word_similarity(${leftSql}, ${rightSql})`;
|
|
221
|
+
return sql `word_similarity(${left}, ${right})`;
|
|
225
222
|
}
|
|
226
223
|
/**
|
|
227
224
|
* Creates a PostgreSQL `strict_word_similarity` function call (from pg_trgm extension).
|
|
@@ -231,37 +228,30 @@ export function wordSimilarity(left, right) {
|
|
|
231
228
|
* @returns A Drizzle SQL object representing the similarity score (0 to 1).
|
|
232
229
|
*/
|
|
233
230
|
export function strictWordSimilarity(left, right) {
|
|
234
|
-
|
|
235
|
-
const rightSql = isString(right) ? sql `${right}` : right;
|
|
236
|
-
return sql `strict_word_similarity(${leftSql}, ${rightSql})`;
|
|
231
|
+
return sql `strict_word_similarity(${left}, ${right})`;
|
|
237
232
|
}
|
|
238
233
|
export function isSimilar(left, right) {
|
|
239
|
-
|
|
240
|
-
const rightSql = isString(right) ? sql `${right}` : right;
|
|
241
|
-
return sql `(${leftSql} % ${rightSql})`;
|
|
234
|
+
return sql `(${left} % ${right})`;
|
|
242
235
|
}
|
|
243
236
|
export function isWordSimilar(left, right) {
|
|
244
|
-
|
|
245
|
-
const rightSql = isString(right) ? sql `${right}` : right;
|
|
246
|
-
return sql `(${leftSql} <% ${rightSql})`;
|
|
237
|
+
return sql `(${left} <% ${right})`;
|
|
247
238
|
}
|
|
248
239
|
export function isStrictWordSimilar(left, right) {
|
|
249
|
-
|
|
250
|
-
const rightSql = isString(right) ? sql `${right}` : right;
|
|
251
|
-
return sql `(${leftSql} <<% ${rightSql})`;
|
|
240
|
+
return sql `(${left} <<% ${right})`;
|
|
252
241
|
}
|
|
253
242
|
export function distance(left, right) {
|
|
254
|
-
|
|
255
|
-
const rightSql = isString(right) ? sql `${right}` : right;
|
|
256
|
-
return sql `(${leftSql} <-> ${rightSql})`;
|
|
243
|
+
return sql `(${left} <-> ${right})`;
|
|
257
244
|
}
|
|
258
245
|
export function wordDistance(left, right) {
|
|
259
|
-
|
|
260
|
-
const rightSql = isString(right) ? sql `${right}` : right;
|
|
261
|
-
return sql `(${leftSql} <<-> ${rightSql})`;
|
|
246
|
+
return sql `(${left} <<-> ${right})`;
|
|
262
247
|
}
|
|
263
248
|
export function strictWordDistance(left, right) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
249
|
+
return sql `(${left} <<<-> ${right})`;
|
|
250
|
+
}
|
|
251
|
+
export function jsonbBuildObject(properties) {
|
|
252
|
+
const entries = Array.isArray(properties) ? properties : Object.entries(properties);
|
|
253
|
+
const chunks = entries
|
|
254
|
+
.filter(([_, propValue]) => isDefined(propValue))
|
|
255
|
+
.map(([propKey, propValue]) => sql `'${sql.raw(propKey)}', ${propValue}`);
|
|
256
|
+
return sql `jsonb_build_object(${sql.join(chunks, sql `, `)})`;
|
|
267
257
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tstdl/base",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.29",
|
|
4
4
|
"author": "Patrick Hein",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"tsc:watch": "tsc --watch",
|
|
20
20
|
"tsc-alias:watch": "tsc-alias --watch",
|
|
21
21
|
"cleanup:dist": "rm -vrf dist/tools/",
|
|
22
|
-
"generate:migration": "./scripts/manage-orm.sh generate",
|
|
22
|
+
"generate:migration": "./scripts/manage-orm.sh generate && npm run copy:orm",
|
|
23
23
|
"generate:readmes": "deno run --allow-run=code2prompt --allow-read --allow-write=source --allow-net=generativelanguage.googleapis.com --allow-env=GEMINI_API_KEY generate-readmes.ts",
|
|
24
24
|
"generate:readmes:new-only": "npm run generate:readmes -- --skip-existing",
|
|
25
25
|
"generate:llms.md": "npm run build:dts && npm run cleanup:dist && ./scripts/generate-llms-docs.sh",
|
|
@@ -132,11 +132,11 @@
|
|
|
132
132
|
"reflect-metadata": "^0.2",
|
|
133
133
|
"rxjs": "^7.8",
|
|
134
134
|
"ts-pattern": "^5.9",
|
|
135
|
-
"type-fest": "^5.
|
|
135
|
+
"type-fest": "^5.2"
|
|
136
136
|
},
|
|
137
137
|
"peerDependencies": {
|
|
138
138
|
"@google-cloud/storage": "^7.17",
|
|
139
|
-
"@google/genai": "^1.
|
|
139
|
+
"@google/genai": "^1.29",
|
|
140
140
|
"@tstdl/angular": "^0.93",
|
|
141
141
|
"@zxcvbn-ts/core": "^3.0",
|
|
142
142
|
"@zxcvbn-ts/language-common": "^3.0",
|
|
@@ -171,8 +171,8 @@
|
|
|
171
171
|
"@types/pg": "8.15",
|
|
172
172
|
"concurrently": "9.2",
|
|
173
173
|
"drizzle-kit": "0.31",
|
|
174
|
-
"eslint": "9.
|
|
175
|
-
"globals": "16.
|
|
174
|
+
"eslint": "9.39",
|
|
175
|
+
"globals": "16.5",
|
|
176
176
|
"tsc-alias": "1.8",
|
|
177
177
|
"typedoc-github-wiki-theme": "2.1",
|
|
178
178
|
"typedoc-plugin-markdown": "4.9",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
CREATE TABLE "test"."test" (
|
|
2
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
3
|
+
"title" text NOT NULL,
|
|
4
|
+
"content" text NOT NULL,
|
|
5
|
+
"tags" text NOT NULL,
|
|
6
|
+
"language" text NOT NULL
|
|
7
|
+
);
|
|
8
|
+
--> statement-breakpoint
|
|
9
|
+
CREATE INDEX "test_parade_idx" ON "test"."test" USING bm25 ("id","language","title","content","tags",(("title" || ' ' || "content" || ' ' || "tags")::pdb.simple('alias=search_text')),(('foo')::pdb.simple('alias=foo'))) WITH (key_field='id',mutable_segment_rows=12);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"id": "
|
|
2
|
+
"id": "bbffc0f2-678b-42e9-8121-1731a04b8987",
|
|
3
3
|
"prevId": "00000000-0000-0000-0000-000000000000",
|
|
4
4
|
"version": "7",
|
|
5
5
|
"dialect": "postgresql",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"indexes": {
|
|
44
|
-
"
|
|
45
|
-
"name": "
|
|
44
|
+
"test_parade_idx": {
|
|
45
|
+
"name": "test_parade_idx",
|
|
46
46
|
"columns": [
|
|
47
47
|
{
|
|
48
48
|
"expression": "id",
|
|
@@ -51,21 +51,39 @@
|
|
|
51
51
|
"nulls": "last"
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
|
-
"expression": "
|
|
55
|
-
"isExpression": false,
|
|
54
|
+
"expression": "\"language\"",
|
|
56
55
|
"asc": true,
|
|
56
|
+
"isExpression": true,
|
|
57
57
|
"nulls": "last"
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
|
-
"expression": "
|
|
61
|
-
"isExpression": false,
|
|
60
|
+
"expression": "\"title\"",
|
|
62
61
|
"asc": true,
|
|
62
|
+
"isExpression": true,
|
|
63
63
|
"nulls": "last"
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
"expression": "
|
|
67
|
-
"
|
|
66
|
+
"expression": "\"content\"",
|
|
67
|
+
"asc": true,
|
|
68
|
+
"isExpression": true,
|
|
69
|
+
"nulls": "last"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"expression": "\"tags\"",
|
|
73
|
+
"asc": true,
|
|
74
|
+
"isExpression": true,
|
|
75
|
+
"nulls": "last"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"expression": "((\"title\" || ' ' || \"content\" || ' ' || \"tags\")::pdb.simple('alias=search_text'))",
|
|
79
|
+
"asc": true,
|
|
80
|
+
"isExpression": true,
|
|
81
|
+
"nulls": "last"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"expression": "(('foo')::pdb.simple('alias=foo'))",
|
|
68
85
|
"asc": true,
|
|
86
|
+
"isExpression": true,
|
|
69
87
|
"nulls": "last"
|
|
70
88
|
}
|
|
71
89
|
],
|
|
@@ -73,7 +91,8 @@
|
|
|
73
91
|
"concurrently": false,
|
|
74
92
|
"method": "bm25",
|
|
75
93
|
"with": {
|
|
76
|
-
"key_field": "'id'"
|
|
94
|
+
"key_field": "'id'",
|
|
95
|
+
"mutable_segment_rows": 12
|
|
77
96
|
}
|
|
78
97
|
}
|
|
79
98
|
},
|
package/test/test.model.js
CHANGED
|
@@ -7,7 +7,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { sql } from 'drizzle-orm';
|
|
11
|
+
import { BaseEntity, ParadeCompoundIndex, ParadeExpressionIndex, ParadeIndex } from '../orm/index.js';
|
|
11
12
|
import { StringProperty } from '../schema/index.js';
|
|
12
13
|
let Test = class Test extends BaseEntity {
|
|
13
14
|
title;
|
|
@@ -16,14 +17,17 @@ let Test = class Test extends BaseEntity {
|
|
|
16
17
|
language;
|
|
17
18
|
};
|
|
18
19
|
__decorate([
|
|
20
|
+
ParadeIndex(),
|
|
19
21
|
StringProperty(),
|
|
20
22
|
__metadata("design:type", String)
|
|
21
23
|
], Test.prototype, "title", void 0);
|
|
22
24
|
__decorate([
|
|
25
|
+
ParadeIndex(),
|
|
23
26
|
StringProperty(),
|
|
24
27
|
__metadata("design:type", String)
|
|
25
28
|
], Test.prototype, "content", void 0);
|
|
26
29
|
__decorate([
|
|
30
|
+
ParadeIndex(),
|
|
27
31
|
StringProperty(),
|
|
28
32
|
__metadata("design:type", String)
|
|
29
33
|
], Test.prototype, "tags", void 0);
|
|
@@ -32,7 +36,9 @@ __decorate([
|
|
|
32
36
|
__metadata("design:type", String)
|
|
33
37
|
], Test.prototype, "language", void 0);
|
|
34
38
|
Test = __decorate([
|
|
35
|
-
|
|
39
|
+
ParadeExpressionIndex('foo', () => sql `'foo'`),
|
|
40
|
+
ParadeCompoundIndex('search_text', (table) => [table.title, 'content', 'tags']),
|
|
41
|
+
ParadeIndex({ columns: ['language'], mutableSegmentRows: 12 })
|
|
36
42
|
], Test);
|
|
37
43
|
export { Test };
|
|
38
44
|
export const testData = [
|
package/test1.js
CHANGED
|
@@ -53,18 +53,18 @@ async function main(_cancellationSignal) {
|
|
|
53
53
|
if (await repository.count() == 0) {
|
|
54
54
|
await repository.insertMany(testData);
|
|
55
55
|
}
|
|
56
|
-
const result = await repository.
|
|
56
|
+
const result = await repository.loadManyByQuery({
|
|
57
|
+
title: { $parade: { match: { value: 'quick fox', distance: 2 } } },
|
|
58
|
+
});
|
|
59
|
+
const result2 = await repository.search({
|
|
57
60
|
query: {
|
|
58
|
-
$
|
|
59
|
-
fields: ['title'],
|
|
60
|
-
query: 'lorem ipsum dolor sit amet',
|
|
61
|
-
},
|
|
61
|
+
$parade: { fields: ['content'], query: 'vibrant city' },
|
|
62
62
|
},
|
|
63
|
-
|
|
64
|
-
order: (x) => ['title', x.score],
|
|
65
|
-
limit: 10,
|
|
63
|
+
highlight: { source: 'content', includePositions: true },
|
|
66
64
|
});
|
|
67
|
-
|
|
65
|
+
for (const item of result2) {
|
|
66
|
+
console.log(item);
|
|
67
|
+
}
|
|
68
68
|
}
|
|
69
69
|
Application.run('Test', [
|
|
70
70
|
provideInitializer(bootstrap),
|
package/utils/enum.js
CHANGED
|
@@ -10,7 +10,7 @@ const memoizedEnumValues = memoizeSingle((enumeration) => {
|
|
|
10
10
|
const entries = enumEntries(enumeration);
|
|
11
11
|
return entries.map((entry) => entry[1]);
|
|
12
12
|
}, { weak: true });
|
|
13
|
-
const memoizedReversedEnum = memoizeSingle((enumeration) => mapObject(enumeration, (
|
|
13
|
+
const memoizedReversedEnum = memoizeSingle((enumeration) => mapObject(enumeration, (key, value) => [value, key]), { weak: true });
|
|
14
14
|
export function enumValueName(enumeration, value) {
|
|
15
15
|
return reversedEnum(enumeration)[value];
|
|
16
16
|
}
|
package/utils/object/object.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SnakeCasedProperties } from 'type-fest';
|
|
1
2
|
import { type JsonPathInput } from '../../json-path/json-path.js';
|
|
2
3
|
import type { BaseType, Entries, FromEntries, ObjectLiteral, Optionalize, OptionalizeNull, PickBy, Record, SimplifyObject, UnionToIntersection } from '../../types/index.js';
|
|
3
4
|
export declare function hasOwnProperty<T extends ObjectLiteral, K extends keyof UnionToIntersection<T>>(obj: T, key: K): obj is Extract<T, Partial<Record<K>>>;
|
|
@@ -13,15 +14,16 @@ export declare function objectKeys<T extends ObjectLiteral>(object: T): (keyof T
|
|
|
13
14
|
export declare function objectValues<T extends ObjectLiteral>(object: T): (T[keyof T])[];
|
|
14
15
|
export declare function fromEntries<A>(entries: A): FromEntries<A>;
|
|
15
16
|
export declare function fromEntries<K extends PropertyKey, T>(entries: Iterable<readonly [K, T]>): Record<K, T>;
|
|
16
|
-
export declare function mapObject<T extends ObjectLiteral, K extends PropertyKey, V>(object: T, mapper: (
|
|
17
|
-
export declare function mapObjectAsync<T extends ObjectLiteral, K extends PropertyKey, V>(object: T, mapper: (
|
|
17
|
+
export declare function mapObject<T extends ObjectLiteral, K extends PropertyKey, V>(object: T, mapper: (key: keyof T, value: T[keyof T]) => [key: K, value: V] | null | undefined): Record<K, V>;
|
|
18
|
+
export declare function mapObjectAsync<T extends ObjectLiteral, K extends PropertyKey, V>(object: T, mapper: (key: keyof T, value: T[keyof T]) => Promise<[key: K, value: V] | null | undefined>): Promise<Record<K, V>>;
|
|
18
19
|
export declare function mapObjectValues<T extends ObjectLiteral, V>(object: T, mapper: (value: T[keyof T], key: keyof T) => V): Record<keyof T, V>;
|
|
19
20
|
export declare function mapObjectKeys<T extends ObjectLiteral, K extends PropertyKey>(object: T, mapper: (key: keyof T, value: T[keyof T]) => K): Record<K, T[keyof T]>;
|
|
21
|
+
export declare function mapObjectKeysToSnakeCase<T extends Record<string>>(object: T): SnakeCasedProperties<T>;
|
|
20
22
|
export declare function mapObjectValuesAsync<T extends ObjectLiteral, V>(object: T, mapper: (value: T[keyof T], key: keyof T) => Promise<V>): Promise<Record<keyof T, V>>;
|
|
21
23
|
export declare function filterObject<T extends ObjectLiteral, U extends T[keyof T]>(object: T, predicate: (value: T[keyof T], key: keyof T) => value is U): PickBy<T, U>;
|
|
22
24
|
export declare function filterObject<T extends ObjectLiteral>(object: T, predicate: (value: T[keyof T], key: keyof T) => boolean): Partial<T>;
|
|
23
25
|
export declare function filterObjectAsync<T extends ObjectLiteral>(object: T, predicate: (value: T[keyof T], key: keyof T) => Promise<boolean>): Promise<Partial<T>>;
|
|
24
|
-
export declare function filterUndefinedFromRecord<K extends PropertyKey, V>(record: Record<K, V
|
|
26
|
+
export declare function filterUndefinedFromRecord<K extends PropertyKey, V>(record: Partial<Record<K, V>>): Record<BaseType<K>, Exclude<V, undefined>>;
|
|
25
27
|
export declare function filterNullishFromRecord<K extends PropertyKey, V>(record: Record<K, V>): Record<BaseType<K>, Exclude<V, null | undefined>>;
|
|
26
28
|
export declare function filterUndefinedObjectProperties<T extends ObjectLiteral>(object: T): SimplifyObject<Optionalize<T>>;
|
|
27
29
|
export declare function filterNullishObjectProperties<T extends ObjectLiteral>(object: T): SimplifyObject<OptionalizeNull<Optionalize<T>>>;
|
package/utils/object/object.js
CHANGED
|
@@ -2,7 +2,8 @@ import { JsonPath } from '../../json-path/json-path.js';
|
|
|
2
2
|
import { filterAsync } from '../async-iterable-helpers/filter.js';
|
|
3
3
|
import { mapAsync } from '../async-iterable-helpers/map.js';
|
|
4
4
|
import { toArrayAsync } from '../async-iterable-helpers/to-array.js';
|
|
5
|
-
import {
|
|
5
|
+
import { toSnakeCase } from '../string/index.js';
|
|
6
|
+
import { isArray, isDefined, isNotNullOrUndefined, isNullOrUndefined, isObject, isSymbol, isUndefined } from '../type-guards.js';
|
|
6
7
|
export function hasOwnProperty(obj, key) {
|
|
7
8
|
return Object.hasOwn(obj, key);
|
|
8
9
|
}
|
|
@@ -26,22 +27,31 @@ export function fromEntries(entries) {
|
|
|
26
27
|
return Object.fromEntries(entries);
|
|
27
28
|
}
|
|
28
29
|
export function mapObject(object, mapper) {
|
|
29
|
-
const mappedEntries = objectKeys(object).
|
|
30
|
+
const mappedEntries = objectKeys(object).flatMap((key) => {
|
|
31
|
+
const result = mapper(key, object[key]);
|
|
32
|
+
if (isNullOrUndefined(result)) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
return [result];
|
|
36
|
+
});
|
|
30
37
|
return Object.fromEntries(mappedEntries);
|
|
31
38
|
}
|
|
32
39
|
export async function mapObjectAsync(object, mapper) {
|
|
33
40
|
const entries = objectKeys(object);
|
|
34
|
-
const mappedEntries = await toArrayAsync(mapAsync(entries, async (key) => await mapper(object[key]
|
|
35
|
-
return Object.fromEntries(mappedEntries);
|
|
41
|
+
const mappedEntries = await toArrayAsync(mapAsync(entries, async (key) => await mapper(key, object[key])));
|
|
42
|
+
return Object.fromEntries(mappedEntries.filter(isNotNullOrUndefined));
|
|
36
43
|
}
|
|
37
44
|
export function mapObjectValues(object, mapper) {
|
|
38
|
-
return mapObject(object, (
|
|
45
|
+
return mapObject(object, (key, value) => [key, mapper(value, key)]);
|
|
39
46
|
}
|
|
40
47
|
export function mapObjectKeys(object, mapper) {
|
|
41
|
-
return mapObject(object, (
|
|
48
|
+
return mapObject(object, (key, value) => [mapper(key, value), value]);
|
|
49
|
+
}
|
|
50
|
+
export function mapObjectKeysToSnakeCase(object) {
|
|
51
|
+
return mapObjectKeys(object, (key) => toSnakeCase(key));
|
|
42
52
|
}
|
|
43
53
|
export async function mapObjectValuesAsync(object, mapper) {
|
|
44
|
-
return await mapObjectAsync(object, async (
|
|
54
|
+
return await mapObjectAsync(object, async (key, value) => [key, await mapper(value, key)]);
|
|
45
55
|
}
|
|
46
56
|
export function filterObject(object, predicate) {
|
|
47
57
|
const mappedEntries = objectEntries(object).filter(([key, value]) => predicate(value, key));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const wordsPattern = /[\da-z]+|[A-Z]+(?![a-z])|[A-Z][\da-z]+/g;
|
|
2
|
+
export function toSnakeCase(value) {
|
|
3
|
+
const words = matchWords(value);
|
|
4
|
+
return words.map((word) => word.toLowerCase()).join('_');
|
|
5
|
+
}
|
|
6
|
+
export function toCamelCase(value) {
|
|
7
|
+
const words = matchWords(value);
|
|
8
|
+
return words.reduce((acc, word, index) => {
|
|
9
|
+
const formattedWord = (index == 0) ? word.toLowerCase() : `${word[0].toUpperCase()}${word.slice(1)}`;
|
|
10
|
+
return acc + formattedWord;
|
|
11
|
+
}, '');
|
|
12
|
+
}
|
|
13
|
+
function matchWords(value) {
|
|
14
|
+
return value.replace(/['\u2019]/g, '').match(wordsPattern) ?? [];
|
|
15
|
+
}
|
package/utils/string/index.d.ts
CHANGED
package/utils/string/index.js
CHANGED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
CREATE TABLE "test"."test" (
|
|
2
|
-
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
3
|
-
"title" text NOT NULL,
|
|
4
|
-
"content" text NOT NULL,
|
|
5
|
-
"tags" text NOT NULL,
|
|
6
|
-
"language" text NOT NULL
|
|
7
|
-
);
|
|
8
|
-
--> statement-breakpoint
|
|
9
|
-
CREATE INDEX "test_id_title_content_tags_idx" ON "test"."test" USING bm25 ("id","title","content","tags") WITH (key_field='id');
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function toSnakeCase(value: string): string;
|