@tstdl/base 0.93.93 → 0.93.95

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/api/response.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { SecretRequirementsError } from '../authentication/errors/secret-requirements.error.js';
2
2
  import { SchemaError } from '../schema/schema.error.js';
3
- import { formatError } from '../utils/format-error.js';
3
+ import { formatError } from '../errors/index.js';
4
4
  import { ApiError, BadRequestError, ForbiddenError, InvalidCredentialsError, InvalidTokenError, MaxBytesExceededError, MethodNotAllowedError, NotFoundError, NotImplementedError, NotSupportedError, UnauthorizedError, UnsupportedMediaTypeError } from '../errors/index.js';
5
5
  import { assertString, isDefined, isFunction, isObject, isString } from '../utils/type-guards.js';
6
6
  import { deserializeSchemaError, serializeSchemaError } from './default-error-handlers.js';
@@ -21,7 +21,7 @@ import { Logger } from '../../logger/index.js';
21
21
  import { MessageBus } from '../../message-bus/index.js';
22
22
  import { computed, signal, toObservable } from '../../signals/api.js';
23
23
  import { currentTimestampSeconds } from '../../utils/date-time.js';
24
- import { formatError } from '../../utils/format-error.js';
24
+ import { formatError } from '../../errors/index.js';
25
25
  import { timeout } from '../../utils/timing.js';
26
26
  import { assertDefinedPass, isDefined, isNotFunction, isNullOrUndefined, isUndefined } from '../../utils/type-guards.js';
27
27
  import { millisecondsPerMinute, millisecondsPerSecond } from '../../utils/units.js';
@@ -1,8 +1,7 @@
1
- import { unwrapError } from '../errors/utils.js';
2
- import { decycle } from './object/decycle.js';
3
- import { objectKeys } from './object/object.js';
4
- import { tryChain } from './try-chain.js';
5
- import { isArray, isDefined, isFunction, isObject, isString, isUndefined } from './type-guards.js';
1
+ import { decycle, objectKeys } from '../utils/object/index.js';
2
+ import { tryChain } from '../utils/try-chain.js';
3
+ import { isArray, isDefined, isFunction, isObject, isString, isUndefined } from '../utils/type-guards.js';
4
+ import { unwrapError } from './utils.js';
6
5
  export function serializeError(error, options = {}) {
7
6
  const { includeName = true, includeRest = 'if-no-extra-info', includeExtraInfo = true, includeStack = true, depth = 5, } = options;
8
7
  if (depth <= 0) {
@@ -97,39 +96,46 @@ function formatSerializedError(serialized, options) {
97
96
  const { includeName = true, includeStack = true, depth = 5 } = options;
98
97
  // 1. Header (Name: Message)
99
98
  const prefix = includeName && name ? `${name}: ` : '';
100
- const header = `${prefix}${message}`;
99
+ const messageString = String(message);
100
+ const header = `${prefix}${messageString}`;
101
+ const alignedHeader = (prefix.length > 0 && messageString.includes('\n'))
102
+ ? `${prefix}${messageString.replace(/\n/g, `\n${' '.repeat(prefix.length)}`)}`
103
+ : header;
104
+ let formatted = alignedHeader;
101
105
  // 2. Body (Rest / Extra Info)
102
- let body = '';
103
- if (rest) {
104
- body += `\n${JSON.stringify(rest, null, 2)}`;
106
+ if (isDefined(rest)) {
107
+ formatted += `\n${indent(JSON.stringify(rest, null, 2), 4)}`;
105
108
  }
106
- if (extraInfo) {
107
- body += `\n${JSON.stringify(extraInfo, null, 2)}`;
109
+ if (isDefined(extraInfo)) {
110
+ formatted += `\n${indent(JSON.stringify(extraInfo, null, 2), 4)}`;
108
111
  }
109
112
  // 3. Stack Trace
110
- let stackString = '';
111
- if (includeStack && stack) {
113
+ if (includeStack && isDefined(stack)) {
112
114
  // Deduplicate header if stack already starts with it (standard Node.js behavior)
113
115
  if (stack.startsWith(header)) {
114
- stackString = stack.slice(header.length);
116
+ formatted += stack.slice(header.length);
115
117
  }
116
118
  else {
117
- stackString = `\n${stack}`;
119
+ formatted += `\n${stack}`;
118
120
  }
119
121
  }
120
122
  // 4. Recursion (Causes and Aggregate Errors)
121
123
  const nextOptions = { ...options, depth: depth - 1 };
122
- const causeString = (includeStack && cause)
123
- ? formatNestedError('Caused by:', cause, nextOptions)
124
- : '';
125
- const aggregateErrorsString = aggregateErrors
126
- ? aggregateErrors
127
- .map((err, i) => formatNestedError(`Sub-error #${i + 1}:`, err, nextOptions))
128
- .join('')
129
- : '';
130
- return `${header}${body}${stackString}${causeString}${aggregateErrorsString}`;
124
+ if (includeStack && isDefined(cause)) {
125
+ formatted += formatNestedError('Caused by:', cause, nextOptions);
126
+ }
127
+ if (isArray(aggregateErrors)) {
128
+ for (const [index, err] of aggregateErrors.entries()) {
129
+ formatted += formatNestedError(`Sub-error #${index + 1}:`, err, nextOptions);
130
+ }
131
+ }
132
+ return formatted;
131
133
  }
132
134
  function formatNestedError(prefix, serializedError, options) {
133
- const formatted = formatSerializedError(serializedError, options).replace(/\n/g, '\n ');
134
- return `\n\n${prefix}\n ${formatted}`;
135
+ const formatted = formatSerializedError(serializedError, options);
136
+ return `\n${prefix}\n${indent(formatted, 2)}`;
137
+ }
138
+ function indent(text, spaces) {
139
+ const indentation = ' '.repeat(spaces);
140
+ return text.split('\n').map((line) => (line.length > 0 ? `${indentation}${line}` : line)).join('\n');
135
141
  }
package/errors/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export * from './custom.error.js';
10
10
  export * from './details.error.js';
11
11
  export * from './errors.localization.js';
12
12
  export * from './forbidden.error.js';
13
+ export * from './format.js';
13
14
  export * from './invalid-credentials.error.js';
14
15
  export * from './invalid-token.error.js';
15
16
  export * from './max-bytes-exceeded.error.js';
package/errors/index.js CHANGED
@@ -10,6 +10,7 @@ export * from './custom.error.js';
10
10
  export * from './details.error.js';
11
11
  export * from './errors.localization.js';
12
12
  export * from './forbidden.error.js';
13
+ export * from './format.js';
13
14
  export * from './invalid-credentials.error.js';
14
15
  export * from './invalid-token.error.js';
15
16
  export * from './max-bytes-exceeded.error.js';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,84 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { formatError } from '../format.js';
3
+ describe('formatError', () => {
4
+ it('should format a simple error', () => {
5
+ const error = new Error('test message');
6
+ const formatted = formatError(error, { includeStack: false });
7
+ expect(formatted).toBe('Error: test message');
8
+ });
9
+ it('should align multi-line messages', () => {
10
+ const error = new Error('line 1\nline 2');
11
+ const formatted = formatError(error, { includeStack: false });
12
+ expect(formatted).toBe('Error: line 1\n line 2');
13
+ });
14
+ it('should format nested errors with causes', () => {
15
+ const cause = new Error('cause message');
16
+ const error = new Error('top message', { cause });
17
+ const formatted = formatError(error, { includeStack: true });
18
+ expect(formatted).toContain('Error: top message');
19
+ expect(formatted).toContain('Caused by:');
20
+ expect(formatted).toContain('Error: cause message');
21
+ });
22
+ it('should deduplicate stack header', () => {
23
+ const error = new Error('test message');
24
+ const formatted = formatError(error, { includeStack: true });
25
+ const lines = formatted.split('\n');
26
+ expect(lines[0]).toBe('Error: test message');
27
+ expect(lines[1].trim()).toMatch(/^at /);
28
+ });
29
+ it('should handle multi-line message alignment with stack deduplication', () => {
30
+ const error = new Error('multi\nline');
31
+ const formatted = formatError(error, { includeStack: true });
32
+ expect(formatted).toContain('Error: multi\n line');
33
+ const lines = formatted.split('\n');
34
+ expect(lines[0]).toBe('Error: multi');
35
+ expect(lines[1]).toBe(' line');
36
+ expect(lines[2].trim()).toMatch(/^at /);
37
+ });
38
+ it('should format rest properties', () => {
39
+ const error = new Error('message');
40
+ error.code = 'ERR_CODE';
41
+ error.details = { foo: 'bar' };
42
+ const formatted = formatError(error, { includeStack: false, includeRest: true });
43
+ expect(formatted).toContain('Error: message');
44
+ expect(formatted).toContain('"code": "ERR_CODE"');
45
+ expect(formatted).toContain('"foo": "bar"');
46
+ });
47
+ it('should format AggregateError', () => {
48
+ const error1 = new Error('sub error 1');
49
+ const error2 = new Error('sub error 2');
50
+ const aggregateError = new AggregateError([error1, error2], 'aggregate message');
51
+ const formatted = formatError(aggregateError, { includeStack: false });
52
+ expect(formatted).toContain('AggregateError: aggregate message');
53
+ expect(formatted).toContain('Sub-error #1:');
54
+ expect(formatted).toContain('Error: sub error 1');
55
+ expect(formatted).toContain('Sub-error #2:');
56
+ expect(formatted).toContain('Error: sub error 2');
57
+ });
58
+ it('should handle deep cause chains', () => {
59
+ const cause2 = new Error('bottom');
60
+ const cause1 = new Error('middle', { cause: cause2 });
61
+ const error = new Error('top', { cause: cause1 });
62
+ const formatted = formatError(error, { includeStack: true });
63
+ expect(formatted).toContain('Error: top');
64
+ expect(formatted).toContain('Caused by:\n Error: middle');
65
+ expect(formatted).toContain('\n Caused by:\n Error: bottom');
66
+ });
67
+ it('should handle non-error objects', () => {
68
+ const obj = { foo: 'bar', baz: 123 };
69
+ const formatted = formatError(obj);
70
+ expect(formatted).toContain('"foo": "bar"');
71
+ expect(formatted).toContain('"baz": 123');
72
+ });
73
+ it('should handle errors with empty messages', () => {
74
+ const error = new Error('');
75
+ error.name = 'CustomError';
76
+ const formatted = formatError(error, { includeStack: false });
77
+ expect(formatted).toBe('CustomError: ');
78
+ });
79
+ it('should handle null or undefined', () => {
80
+ // Current behavior defaults name to 'Error' for non-raw-object fallback
81
+ expect(formatError(null)).toBe('Error: null');
82
+ expect(formatError(undefined)).toBe('Error: undefined');
83
+ });
84
+ });
@@ -1,6 +1,6 @@
1
1
  import { type EnumType } from '../enumeration/enumeration.js';
2
2
  import type { TypedOmit, UndefinableJson } from '../types/index.js';
3
- import type { ErrorExtraInfo } from '../utils/format-error.js';
3
+ import type { ErrorExtraInfo } from '../errors/index.js';
4
4
  import { CustomError } from '../errors/custom.error.js';
5
5
  import type { HttpClientRequest, HttpClientRequestObject, HttpClientResponse, HttpClientResponseObject } from './client/index.js';
6
6
  export declare const HttpErrorReason: {
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { Singleton } from '../../injector/decorators.js';
8
8
  import { enumValueName } from '../../utils/enum.js';
9
- import { formatError } from '../../utils/format-error.js';
9
+ import { formatError } from '../../errors/index.js';
10
10
  import { isNotNullOrUndefined } from '../../utils/type-guards.js';
11
11
  import { LogFormatter } from '../formatter.js';
12
12
  import { LogLevel } from '../level.js';
@@ -22,7 +22,7 @@ let JsonLogFormatter = class JsonLogFormatter extends LogFormatter {
22
22
  };
23
23
  // Special handling for error objects to make them serializable
24
24
  if (isNotNullOrUndefined(payload.error)) {
25
- logObject['error'] = formatError(payload.error, { includeStack: true });
25
+ logObject['error'] = formatError(payload.error);
26
26
  }
27
27
  return JSON.stringify(logObject);
28
28
  }
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { Singleton } from '../../injector/decorators.js';
8
8
  import { supportsColoredStdout } from '../../supports.js';
9
9
  import { enumValueName } from '../../utils/enum.js';
10
- import { formatError } from '../../utils/format-error.js';
10
+ import { formatError } from '../../errors/index.js';
11
11
  import { objectKeys } from '../../utils/object/object.js';
12
12
  import { isNotNullOrUndefined } from '../../utils/type-guards.js';
13
13
  import { LogFormatter } from '../formatter.js';
@@ -41,9 +41,21 @@ let PrettyPrintLogFormatter = class PrettyPrintLogFormatter extends LogFormatter
41
41
  if (objectKeys(displayMeta).length > 0) {
42
42
  metadataString = ` ${dimColor}${JSON.stringify(displayMeta)}${resetColor}`;
43
43
  }
44
- if (isNotNullOrUndefined(payload.error)) {
45
- errorString += `\n${formatError(payload.error, { includeStack: true })}`;
46
- }
44
+ }
45
+ if (isNotNullOrUndefined(payload.error)) {
46
+ const formattedError = formatError(payload.error);
47
+ errorString += `\n${formattedError
48
+ .split('\n')
49
+ .map((line) => {
50
+ if (line.trim().startsWith('at ')) {
51
+ return `${dimColor}${line}${resetColor}`;
52
+ }
53
+ if (line.startsWith('Caused by:') || line.startsWith('Sub-error #')) {
54
+ return `${color}${line}${resetColor}`;
55
+ }
56
+ return line;
57
+ })
58
+ .join('\n')}`;
47
59
  }
48
60
  return `${dimColor}${payload.timestamp.toISOString()}${resetColor} ${color}${levelString}${resetColor} ${moduleString}${moduleString.length > 0 ? ' ' : ''}${payload.message}${metadataString}${errorString}`;
49
61
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,60 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ // Mock supports before importing PrettyPrintLogFormatter
3
+ vi.mock('#/supports.js', () => ({
4
+ supportsColoredStdout: true,
5
+ supportsColoredStderr: true,
6
+ }));
7
+ import { LogLevel } from '../level.js';
8
+ import { PrettyPrintLogFormatter } from './pretty-print.js';
9
+ describe('PrettyPrintLogFormatter', () => {
10
+ const formatter = new PrettyPrintLogFormatter();
11
+ it('should format a log entry with an error and no context', () => {
12
+ const error = new Error('test error');
13
+ const payload = {
14
+ timestamp: new Date('2026-01-22T13:00:00.000Z'),
15
+ level: LogLevel.Error,
16
+ module: ['Test'],
17
+ message: 'something failed',
18
+ interpolationKeys: [],
19
+ context: {},
20
+ error,
21
+ };
22
+ const formatted = formatter.format(payload);
23
+ expect(formatted).toContain('ERROR:');
24
+ expect(formatted).toContain('[Test]');
25
+ expect(formatted).toContain('something failed');
26
+ expect(formatted).toContain('Error: test error');
27
+ expect(formatted).toContain('at '); // Should include stack trace
28
+ });
29
+ it('should dim stack trace lines', () => {
30
+ const error = new Error('test error');
31
+ const payload = {
32
+ timestamp: new Date('2026-01-22T13:00:00.000Z'),
33
+ level: LogLevel.Error,
34
+ module: ['Test'],
35
+ message: 'something failed',
36
+ interpolationKeys: [],
37
+ context: {},
38
+ error,
39
+ };
40
+ const formatted = formatter.format(payload);
41
+ // Check for dim color escape code \x1b[2m before "at " (including indentation)
42
+ expect(formatted).toContain('\x1b[2m at ');
43
+ });
44
+ it('should highlight "Caused by:" with level color', () => {
45
+ const cause = new Error('the cause');
46
+ const error = new Error('the error', { cause });
47
+ const payload = {
48
+ timestamp: new Date('2026-01-22T13:00:00.000Z'),
49
+ level: LogLevel.Error,
50
+ module: ['Test'],
51
+ message: 'failed',
52
+ interpolationKeys: [],
53
+ context: {},
54
+ error,
55
+ };
56
+ const formatted = formatter.format(payload);
57
+ // LogLevel.Error color is \x1b[31m
58
+ expect(formatted).toContain('\x1b[31mCaused by:');
59
+ });
60
+ });
@@ -9,7 +9,7 @@ import { Logger } from '../logger/index.js';
9
9
  import { DatabaseConfig, injectRepository } from '../orm/server/index.js';
10
10
  import { TemplateService } from '../templates/template.service.js';
11
11
  import { currentTimestamp } from '../utils/date-time.js';
12
- import { formatError } from '../utils/format-error.js';
12
+ import { formatError } from '../errors/index.js';
13
13
  import { assertDefined } from '../utils/type-guards.js';
14
14
  import { MailClient, MailClientConfig } from './mail.client.js';
15
15
  import { MailLog } from './models/index.js';
@@ -8,7 +8,7 @@ import type { LiteralUnion, SetRequired } from 'type-fest';
8
8
  import { type SpecificCreateDecoratorOptions } from '../reflection/index.js';
9
9
  import type { AbstractConstructor, Record, TypedOmit } from '../types/index.js';
10
10
  import type { ValueOrProvider } from '../utils/value-or-provider.js';
11
- import type { AnyEntity, BaseEntity, Entity, EntityType } from './entity.js';
11
+ import type { AnyEntity, BaseEntity, EntityType } from './entity.js';
12
12
  import type { Query } from './query/index.js';
13
13
  import type { TargetColumn, TargetColumnPath } from './repository.types.js';
14
14
  import type { ExtraConfigColumnsFromType } from './server/types.js';
@@ -46,7 +46,7 @@ export type OrmTableReflectionData<T extends BaseEntity = BaseEntity> = {
46
46
  index?: IndexReflectionData[];
47
47
  paradeIndex?: ParadeIndexReflectionData<T>;
48
48
  propertyOverrides?: Record<string, OrmColumnReflectionData>;
49
- checks?: CheckReflectionData[];
49
+ checks?: CheckReflectionData<T>[];
50
50
  foreignKeys?: ForeignKeyReflectionData[];
51
51
  inheritance?: InheritanceMetadata<T>;
52
52
  childEntity?: ChildEntityMetadata;
@@ -108,9 +108,9 @@ export type IndexReflectionData<T extends BaseEntity = any> = {
108
108
  order?: 'asc' | 'desc';
109
109
  options?: IndexOptions<T>;
110
110
  };
111
- type CheckReflectionData = {
111
+ export type CheckReflectionData<T extends BaseEntity = any> = {
112
112
  name: string;
113
- builder: CheckBuilder;
113
+ builder: CheckBuilder<T>;
114
114
  options?: {
115
115
  naming?: NamingStrategy;
116
116
  };
@@ -266,7 +266,7 @@ export declare function TenantReference<T extends AnyEntity>(target: () => Entit
266
266
  * @param name The name of the check constraint.
267
267
  * @param builder A function to build the SQL check expression.
268
268
  */
269
- export declare function Check<T extends Entity>(name: string, builder: CheckBuilder<T>): ClassDecorator;
269
+ export declare function Check<T extends BaseEntity>(name: string, builder: CheckBuilder<T>): ClassDecorator;
270
270
  /**
271
271
  * Mark a column for encryption.
272
272
  * The underlying database type will typically be `bytea`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.93.93",
3
+ "version": "0.93.95",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/rpc/rpc.error.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CustomError } from '../errors/custom.error.js';
2
- import { formatError } from '../utils/format-error.js';
2
+ import { formatError } from '../errors/index.js';
3
3
  import { isDefined, isObject } from '../utils/type-guards.js';
4
4
  export class RpcError extends CustomError {
5
5
  static errorName = 'RpcError';
@@ -1,7 +1,7 @@
1
1
  import { CustomError, type CustomErrorOptions } from '../errors/custom.error.js';
2
2
  import type { JsonPath } from '../json-path/index.js';
3
3
  import type { AbstractConstructor, OneOrMany, TypedOmit, UndefinableJson } from '../types/index.js';
4
- import type { ErrorExtraInfo } from '../utils/format-error.js';
4
+ import type { ErrorExtraInfo } from '../errors/index.js';
5
5
  export type SchemaErrorOptions = Pick<CustomErrorOptions, 'fast'> & {
6
6
  path: string | JsonPath;
7
7
  details?: UndefinableJson;
@@ -69,7 +69,7 @@ import { RateLimiter } from '../../rate-limit/index.js';
69
69
  import { createArray, distinct, toArray } from '../../utils/array/array.js';
70
70
  import { digest } from '../../utils/cryptography.js';
71
71
  import { currentTimestamp } from '../../utils/date-time.js';
72
- import { serializeError } from '../../utils/format-error.js';
72
+ import { serializeError } from '../../errors/index.js';
73
73
  import { cancelableTimeout } from '../../utils/timing.js';
74
74
  import { isDefined, isNotNull, isNull, isString, isUndefined } from '../../utils/type-guards.js';
75
75
  import { millisecondsPerSecond } from '../../utils/units.js';
@@ -8,6 +8,10 @@ export declare class TaskContext<Definitions extends TaskDefinitionMap, Type ext
8
8
  constructor(queue: TaskQueue<Definitions>, task: TaskOfType<Definitions, Type>, signal: CancellationToken, logger: Logger);
9
9
  get id(): string;
10
10
  get type(): Type;
11
+ get parentId(): string | null;
12
+ get tags(): string[];
13
+ get completeAfterTags(): string[];
14
+ get scheduleAfterTags(): string[];
11
15
  get data(): TaskData<Definitions, Type>;
12
16
  get state(): TaskState<Definitions, Type> | null;
13
17
  get attempt(): number;
@@ -18,6 +18,18 @@ export class TaskContext {
18
18
  get type() {
19
19
  return this.#task.type;
20
20
  }
21
+ get parentId() {
22
+ return this.#task.parentId;
23
+ }
24
+ get tags() {
25
+ return this.#task.tags;
26
+ }
27
+ get completeAfterTags() {
28
+ return this.#task.completeAfterTags;
29
+ }
30
+ get scheduleAfterTags() {
31
+ return this.#task.scheduleAfterTags;
32
+ }
21
33
  get data() {
22
34
  return this.#task.data;
23
35
  }
@@ -0,0 +1,22 @@
1
+ import type { ColumnBuilder } from './orm/types.js';
2
+ import type { Uuid, Timestamp, Json, IsPrimaryKey, HasDefault } from './orm/types.js';
3
+ type T1 = ColumnBuilder<string>;
4
+ type T2 = ColumnBuilder<Uuid>;
5
+ type T3 = ColumnBuilder<Timestamp>;
6
+ type T4 = ColumnBuilder<Json<{
7
+ a: number;
8
+ }>>;
9
+ type T5 = ColumnBuilder<IsPrimaryKey<HasDefault<Uuid>>>;
10
+ type IsNever<T> = [T] extends [never] ? true : false;
11
+ export type Results = {
12
+ string: T1;
13
+ uuid: T2;
14
+ timestamp: T3;
15
+ json: T4;
16
+ pk_uuid: T5;
17
+ uuid_is_never: IsNever<T2>;
18
+ timestamp_is_never: IsNever<T3>;
19
+ json_is_never: IsNever<T4>;
20
+ pk_uuid_is_never: IsNever<T5>;
21
+ };
22
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/test4.d.ts CHANGED
@@ -1,23 +1 @@
1
1
  import './polyfills.js';
2
- import { DocumentManagementAuthorizationService, type DocumentCollection, type DocumentCollectionMetadata } from './document-management/index.js';
3
- import { DocumentManagementAncillaryService } from './document-management/server/index.js';
4
- export declare class TestDocumentManagementAncillaryService extends DocumentManagementAncillaryService {
5
- resolveMetadata(_tenantId: string, collections: DocumentCollection[]): DocumentCollectionMetadata[];
6
- }
7
- export declare class AllowAllDocumentManagementAuthorizationService extends DocumentManagementAuthorizationService {
8
- getTenantId(): string;
9
- getSubject(): string;
10
- canReadCollection(): boolean;
11
- canCreateDocuments(): boolean;
12
- canUpdateDocument(): boolean;
13
- canDeleteDocuments(): boolean;
14
- canAssignDocuments(): boolean;
15
- canApproveDocument(): boolean;
16
- canRejectDocument(): boolean;
17
- canManageRequests(): boolean;
18
- canManageCategoriesAndTypes(): boolean;
19
- canReadDocumentRequestsTemplates(): boolean;
20
- canManageDocumentRequestsTemplates(): boolean;
21
- canManageValidationDefinitions(): boolean;
22
- canProgressDocumentWorkflow(): boolean;
23
- }
package/test4.js CHANGED
@@ -1,25 +1,10 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
1
  import './polyfills.js';
8
- import { configureAiService } from './ai/index.js';
9
2
  import { Application } from './application/application.js';
10
- import { provideModule, provideSignalHandler } from './application/index.js';
11
- import { DocumentManagementAuthorizationService } from './document-management/index.js';
12
- import { configureDocumentManagement } from './document-management/server/configure.js';
13
- import { DocumentManagementAncillaryService, DocumentManagementService } from './document-management/server/index.js';
14
- import { migrateDocumentManagementSchema } from './document-management/server/module.js';
15
- import { Singleton } from './injector/decorators.js';
3
+ import { provideInitializer, provideModule, provideSignalHandler } from './application/index.js';
16
4
  import { injectAsync } from './injector/inject.js';
17
- import { configureLocalMessageBus } from './message-bus/index.js';
18
- import { configureS3ObjectStorage } from './object-storage/index.js';
19
- import { configureOrm } from './orm/server/index.js';
20
- import { configurePostgresTaskQueue } from './task-queue/postgres/module.js';
5
+ import { PrettyPrintLogFormatter, provideConsoleLogTransport } from './logger/index.js';
6
+ import { configureOrm, Database } from './orm/server/index.js';
21
7
  import { boolean, positiveInteger, string } from './utils/config-parser.js';
22
- import { cancelableTimeout } from './utils/timing.js';
23
8
  const config = {
24
9
  database: {
25
10
  host: string('DATABASE_HOST', '127.0.0.1'),
@@ -45,36 +30,6 @@ const config = {
45
30
  bucketPerModule: boolean('S3_BUCKET_PER_MODULE', true),
46
31
  },
47
32
  };
48
- let TestDocumentManagementAncillaryService = class TestDocumentManagementAncillaryService extends DocumentManagementAncillaryService {
49
- resolveMetadata(_tenantId, collections) {
50
- return collections.map((collection) => ({ name: collection.id, group: null }));
51
- }
52
- };
53
- TestDocumentManagementAncillaryService = __decorate([
54
- Singleton()
55
- ], TestDocumentManagementAncillaryService);
56
- export { TestDocumentManagementAncillaryService };
57
- let AllowAllDocumentManagementAuthorizationService = class AllowAllDocumentManagementAuthorizationService extends DocumentManagementAuthorizationService {
58
- getTenantId() { return '00000000-0000-0000-0000-000000000000'; }
59
- getSubject() { return '00000000-0000-0000-0000-000000000000'; }
60
- canReadCollection() { return true; }
61
- canCreateDocuments() { return true; }
62
- canUpdateDocument() { return true; }
63
- canDeleteDocuments() { return true; }
64
- canAssignDocuments() { return true; }
65
- canApproveDocument() { return true; }
66
- canRejectDocument() { return true; }
67
- canManageRequests() { return true; }
68
- canManageCategoriesAndTypes() { return true; }
69
- canReadDocumentRequestsTemplates() { return true; }
70
- canManageDocumentRequestsTemplates() { return true; }
71
- canManageValidationDefinitions() { return true; }
72
- canProgressDocumentWorkflow() { return true; }
73
- };
74
- AllowAllDocumentManagementAuthorizationService = __decorate([
75
- Singleton()
76
- ], AllowAllDocumentManagementAuthorizationService);
77
- export { AllowAllDocumentManagementAuthorizationService };
78
33
  async function bootstrap() {
79
34
  configureOrm({
80
35
  connection: {
@@ -86,83 +41,14 @@ async function bootstrap() {
86
41
  },
87
42
  repositoryConfig: { schema: 'vitrass' },
88
43
  });
89
- configureS3ObjectStorage({
90
- endpoint: config.s3.endpoint,
91
- bucket: config.s3.bucket,
92
- bucketPerModule: config.s3.bucketPerModule,
93
- accessKey: config.s3.accessKey,
94
- secretKey: config.s3.secretKey,
95
- });
96
- configureDocumentManagement({
97
- ancillaryService: TestDocumentManagementAncillaryService,
98
- authorizationService: AllowAllDocumentManagementAuthorizationService,
99
- fileObjectStorageModule: 'documents',
100
- fileUploadObjectStorageModule: 'document-uploads',
101
- filePreviewObjectStorageModule: 'document-previews',
102
- });
103
- configurePostgresTaskQueue();
104
- configureLocalMessageBus();
105
- console.log('Configuring AI service');
106
- configureAiService({
107
- apiKey: config.ai.apiKey,
108
- keyFile: config.ai.keyFile,
109
- });
110
- await migrateDocumentManagementSchema();
111
44
  }
112
- async function main(cancellationSignal) {
113
- const documentManagementService = await injectAsync(DocumentManagementService);
114
- /*
115
- console.log(await documentManagementService.createCollection({ metadata: { attributes: { name: 'Patrick Hein' } } }));
116
- console.log(await documentManagementService.createCollection({ metadata: { attributes: { name: 'Merit Klenk' } } }));
117
- console.log(await documentManagementService.createCollection({ metadata: { attributes: { name: 'Haus' } } }));
118
- */
119
- const patrickHein = '4396c175-0551-4e70-aed8-13f51d307f4f';
120
- const meritKlenk = '28cec615-b327-43b0-aae6-f049cef9aa26';
121
- const haus = '32d9895f-476d-41f1-b79e-359c548957d3';
122
- const personalausweisType = '2c5c2b21-33ba-4262-ab96-24eaf05864a6';
123
- const lohnabrechnungType = '735d09c1-1ce9-4a29-ad23-3149b6be56ba';
124
- const bauplanType = '1b813c5d-1e75-4f59-853a-4272bb9d9c20';
125
- /*
126
- const personalausweisProperties = await Promise.all([
127
- await documentManagementService.createProperty({ label: 'Vorname', dataType: DocumentPropertyDataType.Text }),
128
- await documentManagementService.createProperty({ label: 'Nachname', dataType: DocumentPropertyDataType.Text }),
129
- await documentManagementService.createProperty({ label: 'Ausweisnummer', dataType: DocumentPropertyDataType.Text }),
130
- await documentManagementService.createProperty({ label: 'Geburtsdatum', dataType: DocumentPropertyDataType.Date }),
131
- await documentManagementService.createProperty({ label: 'Geburtsort', dataType: DocumentPropertyDataType.Text }),
132
- await documentManagementService.createProperty({ label: 'Staatsangehörigkeit', dataType: DocumentPropertyDataType.Text }),
133
- await documentManagementService.createProperty({ label: 'Gültig bis', dataType: DocumentPropertyDataType.Date }),
134
- await documentManagementService.createProperty({ label: 'Ausstellende Behörde', dataType: DocumentPropertyDataType.Text }),
135
- await documentManagementService.createProperty({ label: 'Anschrift Straße', dataType: DocumentPropertyDataType.Text }),
136
- await documentManagementService.createProperty({ label: 'Anschrift Hausnummer', dataType: DocumentPropertyDataType.Text }),
137
- await documentManagementService.createProperty({ label: 'Anschrift Postleitzahl', dataType: DocumentPropertyDataType.Text }),
138
- await documentManagementService.createProperty({ label: 'Anschrift Stadt', dataType: DocumentPropertyDataType.Text })
139
- ]);
140
-
141
- const propertyIds = personalausweisProperties.map((p) => p.id);
142
-
143
- for (const id of propertyIds) {
144
- await documentManagementService.assignPropertyToType({ propertyId: id, typeId: personalausweisType });
145
- }
146
- */
147
- /*
148
- await documentManagementService.createDocumentRequest({ collectionIds: [patrickHein], typeId: lohnabrechnungType, requiredFilesCount: 1, comment: 'Abrechnung Feb 2025' });
149
- await documentManagementService.createDocumentRequest({ collectionIds: [patrickHein], typeId: lohnabrechnungType, requiredFilesCount: 1, comment: 'Abrechnung Jan 2025' });
150
- await documentManagementService.createDocumentRequest({ collectionIds: [patrickHein], typeId: lohnabrechnungType, requiredFilesCount: 1, comment: 'Abrechnung Dez 2024' });
151
- await documentManagementService.createDocumentRequest({ collectionIds: [meritKlenk], typeId: personalausweisType, requiredFilesCount: 1, comment: null });
152
- await documentManagementService.createDocumentRequest({ collectionIds: [patrickHein], typeId: personalausweisType, requiredFilesCount: 1, comment: null });
153
- await documentManagementService.createDocumentRequest({ collectionIds: [haus], typeId: bauplanType, requiredFilesCount: 1, comment: null });
154
- */
155
- /*
156
- const file = await openAsBlob('/home/patrick/Downloads/Brutto-Netto-Abrechnung 2025 01 Januar.pdf');
157
-
158
- const task = await documentManagementService.createDocumentRequestAssignmentTask(
159
- { originalFileName: 'Brutto-Netto-Abrechnung 2025 01 Januar.pdf', collectionIds: [patrickHein, meritKlenk, haus] },
160
- file.stream()
161
- );
162
- */
163
- await cancelableTimeout(60000, cancellationSignal);
45
+ async function main(_cancellationSignal) {
46
+ const database = await injectAsync(Database);
47
+ await database.execute('FOO BAR BAZ');
164
48
  }
165
49
  Application.run('Test', [
50
+ provideInitializer(bootstrap),
166
51
  provideModule(main),
167
52
  provideSignalHandler(),
53
+ provideConsoleLogTransport(PrettyPrintLogFormatter),
168
54
  ]);
package/test5.js CHANGED
@@ -7,12 +7,14 @@ import { Logger } from './logger/logger.js';
7
7
  import { provideConsoleLogTransport } from './logger/transports/console.js';
8
8
  async function main(_cancellationSignal) {
9
9
  const logger = inject(Logger, 'Test');
10
- logger.error('Hello World!', { sessionId: 'abc123' });
11
- logger.warn('Hello World!');
12
- logger.info('Hello World!');
13
- logger.verbose('Hello World!');
14
- logger.debug('Hello World!');
15
- logger.trace('Hello World!');
10
+ logger.error('Hello World!', { sessionId: 'abc' });
11
+ logger.error('Hello World!', new Error('FOO!!'), { sessionId: 'def' });
12
+ logger.error(new Error('BAR!!'), { sessionId: 'ghi' });
13
+ // logger.warn('Hello World!');
14
+ // logger.info('Hello World!');
15
+ // logger.verbose('Hello World!');
16
+ // logger.debug('Hello World!');
17
+ // logger.trace('Hello World!');
16
18
  }
17
19
  Application.run('Test', [
18
20
  provideConsoleLogTransport(PrettyPrintLogFormatter),
package/utils/index.d.ts CHANGED
@@ -19,7 +19,6 @@ export * from './equals.js';
19
19
  export * from './factory-map.js';
20
20
  export * from './feedable-async-iterable.js';
21
21
  export * from './file-reader.js';
22
- export * from './format-error.js';
23
22
  export * from './format.js';
24
23
  export * from './helpers.js';
25
24
  export * from './html-link-utils.js';
package/utils/index.js CHANGED
@@ -19,7 +19,6 @@ export * from './equals.js';
19
19
  export * from './factory-map.js';
20
20
  export * from './feedable-async-iterable.js';
21
21
  export * from './file-reader.js';
22
- export * from './format-error.js';
23
22
  export * from './format.js';
24
23
  export * from './helpers.js';
25
24
  export * from './html-link-utils.js';
File without changes