@tstdl/base 0.93.173 → 0.93.174

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.
@@ -6,7 +6,7 @@ import { CircuitBreakerProvider } from '../../../circuit-breaker/provider.js';
6
6
  import { Logger } from '../../../logger/logger.js';
7
7
  import { setupIntegrationTest } from '../../../testing/index.js';
8
8
  import { vertexAiMultiLocation } from '../multi-region.plugin.js';
9
- vi.mock('#/utils/array/index.js', async (importOriginal) => {
9
+ vi.mock('../../../utils/array/index.js', async (importOriginal) => {
10
10
  const actual = await importOriginal();
11
11
  return {
12
12
  ...actual,
@@ -7,7 +7,7 @@ import { Logger } from '../../../logger/logger.js';
7
7
  import { setupIntegrationTest } from '../../../testing/index.js';
8
8
  import { timeout } from '../../../utils/timing.js';
9
9
  import { vertexAiMultiLocation } from '../multi-region.plugin.js';
10
- vi.mock('#/utils/array/index.js', async (importOriginal) => {
10
+ vi.mock('../../../utils/array/index.js', async (importOriginal) => {
11
11
  const actual = await importOriginal();
12
12
  return {
13
13
  ...actual,
@@ -14,6 +14,7 @@ export function corsMiddleware(options = {}) {
14
14
  const origin = request.headers.tryGetSingle('Origin');
15
15
  const allowCredentials = (await resolveApiEndpointDataProvider(request, context, cors.accessControlAllowCredentials)) ?? endpointDefinition?.credentials;
16
16
  if (isDefined(origin)) {
17
+ let allowOriginValidationFailed = false;
17
18
  if (isDefined(cors.accessControlAllowOrigin) && !response.headers.has('Access-Control-Allow-Origin')) {
18
19
  const allowedOrigin = await resolveApiEndpointDataProvider(request, context, cors.accessControlAllowOrigin);
19
20
  if (isDefined(allowedOrigin)) {
@@ -26,9 +27,8 @@ export function corsMiddleware(options = {}) {
26
27
  response.headers.append('Vary', 'Origin');
27
28
  }
28
29
  }
29
- else if (isOptions) {
30
- response.statusCode = 403;
31
- return;
30
+ else {
31
+ allowOriginValidationFailed = true;
32
32
  }
33
33
  }
34
34
  }
@@ -39,11 +39,14 @@ export function corsMiddleware(options = {}) {
39
39
  response.headers.set('Access-Control-Allow-Origin', origin);
40
40
  response.headers.append('Vary', 'Origin');
41
41
  }
42
- else if (isOptions) {
43
- response.statusCode = 403;
44
- return;
42
+ else {
43
+ allowOriginValidationFailed = true;
45
44
  }
46
45
  }
46
+ if (isOptions && allowOriginValidationFailed && !response.headers.has('Access-Control-Allow-Origin')) {
47
+ response.statusCode = 403;
48
+ return;
49
+ }
47
50
  }
48
51
  if (isOptions) {
49
52
  const customAllowMethods = await resolveApiEndpointDataProvider(request, context, cors.accessControlAllowMethods);
@@ -26,7 +26,7 @@ export declare class AuthenticationClientService<AdditionalTokenPayload extends
26
26
  private readonly logger;
27
27
  private readonly disposeSignal;
28
28
  private readonly forceRefreshRequested;
29
- private readonly forceRefreshRequested$;
29
+ private readonly forceRefreshSubject;
30
30
  private clockOffset;
31
31
  private initialized;
32
32
  private refreshLoopPromise;
@@ -7,7 +7,7 @@ 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 { Subject, filter, firstValueFrom, from, race, skip, takeUntil, timer } from 'rxjs';
10
+ import { Subject, filter, firstValueFrom, from, race, takeUntil, timer } from 'rxjs';
11
11
  import { CancellationSignal } from '../../cancellation/token.js';
12
12
  import { BadRequestError } from '../../errors/bad-request.error.js';
13
13
  import { ForbiddenError } from '../../errors/forbidden.error.js';
@@ -72,7 +72,7 @@ let AuthenticationClientService = class AuthenticationClientService {
72
72
  logger = inject(Logger, 'AuthenticationService');
73
73
  disposeSignal = inject(CancellationSignal).fork();
74
74
  forceRefreshRequested = signal(false);
75
- forceRefreshRequested$ = toObservable(this.forceRefreshRequested);
75
+ forceRefreshSubject = new Subject();
76
76
  clockOffset = 0;
77
77
  initialized = false;
78
78
  refreshLoopPromise;
@@ -267,6 +267,7 @@ let AuthenticationClientService = class AuthenticationClientService {
267
267
  this.setAdditionalData(data);
268
268
  }
269
269
  this.forceRefreshRequested.set(true);
270
+ this.forceRefreshSubject.next();
270
271
  }
271
272
  /**
272
273
  * Refresh the token.
@@ -404,7 +405,7 @@ let AuthenticationClientService = class AuthenticationClientService {
404
405
  timer(Math.max(10, delayMs)),
405
406
  from(this.disposeSignal),
406
407
  this.token$.pipe(filter((t) => t?.exp !== referenceExp)),
407
- this.forceRefreshRequested$.pipe(filter(Boolean), skip(1)),
408
+ this.forceRefreshSubject,
408
409
  ]), { defaultValue: undefined });
409
410
  while (this.disposeSignal.isUnset) {
410
411
  const token = this.token();
@@ -428,9 +429,9 @@ let AuthenticationClientService = class AuthenticationClientService {
428
429
  const currentNow = this.estimatedServerTimestampSeconds();
429
430
  const currentBuffer = calculateRefreshBufferSeconds(currentToken);
430
431
  const stillNeedsRefresh = this.forceRefreshRequested() || (currentNow >= currentToken.exp - currentBuffer);
431
- this.forceRefreshRequested.set(false);
432
432
  if (stillNeedsRefresh) {
433
433
  await this.refresh();
434
+ this.forceRefreshRequested.set(false);
434
435
  }
435
436
  });
436
437
  // If lock is held by another instance/tab, wait briefly for it to finish (passive sync)
@@ -90,10 +90,10 @@ describe('DocumentManagementAiService Integration', () => {
90
90
  await runInInjectionContext(injector, async () => {
91
91
  await aiService.extractData(tenantId, document.id);
92
92
  const lastCall = mockGenerate.mock.calls[0][0];
93
- const systemPrompt = lastCall.system;
94
- const systemPromptText = systemPrompt.map((p) => p.text).join('\n');
95
- expect(systemPromptText).toContain('Format the title of the document exactly as follows: INV-{{Date}}');
96
- expect(systemPromptText).toContain('Focus on items.');
93
+ const userPrompt = lastCall.prompt;
94
+ const userPromptText = userPrompt.map((p) => p.text).join('\n');
95
+ expect(userPromptText).toContain('Format the title of the document exactly as follows: INV-{{Date}}');
96
+ expect(userPromptText).toContain('Focus on items.');
97
97
  });
98
98
  });
99
99
  test('classifyDocumentType should include granular instructions in prompt', async () => {
@@ -6,6 +6,7 @@ import { object, string } from '../../schema/index.js';
6
6
  import { setupIntegrationTest } from '../../testing/index.js';
7
7
  import { isString } from '../../utils/type-guards.js';
8
8
  import { DocumentManagementConfiguration } from '../server/module.js';
9
+ import { DocumentFileService } from '../server/services/document-file.service.js';
9
10
  import { DocumentManagementAiProviderService, DocumentManagementAncillaryService } from '../server/services/index.js';
10
11
  import { AiValidationExecutor } from '../server/validators/ai-validation-executor.js';
11
12
  import { TestDocumentManagementAncillaryService } from './helper.js';
@@ -41,6 +42,7 @@ describe('AiValidationExecutor Overrides', () => {
41
42
  injector.register(DocumentManagementAiProviderService, { useValue: mockAiProvider });
42
43
  injector.register(DocumentManagementAncillaryService, { useToken: TestDocumentManagementAncillaryService });
43
44
  injector.register(DocumentManagementConfiguration, { useValue: { fileObjectStorageModule: 'docs', fileUploadObjectStorageModule: 'uploads', filePreviewObjectStorageModule: 'previews' } });
45
+ injector.register(DocumentFileService, { useValue: { getContent: vi.fn().mockResolvedValue(new Uint8Array([1, 2, 3])) } });
44
46
  });
45
47
  afterAll(async () => {
46
48
  await injector?.dispose();
@@ -66,6 +68,7 @@ describe('AiValidationExecutor Overrides', () => {
66
68
  const context = {
67
69
  execution: { tenantId },
68
70
  definition: { identifier: 'test-validation' },
71
+ document: { id: 'test-doc', mimeType: 'application/pdf' },
69
72
  };
70
73
  await executor.publicExecute(context);
71
74
  const call = generateSpy.mock.calls[0][0];
@@ -23,9 +23,9 @@ export type HttpServerResponseOptions = {
23
23
  };
24
24
  export declare class HttpServerResponse {
25
25
  #private;
26
+ readonly headers: HttpHeaders;
26
27
  statusCode: number | undefined;
27
28
  statusMessage: string | undefined;
28
- headers: HttpHeaders;
29
29
  get body(): HttpServerResponseBody | undefined;
30
30
  set body(value: HttpServerResponseBody | undefined);
31
31
  get bodyType(): HttpServerResponseBodyType;
@@ -5,9 +5,9 @@ import { HttpHeaders } from '../http-headers.js';
5
5
  export class HttpServerResponse {
6
6
  #body;
7
7
  #bodyType;
8
+ headers = new HttpHeaders();
8
9
  statusCode;
9
10
  statusMessage;
10
- headers;
11
11
  get body() {
12
12
  return this.#body;
13
13
  }
@@ -35,10 +35,18 @@ export class HttpServerResponse {
35
35
  });
36
36
  }
37
37
  update(options) {
38
- this.statusCode = options.statusCode;
39
- this.statusMessage = options.statusMessage;
40
- this.headers = new HttpHeaders(options.headers);
41
- this.body = options.body;
38
+ if (isDefined(options.statusCode)) {
39
+ this.statusCode = options.statusCode;
40
+ }
41
+ if (isDefined(options.statusMessage)) {
42
+ this.statusMessage = options.statusMessage;
43
+ }
44
+ if (isDefined(options.headers)) {
45
+ this.headers.setMany(options.headers);
46
+ }
47
+ if (isDefined(options.body)) {
48
+ this.body = options.body;
49
+ }
42
50
  if (isDefined(options.cookies)) {
43
51
  for (const [name, cookie] of objectEntries(options.cookies)) {
44
52
  this.headers.append('Set-Cookie', formatSetCookie(name, cookie.value, cookie));
@@ -1,11 +1,11 @@
1
1
  import { describe, expect, it, vi } from 'vitest';
2
2
  // Mock supports before importing PrettyPrintLogFormatter
3
- vi.mock('#/supports.js', () => ({
3
+ vi.mock('../../supports.js', () => ({
4
4
  supportsColoredStdout: true,
5
5
  supportsColoredStderr: true,
6
6
  }));
7
- import { LogLevel } from '../level.js';
8
7
  import { PrettyPrintLogFormatter } from '../formatters/pretty-print.js';
8
+ import { LogLevel } from '../level.js';
9
9
  describe('PrettyPrintLogFormatter', () => {
10
10
  const formatter = new PrettyPrintLogFormatter();
11
11
  it('should format a log entry with an error and no context', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.93.173",
3
+ "version": "0.93.174",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -203,7 +203,6 @@
203
203
  "typedoc-plugin-missing-exports": "4.1",
204
204
  "typescript": "5.9",
205
205
  "typescript-eslint": "8.57",
206
- "vite-tsconfig-paths": "6.1",
207
206
  "vitest": "4.1"
208
207
  }
209
208
  }