@tstdl/base 0.92.167 → 0.93.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/application/application.d.ts +12 -18
- package/application/application.js +48 -69
- package/application/index.d.ts +1 -5
- package/application/index.js +1 -5
- package/application/providers.d.ts +10 -0
- package/application/providers.js +54 -0
- package/audit/audit.model.d.ts +15 -0
- package/audit/audit.model.js +73 -0
- package/audit/auditor.d.ts +42 -0
- package/audit/auditor.js +111 -0
- package/audit/index.d.ts +3 -0
- package/audit/index.js +3 -0
- package/audit/types.d.ts +22 -0
- package/audit/types.js +19 -0
- package/authentication/client/authentication.service.d.ts +1 -3
- package/authentication/client/authentication.service.js +4 -5
- package/browser/browser-context-controller.d.ts +2 -4
- package/browser/browser-context-controller.js +5 -6
- package/browser/browser-controller.d.ts +2 -4
- package/browser/browser-controller.js +3 -4
- package/browser/browser.service.d.ts +1 -3
- package/browser/browser.service.js +1 -2
- package/browser/page-controller.d.ts +2 -4
- package/browser/page-controller.js +7 -8
- package/browser/utils.js +3 -3
- package/cancellation/token.d.ts +104 -41
- package/cancellation/token.js +125 -54
- package/core.d.ts +1 -13
- package/core.js +1 -46
- package/disposable/disposable.d.ts +0 -8
- package/disposable/disposable.js +1 -3
- package/disposable/index.d.ts +0 -6
- package/disposable/index.js +0 -6
- package/disposable/using.d.ts +0 -1
- package/disposable/using.js +2 -3
- package/distributed-loop/distributed-loop.js +2 -2
- package/errors/utils.js +4 -1
- package/examples/api/authentication.js +11 -5
- package/examples/api/basic-overview.js +17 -12
- package/examples/api/custom-authentication.js +13 -7
- package/examples/api/streaming.js +15 -12
- package/examples/browser/basic.js +6 -3
- package/examples/document-management/main.js +6 -3
- package/examples/http/client.js +7 -3
- package/examples/mail/basic.js +9 -7
- package/examples/pdf/basic.js +8 -6
- package/examples/template/basic.js +7 -5
- package/http/client/http-client-request.d.ts +1 -2
- package/http/client/http-client-request.js +1 -2
- package/http/server/http-server.d.ts +1 -3
- package/http/server/http-server.js +0 -1
- package/http/server/node/node-http-server.d.ts +1 -2
- package/http/server/node/node-http-server.js +1 -2
- package/import.js +1 -1
- package/injector/injector.d.ts +1 -1
- package/injector/types.d.ts +3 -4
- package/lock/lock.d.ts +40 -21
- package/lock/lock.js +74 -1
- package/lock/postgres/drizzle/0000_busy_tattoo.sql +7 -0
- package/lock/postgres/drizzle/meta/0000_snapshot.json +65 -0
- package/lock/postgres/drizzle/meta/_journal.json +13 -0
- package/lock/postgres/drizzle.config.js +11 -0
- package/lock/postgres/index.d.ts +2 -0
- package/lock/postgres/index.js +2 -0
- package/lock/postgres/lock.d.ts +14 -0
- package/lock/postgres/lock.js +127 -0
- package/lock/postgres/models/index.d.ts +2 -0
- package/lock/postgres/models/index.js +2 -0
- package/lock/postgres/models/lock.model.d.ts +7 -0
- package/{examples/orm/user.model.js → lock/postgres/models/lock.model.js} +22 -30
- package/lock/postgres/models/schemas.d.ts +3 -0
- package/lock/postgres/models/schemas.js +4 -0
- package/lock/postgres/module.d.ts +6 -0
- package/lock/postgres/module.js +26 -0
- package/lock/postgres/provider.d.ts +6 -0
- package/lock/postgres/provider.js +29 -0
- package/lock/provider.d.ts +12 -2
- package/lock/provider.js +24 -1
- package/lock/web/web-lock.d.ts +4 -3
- package/lock/web/web-lock.js +49 -42
- package/lock/web/web-lock.provider.d.ts +0 -3
- package/lock/web/web-lock.provider.js +5 -22
- package/logger/formatter.d.ts +13 -0
- package/logger/formatter.js +3 -0
- package/logger/formatters/index.d.ts +2 -0
- package/logger/formatters/index.js +2 -0
- package/logger/formatters/json.d.ts +5 -0
- package/logger/formatters/json.js +33 -0
- package/logger/formatters/pretty-print.d.ts +5 -0
- package/logger/formatters/pretty-print.js +55 -0
- package/logger/index.d.ts +5 -2
- package/logger/index.js +5 -2
- package/logger/level.d.ts +10 -8
- package/logger/level.js +9 -9
- package/logger/logger.d.ts +21 -30
- package/logger/logger.js +98 -26
- package/logger/manager.d.ts +20 -0
- package/logger/manager.js +86 -0
- package/logger/tokens.d.ts +1 -1
- package/logger/tokens.js +1 -1
- package/logger/transport.d.ts +14 -0
- package/logger/transport.js +16 -0
- package/logger/transports/console.d.ts +14 -0
- package/logger/transports/console.js +36 -0
- package/logger/transports/index.d.ts +1 -0
- package/logger/transports/index.js +1 -0
- package/mail/clients/nodemailer.mail-client.d.ts +0 -1
- package/mail/clients/nodemailer.mail-client.js +9 -7
- package/message-bus/local/local-message-bus.js +2 -2
- package/message-bus/message-bus-base.d.ts +2 -3
- package/message-bus/message-bus-base.js +5 -6
- package/message-bus/message-bus.d.ts +1 -2
- package/message-bus/message-bus.js +1 -2
- package/module/index.d.ts +0 -2
- package/module/index.js +0 -2
- package/module/module.d.ts +17 -18
- package/module/module.js +47 -12
- package/module/modules/function.module.d.ts +6 -6
- package/module/modules/function.module.js +25 -9
- package/module/modules/web-server.module.d.ts +2 -10
- package/module/modules/web-server.module.js +3 -11
- package/openid-connect/index.d.ts +0 -2
- package/openid-connect/index.js +0 -2
- package/openid-connect/oidc-state.model.d.ts +4 -5
- package/openid-connect/oidc-state.model.js +51 -1
- package/openid-connect/oidc.service-model.d.ts +1 -1
- package/openid-connect/oidc.service.d.ts +2 -6
- package/openid-connect/oidc.service.js +24 -37
- package/orm/decorators.d.ts +10 -1
- package/orm/decorators.js +8 -0
- package/orm/server/repository.d.ts +3 -1
- package/orm/server/repository.js +32 -3
- package/package.json +19 -29
- package/pdf/pdf.service.js +9 -9
- package/pool/pool.d.ts +1 -3
- package/pool/pool.js +3 -4
- package/queue/postgres/job.model.d.ts +1 -2
- package/queue/postgres/job.model.js +1 -2
- package/queue/postgres/module.js +1 -1
- package/threading/thread-pool.d.ts +1 -3
- package/threading/thread-pool.js +7 -8
- package/utils/format-error.d.ts +7 -0
- package/utils/format-error.js +59 -17
- package/utils/function/memoize.d.ts +22 -7
- package/utils/function/memoize.js +82 -23
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/object/dereference.d.ts +51 -19
- package/utils/object/dereference.js +52 -43
- package/utils/timing.js +2 -2
- package/utils/try-chain.d.ts +22 -0
- package/utils/try-chain.js +46 -0
- package/database/entity-repository.d.ts +0 -50
- package/database/entity-repository.js +0 -3
- package/database/entity.d.ts +0 -7
- package/database/entity.js +0 -1
- package/database/id.d.ts +0 -1
- package/database/id.js +0 -9
- package/database/index.d.ts +0 -11
- package/database/index.js +0 -11
- package/database/module.d.ts +0 -8
- package/database/module.js +0 -11
- package/database/mongo/classes.d.ts +0 -21
- package/database/mongo/classes.js +0 -26
- package/database/mongo/index.d.ts +0 -15
- package/database/mongo/index.js +0 -15
- package/database/mongo/model/document.d.ts +0 -29
- package/database/mongo/model/document.js +0 -63
- package/database/mongo/model/index.d.ts +0 -1
- package/database/mongo/model/index.js +0 -1
- package/database/mongo/module.d.ts +0 -8
- package/database/mongo/module.js +0 -68
- package/database/mongo/mongo-base.repository.d.ts +0 -103
- package/database/mongo/mongo-base.repository.js +0 -263
- package/database/mongo/mongo-bulk.d.ts +0 -35
- package/database/mongo/mongo-bulk.js +0 -90
- package/database/mongo/mongo-entity-repository.d.ts +0 -98
- package/database/mongo/mongo-entity-repository.js +0 -278
- package/database/mongo/operations.d.ts +0 -10
- package/database/mongo/operations.js +0 -54
- package/database/mongo/query-converter.d.ts +0 -6
- package/database/mongo/query-converter.js +0 -83
- package/database/mongo/simple-entity-repository.d.ts +0 -7
- package/database/mongo/simple-entity-repository.js +0 -6
- package/database/mongo/types.d.ts +0 -50
- package/database/mongo/types.js +0 -3
- package/database/query.d.ts +0 -121
- package/database/query.js +0 -7
- package/database/utils.d.ts +0 -2
- package/database/utils.js +0 -3
- package/disposable/async-disposer.d.ts +0 -35
- package/disposable/async-disposer.js +0 -125
- package/examples/orm/drizzle.config.js +0 -6
- package/examples/orm/schemas.d.ts +0 -3
- package/examples/orm/schemas.js +0 -4
- package/examples/orm/test.d.ts +0 -1
- package/examples/orm/test.js +0 -11
- package/examples/orm/user.model.d.ts +0 -13
- package/key-value-store/mongo/index.d.ts +0 -6
- package/key-value-store/mongo/index.js +0 -6
- package/key-value-store/mongo/module.d.ts +0 -8
- package/key-value-store/mongo/module.js +0 -18
- package/key-value-store/mongo/mongo-key-value-store.provider.d.ts +0 -8
- package/key-value-store/mongo/mongo-key-value-store.provider.js +0 -26
- package/key-value-store/mongo/mongo-key-value.model.d.ts +0 -7
- package/key-value-store/mongo/mongo-key-value.model.js +0 -1
- package/key-value-store/mongo/mongo-key-value.repository.d.ts +0 -10
- package/key-value-store/mongo/mongo-key-value.repository.js +0 -31
- package/key-value-store/mongo/mongo-key-value.store.d.ts +0 -15
- package/key-value-store/mongo/mongo-key-value.store.js +0 -82
- package/key-value-store/mongo/tokens.d.ts +0 -3
- package/key-value-store/mongo/tokens.js +0 -2
- package/lock/mongo/index.d.ts +0 -5
- package/lock/mongo/index.js +0 -5
- package/lock/mongo/lock.d.ts +0 -14
- package/lock/mongo/lock.js +0 -125
- package/lock/mongo/model.d.ts +0 -6
- package/lock/mongo/model.js +0 -1
- package/lock/mongo/module.d.ts +0 -12
- package/lock/mongo/module.js +0 -20
- package/lock/mongo/mongo-lock-repository.d.ts +0 -14
- package/lock/mongo/mongo-lock-repository.js +0 -67
- package/lock/mongo/provider.d.ts +0 -8
- package/lock/mongo/provider.js +0 -36
- package/logger/console/index.d.ts +0 -1
- package/logger/console/index.js +0 -1
- package/logger/console/logger.d.ts +0 -11
- package/logger/console/logger.js +0 -64
- package/logger/noop/index.d.ts +0 -1
- package/logger/noop/index.js +0 -1
- package/logger/noop/logger.d.ts +0 -9
- package/logger/noop/logger.js +0 -21
- package/migration/index.d.ts +0 -9
- package/migration/index.js +0 -9
- package/migration/migration-state-repository.d.ts +0 -4
- package/migration/migration-state-repository.js +0 -3
- package/migration/migration-state.d.ts +0 -6
- package/migration/migration-state.js +0 -1
- package/migration/migrator.d.ts +0 -23
- package/migration/migrator.js +0 -76
- package/migration/mongo/index.d.ts +0 -2
- package/migration/mongo/index.js +0 -2
- package/migration/mongo/migration-state-repository.d.ts +0 -11
- package/migration/mongo/migration-state-repository.js +0 -32
- package/migration/mongo/module.d.ts +0 -12
- package/migration/mongo/module.js +0 -17
- package/module/module-base.d.ts +0 -18
- package/module/module-base.js +0 -40
- package/module/module-metric-reporter.d.ts +0 -29
- package/module/module-metric-reporter.js +0 -62
- package/openid-connect/mongo-oidc-state.repository.d.ts +0 -21
- package/openid-connect/mongo-oidc-state.repository.js +0 -52
- package/openid-connect/oidc-state.repository.d.ts +0 -4
- package/openid-connect/oidc-state.repository.js +0 -3
- package/process-shutdown.d.ts +0 -9
- package/process-shutdown.js +0 -65
- package/queue/mongo/index.d.ts +0 -4
- package/queue/mongo/index.js +0 -4
- package/queue/mongo/job.d.ts +0 -12
- package/queue/mongo/job.js +0 -1
- package/queue/mongo/mongo-job.repository.d.ts +0 -13
- package/queue/mongo/mongo-job.repository.js +0 -54
- package/queue/mongo/queue.d.ts +0 -38
- package/queue/mongo/queue.js +0 -266
- package/queue/mongo/queue.provider.d.ts +0 -18
- package/queue/mongo/queue.provider.js +0 -38
- package/search-index/elastic/config.d.ts +0 -8
- package/search-index/elastic/config.js +0 -26
- package/search-index/elastic/index.d.ts +0 -8
- package/search-index/elastic/index.js +0 -8
- package/search-index/elastic/keyword-rewriter.d.ts +0 -8
- package/search-index/elastic/keyword-rewriter.js +0 -18
- package/search-index/elastic/model/elastic-query.d.ts +0 -16
- package/search-index/elastic/model/elastic-query.js +0 -1
- package/search-index/elastic/model/index-mapping.d.ts +0 -26
- package/search-index/elastic/model/index-mapping.js +0 -4
- package/search-index/elastic/model/index.d.ts +0 -3
- package/search-index/elastic/model/index.js +0 -3
- package/search-index/elastic/model/sort.d.ts +0 -8
- package/search-index/elastic/model/sort.js +0 -1
- package/search-index/elastic/module.d.ts +0 -10
- package/search-index/elastic/module.js +0 -49
- package/search-index/elastic/query-builder/boolean-query-builder.d.ts +0 -11
- package/search-index/elastic/query-builder/boolean-query-builder.js +0 -52
- package/search-index/elastic/query-builder/index.d.ts +0 -1
- package/search-index/elastic/query-builder/index.js +0 -1
- package/search-index/elastic/query-converter.d.ts +0 -9
- package/search-index/elastic/query-converter.js +0 -183
- package/search-index/elastic/search-index.d.ts +0 -30
- package/search-index/elastic/search-index.js +0 -144
- package/search-index/elastic/sort-converter.d.ts +0 -4
- package/search-index/elastic/sort-converter.js +0 -14
- package/search-index/elastic/types.d.ts +0 -5
- package/search-index/elastic/types.js +0 -1
- package/search-index/error.d.ts +0 -10
- package/search-index/error.js +0 -14
- package/search-index/index.d.ts +0 -3
- package/search-index/index.js +0 -3
- package/search-index/memory/index.d.ts +0 -1
- package/search-index/memory/index.js +0 -1
- package/search-index/memory/memory-search-index.d.ts +0 -19
- package/search-index/memory/memory-search-index.js +0 -144
- package/search-index/search-index.d.ts +0 -46
- package/search-index/search-index.js +0 -31
- package/search-index/search-result.d.ts +0 -12
- package/search-index/search-result.js +0 -1
- package/theme/adapters/css-adapter.d.ts +0 -5
- package/theme/adapters/css-adapter.js +0 -29
- package/theme/adapters/index.d.ts +0 -2
- package/theme/adapters/index.js +0 -2
- package/theme/adapters/tailwind-adapter.d.ts +0 -18
- package/theme/adapters/tailwind-adapter.js +0 -32
- package/theme/index.d.ts +0 -1
- package/theme/index.js +0 -1
- package/theme/theme-service.d.ts +0 -43
- package/theme/theme-service.js +0 -128
- /package/{examples/orm → lock/postgres}/drizzle.config.d.ts +0 -0
package/orm/decorators.js
CHANGED
|
@@ -145,3 +145,11 @@ export function Index(columnsOrOptions, options) {
|
|
|
145
145
|
}
|
|
146
146
|
return createColumnDecorator({ index: { options: columnsOrOptions } });
|
|
147
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Decorator to mark a column as an expiration field. This will be used to automatically delete records when expired.
|
|
150
|
+
* @param mode - Whether to delete soft or hard.
|
|
151
|
+
* @returns A property decorator.
|
|
152
|
+
*/
|
|
153
|
+
export function ExpiresAt(mode = 'soft') {
|
|
154
|
+
return createColumnDecorator({ expirationField: { mode } });
|
|
155
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SQL } from 'drizzle-orm';
|
|
2
2
|
import type { PgColumn, PgInsertValue, PgUpdateSetSource } from 'drizzle-orm/pg-core';
|
|
3
|
-
import { type Resolvable, resolveArgumentType } from '../../injector/interfaces.js';
|
|
3
|
+
import { afterResolve, type Resolvable, resolveArgumentType } from '../../injector/interfaces.js';
|
|
4
4
|
import type { DeepPartial, OneOrMany, Paths, Type, UntaggedDeep } from '../../types/index.js';
|
|
5
5
|
import { Entity, type EntityMetadataAttributes, type EntityType, type EntityWithoutMetadata } from '../entity.js';
|
|
6
6
|
import type { Query } from '../query.js';
|
|
@@ -37,6 +37,8 @@ export declare class EntityRepository<T extends Entity | EntityWithoutMetadata =
|
|
|
37
37
|
*/
|
|
38
38
|
get table(): PgTableFromType<EntityType<T>>;
|
|
39
39
|
readonly [resolveArgumentType]: EntityType<T>;
|
|
40
|
+
[afterResolve](): void;
|
|
41
|
+
private expirationLoop;
|
|
40
42
|
protected getTransactionalContextData(): EntityRepositoryContext;
|
|
41
43
|
/**
|
|
42
44
|
* Loads a single entity by its ID.
|
package/orm/server/repository.js
CHANGED
|
@@ -4,20 +4,24 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { and, asc, count, desc, eq, inArray, isNull, isSQLWrapper, SQL, sql } from 'drizzle-orm';
|
|
7
|
+
import { and, asc, count, desc, eq, inArray, isNull, isSQLWrapper, lte, or, SQL, sql } from 'drizzle-orm';
|
|
8
8
|
import { match } from 'ts-pattern';
|
|
9
|
+
import { CancellationSignal } from '../../cancellation/token.js';
|
|
9
10
|
import { NotFoundError } from '../../errors/not-found.error.js';
|
|
10
11
|
import { Singleton } from '../../injector/decorators.js';
|
|
11
12
|
import { inject, injectArgument } from '../../injector/inject.js';
|
|
12
|
-
import { resolveArgumentType } from '../../injector/interfaces.js';
|
|
13
|
+
import { afterResolve, resolveArgumentType } from '../../injector/interfaces.js';
|
|
13
14
|
import { Schema } from '../../schema/schema.js';
|
|
14
15
|
import { distinct, toArray } from '../../utils/array/array.js';
|
|
15
16
|
import { mapAsync } from '../../utils/async-iterable-helpers/map.js';
|
|
16
17
|
import { toArrayAsync } from '../../utils/async-iterable-helpers/to-array.js';
|
|
17
18
|
import { importSymmetricKey } from '../../utils/cryptography.js';
|
|
18
19
|
import { fromDeepObjectEntries, fromEntries, objectEntries } from '../../utils/object/object.js';
|
|
19
|
-
import {
|
|
20
|
+
import { cancelableTimeout } from '../../utils/timing.js';
|
|
21
|
+
import { tryIgnoreAsync } from '../../utils/try-ignore.js';
|
|
22
|
+
import { assertDefined, assertDefinedPass, isArray, isDefined, isString, isUndefined } from '../../utils/type-guards.js';
|
|
20
23
|
import { typeExtends } from '../../utils/type/index.js';
|
|
24
|
+
import { millisecondsPerSecond } from '../../utils/units.js';
|
|
21
25
|
import { Entity } from '../entity.js';
|
|
22
26
|
import { TRANSACTION_TIMESTAMP } from '../sqls.js';
|
|
23
27
|
import { getColumnDefinitions, getColumnDefinitionsMap, getDrizzleTableFromType } from './drizzle/schema-converter.js';
|
|
@@ -37,6 +41,7 @@ const entityTypeToken = Symbol('EntityType');
|
|
|
37
41
|
let EntityRepository = class EntityRepository extends Transactional {
|
|
38
42
|
#context = isInTransactionalContext() ? getTransactionalContextData(this) : {};
|
|
39
43
|
#encryptionSecret = isInTransactionalContext() ? this.#context.encryptionSecret : inject(ENCRYPTION_SECRET, undefined, { optional: true });
|
|
44
|
+
#cancellationSignal = isInTransactionalContext() ? undefined : inject(CancellationSignal);
|
|
40
45
|
#transformContext = this.#context.transformContext;
|
|
41
46
|
type = this.#context.type ?? injectArgument(this, { optional: true }) ?? assertDefinedPass(this.constructor[entityTypeToken], 'Missing entity type.');
|
|
42
47
|
typeName = this.type.entityName ?? this.type.name;
|
|
@@ -51,6 +56,30 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
51
56
|
get table() {
|
|
52
57
|
return this.#table;
|
|
53
58
|
}
|
|
59
|
+
[afterResolve]() {
|
|
60
|
+
if (!this.isInTransaction) {
|
|
61
|
+
void this.expirationLoop();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async expirationLoop() {
|
|
65
|
+
const softExpirationColumns = this.#columnDefinitions.filter((column) => column.reflectionData?.expirationField?.mode == 'soft');
|
|
66
|
+
const hardExpirationColumns = this.#columnDefinitions.filter((column) => column.reflectionData?.expirationField?.mode == 'hard');
|
|
67
|
+
if ((softExpirationColumns.length + hardExpirationColumns.length) == 0) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const softDeletionQuery = or(...softExpirationColumns.map((column) => lte(this.getColumn(column), TRANSACTION_TIMESTAMP)));
|
|
71
|
+
const hardDeletionQuery = or(...hardExpirationColumns.map((column) => lte(this.getColumn(column), TRANSACTION_TIMESTAMP)));
|
|
72
|
+
assertDefined(this.#cancellationSignal);
|
|
73
|
+
while (this.#cancellationSignal.isUnset) {
|
|
74
|
+
if (isDefined(softDeletionQuery)) {
|
|
75
|
+
await tryIgnoreAsync(async () => await this.deleteManyByQuery(softDeletionQuery));
|
|
76
|
+
}
|
|
77
|
+
if (isDefined(hardDeletionQuery)) {
|
|
78
|
+
await tryIgnoreAsync(async () => await this.hardDeleteManyByQuery(hardDeletionQuery));
|
|
79
|
+
}
|
|
80
|
+
await cancelableTimeout(30 * millisecondsPerSecond, this.#cancellationSignal);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
54
83
|
getTransactionalContextData() {
|
|
55
84
|
const context = {
|
|
56
85
|
type: this.type,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tstdl/base",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.93.0",
|
|
4
4
|
"author": "Patrick Hein",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -11,27 +11,32 @@
|
|
|
11
11
|
"build:watch": "concurrently --raw --kill-others npm:tsc:watch npm:tsc-alias:watch",
|
|
12
12
|
"build:production": "rm -rf dist && npm run build && npm run build:production:copy-files",
|
|
13
13
|
"build:production:copy-files": "cp package.json eslint.config.js tsconfig.server.json dist/ && cp tsconfig.base.json dist/tsconfig.json && npm run copy:orm",
|
|
14
|
-
"build:dts": "tsc -p tsconfig.dts.json",
|
|
14
|
+
"build:dts": "rm -rf dist && tsc -p tsconfig.dts.json && tsc-alias",
|
|
15
15
|
"build:docs": "typedoc",
|
|
16
16
|
"build:docs:watch": "typedoc --watch",
|
|
17
17
|
"lint": "eslint --cache source/",
|
|
18
|
-
"pub": "npm run build:production &&
|
|
18
|
+
"pub": "npm run build:production && npm run cleanup:dist && npm publish dist/",
|
|
19
19
|
"tsc:watch": "tsc --watch",
|
|
20
20
|
"tsc-alias:watch": "tsc-alias --watch",
|
|
21
|
-
"
|
|
21
|
+
"cleanup:dist": "rm -vf dist/test* && rm -vrf dist/tools/",
|
|
22
|
+
"generate:migration": "npm run generate:migration:document-management && npm run generate:migration:authentication && npm run generate:migration:mail && npm run generate:migration:queue && npm run generate:migration:key-value-store && npm run generate:migration:lock",
|
|
22
23
|
"generate:migration:document-management": "drizzle-kit generate --config dist/document-management/server/drizzle.config.js",
|
|
23
24
|
"generate:migration:authentication": "drizzle-kit generate --config dist/authentication/server/drizzle.config.js",
|
|
24
25
|
"generate:migration:mail": "drizzle-kit generate --config dist/mail/drizzle.config.js",
|
|
25
26
|
"generate:migration:queue": "drizzle-kit generate --config dist/queue/postgres/drizzle.config.js",
|
|
26
27
|
"generate:migration:key-value-store": "drizzle-kit generate --config dist/key-value-store/postgres/drizzle.config.js",
|
|
27
|
-
"generate:
|
|
28
|
+
"generate:migration:lock": "drizzle-kit generate --config dist/lock/postgres/drizzle.config.js",
|
|
29
|
+
"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",
|
|
28
30
|
"generate:readmes:new-only": "npm run generate:readmes -- --skip-existing",
|
|
29
|
-
"
|
|
31
|
+
"generate:llms.md": "npm run build:dts && npm run cleanup:dist && ./scripts/generate-llms-docs.sh",
|
|
32
|
+
"generate:context7-docs": "npm run build:dts && npm run cleanup:dist && ./scripts/generate-context7-docs.sh",
|
|
33
|
+
"copy:orm": "npm run copy:orm:document-management && npm run copy:orm:authentication && npm run copy:orm:mail && npm run copy:orm:queue && npm run copy:orm:key-value-store && npm run copy:orm:lock",
|
|
30
34
|
"copy:orm:document-management": "rm -rf ./dist/document-management/server/drizzle && cp -r ./source/document-management/server/drizzle ./dist/document-management/server/",
|
|
31
35
|
"copy:orm:authentication": "rm -rf ./dist/authentication/server/drizzle && cp -r ./source/authentication/server/drizzle ./dist/authentication/server/",
|
|
32
36
|
"copy:orm:mail": "rm -rf ./dist/mail/drizzle && cp -r ./source/mail/drizzle ./dist/mail/",
|
|
33
37
|
"copy:orm:queue": "rm -rf ./dist/queue/postgres/drizzle && cp -r ./source/queue/postgres/drizzle ./dist/queue/postgres/",
|
|
34
|
-
"copy:orm:key-value-store": "rm -rf ./dist/key-value-store/postgres/drizzle && cp -r ./source/key-value-store/postgres/drizzle ./dist/key-value-store/postgres/"
|
|
38
|
+
"copy:orm:key-value-store": "rm -rf ./dist/key-value-store/postgres/drizzle && cp -r ./source/key-value-store/postgres/drizzle ./dist/key-value-store/postgres/",
|
|
39
|
+
"copy:orm:lock": "rm -rf ./dist/lock/postgres/drizzle && cp -r ./source/lock/postgres/drizzle ./dist/lock/postgres/"
|
|
35
40
|
},
|
|
36
41
|
"exports": {
|
|
37
42
|
"./tsconfig.json": "./tsconfig.json",
|
|
@@ -40,7 +45,6 @@
|
|
|
40
45
|
"./environment": "./environment.js",
|
|
41
46
|
"./interfaces": "./interfaces.js",
|
|
42
47
|
"./polyfills": "./polyfills.js",
|
|
43
|
-
"./process-shutdown": "./process-shutdown.js",
|
|
44
48
|
"./supports": "./supports.js",
|
|
45
49
|
"./tokens": "./tokens.js",
|
|
46
50
|
"./ai": "./ai/index.js",
|
|
@@ -55,8 +59,6 @@
|
|
|
55
59
|
"./cookie": "./cookie/index.js",
|
|
56
60
|
"./css": "./css/index.js",
|
|
57
61
|
"./data-structures": "./data-structures/index.js",
|
|
58
|
-
"./database": "./database/index.js",
|
|
59
|
-
"./database/mongo": "./database/mongo/index.js",
|
|
60
62
|
"./decorators": "./decorators/index.js",
|
|
61
63
|
"./disposable": "./disposable/index.js",
|
|
62
64
|
"./distributed-loop": "./distributed-loop/index.js",
|
|
@@ -79,10 +81,9 @@
|
|
|
79
81
|
"./json-path": "./json-path/index.js",
|
|
80
82
|
"./jsx": "./jsx/index.js",
|
|
81
83
|
"./key-value-store": "./key-value-store/index.js",
|
|
82
|
-
"./key-value-store/mongo": "./key-value-store/mongo/index.js",
|
|
83
84
|
"./key-value-store/postgres": "./key-value-store/postgres/index.js",
|
|
84
85
|
"./lock": "./lock/index.js",
|
|
85
|
-
"./lock/
|
|
86
|
+
"./lock/postgres": "./lock/postgres/index.js",
|
|
86
87
|
"./lock/web": "./lock/web/index.js",
|
|
87
88
|
"./logger": "./logger/index.js",
|
|
88
89
|
"./mail": "./mail/index.js",
|
|
@@ -100,7 +101,6 @@
|
|
|
100
101
|
"./process": "./process/index.js",
|
|
101
102
|
"./promise": "./promise/index.js",
|
|
102
103
|
"./queue": "./queue/index.js",
|
|
103
|
-
"./queue/mongo": "./queue/mongo/index.js",
|
|
104
104
|
"./queue/postgres": "./queue/postgres/index.js",
|
|
105
105
|
"./random": "./random/index.js",
|
|
106
106
|
"./reflection": "./reflection/index.js",
|
|
@@ -109,9 +109,6 @@
|
|
|
109
109
|
"./rxjs-utils": "./rxjs-utils/index.js",
|
|
110
110
|
"./schema": "./schema/index.js",
|
|
111
111
|
"./schema/converters": "./schema/converters/index.js",
|
|
112
|
-
"./search-index": "./search-index/index.js",
|
|
113
|
-
"./search-index/elastic": "./search-index/elastic/index.js",
|
|
114
|
-
"./search-index/memory": "./search-index/memory/index.js",
|
|
115
112
|
"./serializer": "./serializer/index.js",
|
|
116
113
|
"./serializer/handlers": "./serializer/handlers/index.js",
|
|
117
114
|
"./signals": "./signals/index.js",
|
|
@@ -123,8 +120,6 @@
|
|
|
123
120
|
"./templates/resolvers": "./templates/resolvers/index.js",
|
|
124
121
|
"./templates/types": "./templates/types/index.js",
|
|
125
122
|
"./text": "./text/index.js",
|
|
126
|
-
"./theme": "./theme/index.js",
|
|
127
|
-
"./theme/adapters": "./theme/adapters/index.js",
|
|
128
123
|
"./threading": "./threading/index.js",
|
|
129
124
|
"./types": "./types/index.js",
|
|
130
125
|
"./utils": "./utils/index.js",
|
|
@@ -148,28 +143,25 @@
|
|
|
148
143
|
"type-fest": "4.37"
|
|
149
144
|
},
|
|
150
145
|
"peerDependencies": {
|
|
151
|
-
"@elastic/elasticsearch": "^9.1",
|
|
152
146
|
"@google-cloud/storage": "^7.17",
|
|
153
|
-
"@google/genai": "^1.
|
|
147
|
+
"@google/genai": "^1.19",
|
|
154
148
|
"@tstdl/angular": "^0.92",
|
|
155
149
|
"@zxcvbn-ts/core": "^3.0",
|
|
156
150
|
"@zxcvbn-ts/language-common": "^3.0",
|
|
157
151
|
"@zxcvbn-ts/language-de": "^3.0",
|
|
158
152
|
"@zxcvbn-ts/language-en": "^3.0",
|
|
159
|
-
"chroma-js": "^2.6",
|
|
160
153
|
"drizzle-orm": "^0.44",
|
|
161
154
|
"file-type": "^21.0",
|
|
162
155
|
"handlebars": "^4.7",
|
|
163
156
|
"minio": "^8.0",
|
|
164
157
|
"mjml": "^4.15",
|
|
165
|
-
"mongodb": "^6.18",
|
|
166
158
|
"nodemailer": "^7.0",
|
|
167
159
|
"pg": "^8.16",
|
|
168
160
|
"playwright": "^1.55",
|
|
169
161
|
"preact": "^10.27",
|
|
170
162
|
"preact-render-to-string": "^6.6",
|
|
171
163
|
"sharp": "^0.34",
|
|
172
|
-
"undici": "^7.
|
|
164
|
+
"undici": "^7.16",
|
|
173
165
|
"urlpattern-polyfill": "^10.1"
|
|
174
166
|
},
|
|
175
167
|
"peerDependenciesMeta": {
|
|
@@ -178,8 +170,7 @@
|
|
|
178
170
|
}
|
|
179
171
|
},
|
|
180
172
|
"devDependencies": {
|
|
181
|
-
"@stylistic/eslint-plugin": "5.
|
|
182
|
-
"@types/chroma-js": "2.4",
|
|
173
|
+
"@stylistic/eslint-plugin": "5.3",
|
|
183
174
|
"@types/koa__router": "12.0",
|
|
184
175
|
"@types/luxon": "3.7",
|
|
185
176
|
"@types/minio": "7.1",
|
|
@@ -189,15 +180,14 @@
|
|
|
189
180
|
"@types/pg": "8.15",
|
|
190
181
|
"concurrently": "9.2",
|
|
191
182
|
"drizzle-kit": "0.31",
|
|
192
|
-
"eslint": "9.
|
|
193
|
-
"globals": "16.
|
|
194
|
-
"repomix": "1.3",
|
|
183
|
+
"eslint": "9.35",
|
|
184
|
+
"globals": "16.4",
|
|
195
185
|
"tsc-alias": "1.8",
|
|
196
186
|
"typedoc-github-wiki-theme": "2.1",
|
|
197
187
|
"typedoc-plugin-markdown": "4.8",
|
|
198
188
|
"typedoc-plugin-missing-exports": "4.1",
|
|
199
189
|
"typescript": "5.9",
|
|
200
|
-
"typescript-eslint": "8.
|
|
190
|
+
"typescript-eslint": "8.43"
|
|
201
191
|
},
|
|
202
192
|
"overrides": {
|
|
203
193
|
"drizzle-kit": {
|
package/pdf/pdf.service.js
CHANGED
|
@@ -24,7 +24,7 @@ import { finalizeStream } from '../utils/stream/finalize-stream.js';
|
|
|
24
24
|
import { readableStreamFromPromise } from '../utils/stream/from-promise.js';
|
|
25
25
|
import { readBinaryStream } from '../utils/stream/stream-reader.js';
|
|
26
26
|
import { timeout } from '../utils/timing.js';
|
|
27
|
-
import { isDefined } from '../utils/type-guards.js';
|
|
27
|
+
import { isDefined, isNumber } from '../utils/type-guards.js';
|
|
28
28
|
export class PdfServiceRenderOptions extends PdfRenderOptions {
|
|
29
29
|
browserContext;
|
|
30
30
|
locale;
|
|
@@ -81,7 +81,7 @@ let PdfService = class PdfService {
|
|
|
81
81
|
* @returns pdf stream
|
|
82
82
|
*/
|
|
83
83
|
renderHtmlStream(html, options) {
|
|
84
|
-
return this.renderStream(async (page) => page.setContent(html), options);
|
|
84
|
+
return this.renderStream(async (page) => await page.setContent(html), options);
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* Renders HTML to pdf
|
|
@@ -91,7 +91,7 @@ let PdfService = class PdfService {
|
|
|
91
91
|
*/
|
|
92
92
|
async renderHtml(html, options) {
|
|
93
93
|
const stream = this.renderHtmlStream(html, options);
|
|
94
|
-
return readBinaryStream(stream);
|
|
94
|
+
return await readBinaryStream(stream);
|
|
95
95
|
}
|
|
96
96
|
/**
|
|
97
97
|
* Renders an url to pdf stream
|
|
@@ -112,7 +112,7 @@ let PdfService = class PdfService {
|
|
|
112
112
|
*/
|
|
113
113
|
async renderUrl(url, options) {
|
|
114
114
|
const stream = this.renderUrlStream(url, options);
|
|
115
|
-
return readBinaryStream(stream);
|
|
115
|
+
return await readBinaryStream(stream);
|
|
116
116
|
}
|
|
117
117
|
/**
|
|
118
118
|
* Renders a template to pdf
|
|
@@ -137,15 +137,15 @@ let PdfService = class PdfService {
|
|
|
137
137
|
*/
|
|
138
138
|
async renderTemplate(keyOrTemplate, templateContext, options) {
|
|
139
139
|
const stream = this.renderTemplateStream(keyOrTemplate, templateContext, options);
|
|
140
|
-
return readBinaryStream(stream);
|
|
140
|
+
return await readBinaryStream(stream);
|
|
141
141
|
}
|
|
142
142
|
renderStream(handler, options = {}) {
|
|
143
143
|
return readableStreamFromPromise(async () => {
|
|
144
144
|
const context = options.browserContext ?? await this.browserController.newContext({ locale: options.locale ?? this.defaultLocale });
|
|
145
145
|
const page = await context.newPage();
|
|
146
146
|
if (isDefined(options.log) && (options.log != false)) {
|
|
147
|
-
const level = (options.log
|
|
148
|
-
const logger = this.logger.fork({ level
|
|
147
|
+
const level = isNumber(options.log) ? options.log : LogLevel.Trace;
|
|
148
|
+
const logger = this.logger.fork('PAGE', { level });
|
|
149
149
|
page.attachLogger(logger);
|
|
150
150
|
}
|
|
151
151
|
const optionsFromHandler = await handler(page);
|
|
@@ -165,7 +165,7 @@ let PdfService = class PdfService {
|
|
|
165
165
|
return finalizeStream(pdfStream, {
|
|
166
166
|
beforeDone: close,
|
|
167
167
|
beforeCancel: close,
|
|
168
|
-
error: close
|
|
168
|
+
error: close,
|
|
169
169
|
});
|
|
170
170
|
});
|
|
171
171
|
}
|
|
@@ -178,6 +178,6 @@ export function pdfTemplate(name, fields, options) {
|
|
|
178
178
|
return {
|
|
179
179
|
name,
|
|
180
180
|
fields,
|
|
181
|
-
options
|
|
181
|
+
options,
|
|
182
182
|
};
|
|
183
183
|
}
|
package/pool/pool.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { AsyncDisposable } from '../disposable/disposable.js';
|
|
2
|
-
import { disposeAsync } from '../disposable/disposable.js';
|
|
3
1
|
import type { Logger } from '../logger/index.js';
|
|
4
2
|
export type PoolOptions = {
|
|
5
3
|
/**
|
|
@@ -45,5 +43,5 @@ export declare class Pool<T extends object> implements AsyncDisposable {
|
|
|
45
43
|
use<R>(handler: (instance: T) => R | Promise<R>, options?: PoolUseOptions): Promise<R>;
|
|
46
44
|
disposeInstance(instance: T): Promise<void>;
|
|
47
45
|
dispose(): Promise<void>;
|
|
48
|
-
[
|
|
46
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
49
47
|
}
|
package/pool/pool.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ArrayList } from '../data-structures/array-list.js';
|
|
2
2
|
import { SetCollection } from '../data-structures/set-collection.js';
|
|
3
|
-
import { disposeAsync } from '../disposable/disposable.js';
|
|
4
3
|
import { hardwareConcurrency } from '../environment.js';
|
|
5
4
|
import { isDefined } from '../utils/type-guards.js';
|
|
6
5
|
export class Pool {
|
|
@@ -57,7 +56,7 @@ export class Pool {
|
|
|
57
56
|
while (!this.freeInstances.hasItems) {
|
|
58
57
|
await this.freeInstances.$onItems;
|
|
59
58
|
}
|
|
60
|
-
return this.get();
|
|
59
|
+
return await this.get();
|
|
61
60
|
}
|
|
62
61
|
async release(instance) {
|
|
63
62
|
if (this.freeInstances.includes(instance)) {
|
|
@@ -110,9 +109,9 @@ export class Pool {
|
|
|
110
109
|
await this.disposer(instance);
|
|
111
110
|
}
|
|
112
111
|
async dispose() {
|
|
113
|
-
|
|
112
|
+
await this[Symbol.asyncDispose]();
|
|
114
113
|
}
|
|
115
|
-
async [
|
|
114
|
+
async [Symbol.asyncDispose]() {
|
|
116
115
|
this.disposed = true;
|
|
117
116
|
if (this.length == 0) {
|
|
118
117
|
return;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { EntityWithoutMetadata } from '../../orm/
|
|
2
|
-
import { Integer, Json, Timestamp } from '../../orm/index.js';
|
|
1
|
+
import { EntityWithoutMetadata, Integer, Json, Timestamp } from '../../orm/index.js';
|
|
3
2
|
import type { ObjectLiteral } from '../../types/index.js';
|
|
4
3
|
import type { Job } from '../queue.js';
|
|
5
4
|
export declare class PostgresJob<T extends ObjectLiteral = ObjectLiteral> extends EntityWithoutMetadata implements Job<T> {
|
|
@@ -8,8 +8,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
10
|
import { Index, Table } from '../../orm/decorators.js';
|
|
11
|
-
import { EntityWithoutMetadata } from '../../orm/
|
|
12
|
-
import { Integer, Json, Timestamp } from '../../orm/index.js';
|
|
11
|
+
import { EntityWithoutMetadata, Integer, Json, Timestamp } from '../../orm/index.js';
|
|
13
12
|
import { StringProperty } from '../../schema/index.js';
|
|
14
13
|
let PostgresJob = class PostgresJob extends EntityWithoutMetadata {
|
|
15
14
|
queue;
|
package/queue/postgres/module.js
CHANGED
|
@@ -24,6 +24,6 @@ export async function migratePostgresQueueSchema() {
|
|
|
24
24
|
await migrate(database, {
|
|
25
25
|
migrationsSchema: 'queue',
|
|
26
26
|
migrationsTable: '_migrations',
|
|
27
|
-
migrationsFolder: import.meta.resolve('./drizzle').replace('file://', '')
|
|
27
|
+
migrationsFolder: import.meta.resolve('./drizzle').replace('file://', ''),
|
|
28
28
|
});
|
|
29
29
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type * as NodeWorkerThreads from 'node:worker_threads';
|
|
2
2
|
import type { LiteralUnion } from 'type-fest';
|
|
3
|
-
import type { AsyncDisposable } from '../disposable/index.js';
|
|
4
|
-
import { disposeAsync } from '../disposable/index.js';
|
|
5
3
|
import type { Logger } from '../logger/index.js';
|
|
6
4
|
import type { ThreadWorker } from './thread-worker.js';
|
|
7
5
|
export type ThreadOptions = (WorkerOptions | NodeWorkerThreads.WorkerOptions) & {
|
|
@@ -13,7 +11,7 @@ export declare class ThreadPool implements AsyncDisposable {
|
|
|
13
11
|
readonly options: ThreadOptions | undefined;
|
|
14
12
|
constructor(url: string | URL, logger: Logger, options?: ThreadOptions);
|
|
15
13
|
dispose(): Promise<void>;
|
|
16
|
-
[
|
|
14
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
17
15
|
getProcessor<T extends ThreadWorker>(name?: string): (...args: Parameters<T>) => Promise<ReturnType<T>>;
|
|
18
16
|
process<T extends ThreadWorker>(name: LiteralUnion<'default', string>, ...args: Parameters<T>): Promise<ReturnType<T>>;
|
|
19
17
|
private spawn;
|
package/threading/thread-pool.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { disposeAsync } from '../disposable/index.js';
|
|
2
1
|
import { isNode } from '../environment.js';
|
|
3
2
|
import { dynamicImport } from '../import.js';
|
|
4
3
|
import { Pool } from '../pool/index.js';
|
|
@@ -9,7 +8,7 @@ if (isNode) {
|
|
|
9
8
|
spawnWorker = async (url, options) => {
|
|
10
9
|
const workerThreads = await dynamicImport('node:worker_threads');
|
|
11
10
|
spawnWorker = () => new workerThreads.Worker(url, options);
|
|
12
|
-
return spawnWorker(url, options);
|
|
11
|
+
return await spawnWorker(url, options);
|
|
13
12
|
};
|
|
14
13
|
}
|
|
15
14
|
else {
|
|
@@ -22,26 +21,26 @@ export class ThreadPool {
|
|
|
22
21
|
constructor(url, logger, options) {
|
|
23
22
|
this.url = url;
|
|
24
23
|
this.options = options;
|
|
25
|
-
this.pool = new Pool(async () => this.spawn(), async ({ worker }) => worker.terminate(), logger, { size: options?.threadCount });
|
|
24
|
+
this.pool = new Pool(async () => await this.spawn(), async ({ worker }) => await worker.terminate(), logger, { size: options?.threadCount });
|
|
26
25
|
}
|
|
27
26
|
async dispose() {
|
|
28
|
-
|
|
27
|
+
await this[Symbol.asyncDispose]();
|
|
29
28
|
}
|
|
30
|
-
async [
|
|
29
|
+
async [Symbol.asyncDispose]() {
|
|
31
30
|
await this.pool.dispose();
|
|
32
31
|
}
|
|
33
32
|
getProcessor(name = 'default') {
|
|
34
|
-
const processor = async (...args) => this.process(name, ...args);
|
|
33
|
+
const processor = async (...args) => await this.process(name, ...args);
|
|
35
34
|
return processor;
|
|
36
35
|
}
|
|
37
36
|
async process(name, ...args) {
|
|
38
|
-
return this.pool.use(async (entry) => {
|
|
37
|
+
return await this.pool.use(async (entry) => {
|
|
39
38
|
if (!entry.remotes.has(name)) {
|
|
40
39
|
const rpcEndpoint = MessagePortRpcEndpoint.from(entry.worker);
|
|
41
40
|
const remote = await Rpc.connect(rpcEndpoint, `thread-worker:${name}`);
|
|
42
41
|
entry.remotes.set(name, remote);
|
|
43
42
|
}
|
|
44
|
-
return entry.remotes.get(name)(...args);
|
|
43
|
+
return await entry.remotes.get(name)(...args);
|
|
45
44
|
});
|
|
46
45
|
}
|
|
47
46
|
async spawn() {
|
package/utils/format-error.d.ts
CHANGED
|
@@ -16,9 +16,16 @@ export type FormatErrorOptions = {
|
|
|
16
16
|
* Include stack trace
|
|
17
17
|
*/
|
|
18
18
|
includeStack?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Maximum recursion depth for nested causes and aggregate errors (default: 5)
|
|
21
|
+
*/
|
|
22
|
+
depth?: number;
|
|
19
23
|
};
|
|
20
24
|
export interface ErrorExtraInfo {
|
|
21
25
|
/** Format extra data (without message and stack) as JSON */
|
|
22
26
|
getExtraInfo(): UndefinableJson | undefined;
|
|
23
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Enhanced error formatting
|
|
30
|
+
*/
|
|
24
31
|
export declare function formatError(error: any, options?: FormatErrorOptions): string;
|
package/utils/format-error.js
CHANGED
|
@@ -1,35 +1,77 @@
|
|
|
1
1
|
import { unwrapError } from '../errors/utils.js';
|
|
2
2
|
import { decycle } from './object/decycle.js';
|
|
3
3
|
import { objectKeys } from './object/object.js';
|
|
4
|
-
import {
|
|
4
|
+
import { tryChain } from './try-chain.js';
|
|
5
|
+
import { isDefined, isFunction, isObject, isUndefined } from './type-guards.js';
|
|
6
|
+
/**
|
|
7
|
+
* Enhanced error formatting
|
|
8
|
+
*/
|
|
5
9
|
export function formatError(error, options = {}) {
|
|
6
|
-
const { includeRest = 'if-no-extra-info', includeExtraInfo = true, includeStack = true } = options;
|
|
10
|
+
const { includeName = true, includeRest = 'if-no-extra-info', includeExtraInfo = true, includeStack = true, depth = 5, } = options;
|
|
11
|
+
if (depth <= 0) {
|
|
12
|
+
return '[Max recursion depth reached]';
|
|
13
|
+
}
|
|
14
|
+
const actualError = unwrapError(error);
|
|
7
15
|
let name;
|
|
8
16
|
let message;
|
|
9
17
|
let stack;
|
|
10
18
|
let rest;
|
|
11
19
|
let extraInfo;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
let cause;
|
|
21
|
+
let aggregateErrors;
|
|
22
|
+
if (isObject(actualError)) {
|
|
23
|
+
if (actualError instanceof Error) {
|
|
24
|
+
({ name, message, stack, cause, ...rest } = actualError);
|
|
25
|
+
if (actualError instanceof AggregateError) {
|
|
26
|
+
aggregateErrors = actualError.errors;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// Handle plain objects that might have error-like properties
|
|
31
|
+
({ name, message, stack, cause, ...rest } = actualError);
|
|
32
|
+
}
|
|
33
|
+
// Check for extra info (duck-typing)
|
|
34
|
+
if (includeExtraInfo && isFunction(actualError.getExtraInfo)) { // eslint-disable-line @typescript-eslint/unbound-method
|
|
17
35
|
extraInfo = actualError.getExtraInfo();
|
|
18
36
|
}
|
|
19
37
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
38
|
+
// If no message, serialize the whole object as a fallback
|
|
39
|
+
if (isUndefined(message) || String(message).trim().length === 0) { // eslint-disable-line @typescript-eslint/no-unnecessary-type-conversion
|
|
40
|
+
// Handle primitives directly
|
|
41
|
+
if (!isObject(actualError)) {
|
|
42
|
+
message = String(actualError);
|
|
24
43
|
}
|
|
25
|
-
|
|
26
|
-
|
|
44
|
+
else {
|
|
45
|
+
message = tryChain([
|
|
46
|
+
() => JSON.stringify(actualError, null, 2), // Try normal serialization first
|
|
47
|
+
() => {
|
|
48
|
+
// Fallback with decycle for objects with circular references
|
|
49
|
+
const decycledError = decycle(actualError);
|
|
50
|
+
return JSON.stringify(decycledError, null, 2);
|
|
51
|
+
},
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
53
|
+
() => `[Unstringifiable object: ${String(actualError)}]`, // Safe fallback if JSON.stringify still fails
|
|
54
|
+
]);
|
|
27
55
|
}
|
|
28
56
|
}
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
57
|
+
// --- String Assembly ---
|
|
58
|
+
const nameString = includeName ? `${name ?? 'Error'}: ` : '';
|
|
59
|
+
let restString = '';
|
|
60
|
+
const shouldIncludeRest = (includeRest == true) || (includeRest == 'if-no-extra-info' && isUndefined(extraInfo));
|
|
61
|
+
if (shouldIncludeRest && isDefined(rest) && objectKeys(rest).length > 0) {
|
|
62
|
+
restString = `\n${JSON.stringify(decycle(rest), null, 2)}`;
|
|
63
|
+
}
|
|
32
64
|
const extraInfoString = isDefined(extraInfo) ? `\n${JSON.stringify(extraInfo, null, 2)}` : '';
|
|
33
65
|
const stackString = (includeStack && isDefined(stack)) ? `\n${stack}` : '';
|
|
34
|
-
|
|
66
|
+
const causeString = includeStack && cause
|
|
67
|
+
? formatNestedError('Caused by:', cause, { ...options, depth: depth - 1 })
|
|
68
|
+
: '';
|
|
69
|
+
const aggregateErrorsString = Array.isArray(aggregateErrors)
|
|
70
|
+
? aggregateErrors.map((err, i) => formatNestedError(`Sub-error #${i + 1}:`, err, { ...options, depth: depth - 1 })).join('')
|
|
71
|
+
: '';
|
|
72
|
+
return `${nameString}${message}${restString}${extraInfoString}${stackString}${causeString}${aggregateErrorsString}`;
|
|
73
|
+
}
|
|
74
|
+
function formatNestedError(prefix, error, options) {
|
|
75
|
+
const formatted = formatError(error, options).replace(/\n/g, '\n ');
|
|
76
|
+
return `\n\n${prefix}\n ${formatted}`;
|
|
35
77
|
}
|
|
@@ -17,20 +17,35 @@ export declare function memoizeSingle<Fn extends (parameter: any) => any>(fn: Fn
|
|
|
17
17
|
export declare function memoizeClass<T extends Constructor>(type: T, options?: MemoizeOptions): (...parameters: ConstructorParameters<T>) => InstanceType<T>;
|
|
18
18
|
export declare function memoizeClassSingle<T extends Constructor<any, [any]>>(type: T, options?: MemoizeOptions): (...parameters: ConstructorParameters<T>) => InstanceType<T>;
|
|
19
19
|
/**
|
|
20
|
-
* Memoizes
|
|
20
|
+
* Memoizes the result of a class getter, ensuring the getter's logic is
|
|
21
|
+
* executed only once per instance.
|
|
22
|
+
*
|
|
23
|
+
* Subsequent accesses to the getter will return the cached value.
|
|
24
|
+
*
|
|
25
|
+
* @param strategy The memoization strategy to use.
|
|
26
|
+
* - `attach`: (Default) Uses `Symbol` properties to store the cached value directly on the class instance. This is generally faster but adds hidden properties to the instance.
|
|
27
|
+
* - `weak-map`: Uses a `WeakMap` to store the cached value, with the class instance as the key. This avoids adding any properties to the instance, keeping it "clean".
|
|
21
28
|
*
|
|
22
29
|
* @example
|
|
23
30
|
* ```typescript
|
|
24
|
-
* class
|
|
31
|
+
* class MyEvaluator {
|
|
25
32
|
* @Memoize()
|
|
26
|
-
* get
|
|
27
|
-
* // expensive
|
|
28
|
-
* return
|
|
33
|
+
* get result() {
|
|
34
|
+
* // This expensive result creation only happens once per instance.
|
|
35
|
+
* return this.computeExpensiveResult();
|
|
29
36
|
* }
|
|
30
37
|
* }
|
|
38
|
+
*
|
|
39
|
+
* const service = new MyEvaluator();
|
|
40
|
+
* const s1 = service.result; // Logs "Creating new result..."
|
|
41
|
+
* const s2 = service.result; // Does not log anything, returns cached result.
|
|
42
|
+
* console.log(s1 === s2); // true
|
|
31
43
|
* ```
|
|
32
44
|
*
|
|
33
45
|
* @remarks
|
|
34
|
-
*
|
|
46
|
+
* If the decorated property has a corresponding setter, calling the setter will
|
|
47
|
+
* invalidate the cache. The getter will be re-evaluated on its next access.
|
|
48
|
+
*
|
|
49
|
+
* @returns An accessor decorator function.
|
|
35
50
|
*/
|
|
36
|
-
export declare function Memoize(): MethodDecorator;
|
|
51
|
+
export declare function Memoize(strategy?: 'attach' | 'weak-map'): MethodDecorator;
|