@tstdl/base 0.93.125 → 0.93.127
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/ai/genkit/tests/multi-region.test.js +6 -6
- package/ai/index.d.ts +2 -6
- package/ai/index.js +2 -6
- package/ai/parser/index.d.ts +1 -0
- package/ai/parser/index.js +1 -0
- package/ai/parser/parser.d.ts +12 -0
- package/ai/parser/parser.js +28 -0
- package/ai/prompts/build.d.ts +21 -0
- package/ai/prompts/build.js +25 -0
- package/ai/prompts/index.d.ts +2 -0
- package/ai/prompts/index.js +2 -0
- package/ai/prompts/instructions-formatter.d.ts +9 -22
- package/ai/prompts/instructions-formatter.js +20 -7
- package/ai/prompts/instructions.js +1 -1
- package/ai/prompts/steering.d.ts +27 -0
- package/ai/prompts/steering.js +54 -0
- package/ai/tests/instructions-formatter.test.js +115 -0
- package/ai/tests/steering.test.js +37 -0
- package/application/application.d.ts +2 -1
- package/application/application.js +3 -0
- package/authentication/client/module.d.ts +1 -1
- package/authentication/client/module.js +4 -5
- package/authentication/tests/authentication-ancillary.service.test.js +1 -1
- package/authentication/tests/authentication.api-controller.test.js +3 -1
- package/authentication/tests/authentication.api-request-token.provider.test.js +1 -1
- package/authentication/tests/authentication.client-service.test.js +1 -1
- package/authentication/tests/authentication.service.test.js +1 -1
- package/authentication/tests/subject.service.test.js +1 -1
- package/circuit-breaker/tests/circuit-breaker.test.js +1 -1
- package/document-management/api/document-management.api.d.ts +16 -16
- package/document-management/api/document-management.api.js +12 -12
- package/document-management/models/ai-configuration.d.ts +59 -0
- package/document-management/models/ai-configuration.js +1 -0
- package/document-management/models/document-assignment-scope.model.js +2 -4
- package/document-management/models/document-assignment-task.model.js +2 -4
- package/document-management/models/document-collection-assignment.model.js +2 -4
- package/document-management/models/document-collection.model.js +2 -3
- package/document-management/models/document-content.model.d.ts +6 -0
- package/document-management/models/document-content.model.js +32 -0
- package/document-management/models/document-property-value.model.js +1 -2
- package/document-management/models/document-request-collection-assignment.model.js +2 -4
- package/document-management/models/document-request.model.js +2 -4
- package/document-management/models/document-tag-assignment.model.js +2 -3
- package/document-management/models/document-validation-execution-related-document.model.js +2 -4
- package/document-management/models/document-validation-execution.model.js +2 -5
- package/document-management/models/document-workflow.model.d.ts +2 -1
- package/document-management/models/document-workflow.model.js +4 -5
- package/document-management/models/document.model.js +2 -3
- package/document-management/models/index.d.ts +2 -0
- package/document-management/models/index.js +2 -0
- package/document-management/server/api/document-management.api.d.ts +7 -7
- package/document-management/server/api/document-management.api.js +9 -9
- package/document-management/server/configure.d.ts +4 -1
- package/document-management/server/configure.js +9 -4
- package/document-management/server/drizzle/{0000_complex_black_bird.sql → 0000_curious_nighthawk.sql} +7 -27
- package/document-management/server/drizzle/meta/0000_snapshot.json +12 -284
- package/document-management/server/drizzle/meta/_journal.json +2 -2
- package/document-management/server/module.d.ts +2 -0
- package/document-management/server/module.js +1 -0
- package/document-management/server/schemas.d.ts +2 -1
- package/document-management/server/services/document-file.service.d.ts +6 -6
- package/document-management/server/services/document-file.service.js +7 -81
- package/document-management/server/services/document-management-ai-provider.service.d.ts +66 -0
- package/document-management/server/services/document-management-ai-provider.service.js +2 -0
- package/document-management/server/services/document-management-ai.service.d.ts +44 -7
- package/document-management/server/services/document-management-ai.service.js +332 -329
- package/document-management/server/services/document-validation.service.d.ts +1 -1
- package/document-management/server/services/document-workflow.service.d.ts +4 -3
- package/document-management/server/services/document-workflow.service.js +26 -9
- package/document-management/server/services/document.service.d.ts +7 -3
- package/document-management/server/services/document.service.js +13 -4
- package/document-management/server/services/index.d.ts +1 -0
- package/document-management/server/services/index.js +1 -0
- package/document-management/server/validators/ai-validation-executor.d.ts +419 -12
- package/document-management/server/validators/ai-validation-executor.js +51 -46
- package/document-management/server/validators/single-document-validation-executor.d.ts +1 -3
- package/document-management/server/validators/single-document-validation-executor.js +2 -4
- package/document-management/service-models/document.service-model.d.ts +3 -3
- package/document-management/service-models/document.service-model.js +1 -1
- package/document-management/tests/ai-config-hierarchy.test.d.ts +1 -0
- package/document-management/tests/ai-config-hierarchy.test.js +64 -0
- package/document-management/tests/ai-config-integration.test.d.ts +1 -0
- package/document-management/tests/ai-config-integration.test.js +125 -0
- package/document-management/tests/ai-config-merge.test.d.ts +1 -0
- package/document-management/tests/ai-config-merge.test.js +38 -0
- package/document-management/tests/document-management-ai-overrides.test.d.ts +1 -0
- package/document-management/tests/document-management-ai-overrides.test.js +64 -0
- package/document-management/tests/document-management-core.test.js +6 -6
- package/document-management/tests/document-management.api.test.js +5 -5
- package/document-management/tests/document-statistics.service.test.js +10 -6
- package/document-management/tests/document-validation-ai-overrides.test.d.ts +1 -0
- package/document-management/tests/document-validation-ai-overrides.test.js +85 -0
- package/document-management/tests/document.service.test.js +15 -11
- package/document-management/tests/enum-helpers.test.js +5 -5
- package/examples/document-management/ai-provider.d.ts +20 -0
- package/examples/document-management/ai-provider.js +74 -0
- package/examples/document-management/main.js +9 -6
- package/examples/injector/graph-example.d.ts +1 -0
- package/examples/injector/graph-example.js +340 -0
- package/injector/decorators.d.ts +4 -4
- package/injector/decorators.js +5 -6
- package/injector/forward-ref.d.ts +15 -0
- package/injector/forward-ref.js +20 -0
- package/injector/graph.d.ts +113 -0
- package/injector/graph.js +652 -0
- package/injector/index.d.ts +2 -0
- package/injector/index.js +2 -0
- package/injector/inject.d.ts +15 -15
- package/injector/injector.d.ts +101 -13
- package/injector/injector.js +103 -59
- package/injector/resolve-chain.d.ts +20 -6
- package/injector/resolve-chain.js +39 -14
- package/injector/tests/advanced.test.d.ts +1 -0
- package/injector/tests/advanced.test.js +116 -0
- package/injector/tests/async-init.test.d.ts +1 -0
- package/injector/tests/async-init.test.js +77 -0
- package/injector/tests/basic.test.d.ts +1 -0
- package/injector/tests/basic.test.js +114 -0
- package/injector/tests/hierarchical.test.d.ts +1 -0
- package/injector/tests/hierarchical.test.js +59 -0
- package/injector/tests/lifecycles.test.d.ts +1 -0
- package/injector/tests/lifecycles.test.js +109 -0
- package/injector/token.d.ts +2 -1
- package/injector/token.js +4 -1
- package/injector/type-info.d.ts +1 -5
- package/injector/types.d.ts +4 -10
- package/logger/tests/pretty-print.test.d.ts +1 -0
- package/logger/{formatters → tests}/pretty-print.test.js +1 -1
- package/logger/transports/console.d.ts +3 -2
- package/logger/transports/console.js +4 -3
- package/notification/tests/notification-api.test.js +8 -5
- package/notification/tests/notification-client.test.d.ts +1 -0
- package/notification/tests/{unit/notification-client.test.js → notification-client.test.js} +5 -5
- package/notification/tests/notification-flow.test.js +6 -5
- package/notification/tests/notification-sse.service.test.js +1 -1
- package/notification/tests/notification-type.service.test.js +1 -1
- package/object-storage/s3/s3.object-storage.js +3 -0
- package/object-storage/s3/tests/s3.object-storage.integration.test.js +1 -1
- package/orm/tests/repository-attributes.test.js +10 -17
- package/orm/tests/repository-cti-mapping.test.js +2 -2
- package/orm/tests/repository-cti-soft-delete.test.js +1 -1
- package/orm/tests/repository-cti.test.js +19 -33
- package/orm/tests/repository-extra-coverage.test.js +1 -1
- package/orm/tests/repository-search.test.js +5 -2
- package/orm/tests/transaction-safety.test.js +1 -1
- package/package.json +7 -9
- package/rate-limit/tests/postgres-rate-limiter.test.js +6 -16
- package/renderer/d2.d.ts +77 -0
- package/renderer/d2.js +68 -0
- package/renderer/graphviz.d.ts +47 -0
- package/renderer/graphviz.js +58 -0
- package/renderer/index.d.ts +4 -0
- package/renderer/index.js +4 -0
- package/renderer/typst.d.ts +57 -0
- package/renderer/typst.js +62 -0
- package/rpc/adapters/readable-stream.adapter.d.ts +3 -0
- package/rpc/adapters/readable-stream.adapter.js +5 -1
- package/rpc/rpc.js +28 -3
- package/rpc/tests/rpc.integration.test.js +3 -1
- package/schema/schemas/nullable.js +1 -1
- package/task-queue/task-queue.d.ts +2 -0
- package/task-queue/task-queue.js +6 -2
- package/task-queue/tests/complex.test.js +1 -1
- package/task-queue/tests/dependencies.test.js +3 -3
- package/task-queue/tests/extensive-dependencies.test.js +1 -1
- package/task-queue/tests/queue.test.js +1 -1
- package/task-queue/tests/worker.test.js +4 -7
- package/test5.js +52 -8
- package/{unit-test → testing}/integration-setup.d.ts +1 -0
- package/{unit-test → testing}/integration-setup.js +13 -0
- package/utils/base64.d.ts +7 -0
- package/utils/base64.js +10 -1
- package/utils/noop.d.ts +7 -1
- package/utils/noop.js +7 -1
- package/ai/ai-file.service.d.ts +0 -57
- package/ai/ai-file.service.js +0 -233
- package/ai/ai-session.d.ts +0 -38
- package/ai/ai-session.js +0 -50
- package/ai/ai.service.d.ts +0 -126
- package/ai/ai.service.js +0 -481
- package/ai/functions.d.ts +0 -9
- package/ai/functions.js +0 -38
- package/ai/module.d.ts +0 -26
- package/ai/module.js +0 -25
- package/ai/types.d.ts +0 -229
- package/ai/types.js +0 -33
- package/latex/index.d.ts +0 -1
- package/latex/index.js +0 -1
- package/typst/index.d.ts +0 -1
- package/typst/index.js +0 -1
- package/typst/render.d.ts +0 -23
- package/typst/render.js +0 -32
- /package/{logger/formatters/pretty-print.test.d.ts → ai/tests/instructions-formatter.test.d.ts} +0 -0
- /package/{notification/tests/unit/notification-client.test.d.ts → ai/tests/steering.test.d.ts} +0 -0
- /package/{latex/render.d.ts → renderer/latex.d.ts} +0 -0
- /package/{latex/render.js → renderer/latex.js} +0 -0
- /package/{unit-test → testing}/index.d.ts +0 -0
- /package/{unit-test → testing}/index.js +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tstdl/base",
|
|
3
|
-
"version": "0.93.
|
|
3
|
+
"version": "0.93.127",
|
|
4
4
|
"author": "Patrick Hein",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -76,7 +76,6 @@
|
|
|
76
76
|
"./jsx": "./jsx/index.js",
|
|
77
77
|
"./key-value-store": "./key-value-store/index.js",
|
|
78
78
|
"./key-value-store/postgres": "./key-value-store/postgres/index.js",
|
|
79
|
-
"./latex": "./latex/index.js",
|
|
80
79
|
"./lock": "./lock/index.js",
|
|
81
80
|
"./lock/postgres": "./lock/postgres/index.js",
|
|
82
81
|
"./lock/web": "./lock/web/index.js",
|
|
@@ -93,8 +92,8 @@
|
|
|
93
92
|
"./object-storage/s3": "./object-storage/s3/index.js",
|
|
94
93
|
"./openid-connect": "./openid-connect/index.js",
|
|
95
94
|
"./orm": "./orm/index.js",
|
|
96
|
-
"./orm/schemas": "./orm/schemas/index.js",
|
|
97
95
|
"./orm/data-types": "./orm/data-types/index.js",
|
|
96
|
+
"./orm/schemas": "./orm/schemas/index.js",
|
|
98
97
|
"./orm/server": "./orm/server/index.js",
|
|
99
98
|
"./password": "./password/index.js",
|
|
100
99
|
"./pdf": "./pdf/index.js",
|
|
@@ -105,6 +104,7 @@
|
|
|
105
104
|
"./rate-limit": "./rate-limit/index.js",
|
|
106
105
|
"./rate-limit/postgres": "./rate-limit/postgres/index.js",
|
|
107
106
|
"./reflection": "./reflection/index.js",
|
|
107
|
+
"./renderer": "./renderer/index.js",
|
|
108
108
|
"./rpc": "./rpc/index.js",
|
|
109
109
|
"./rpc/endpoints": "./rpc/endpoints/index.js",
|
|
110
110
|
"./rxjs-utils": "./rxjs-utils/index.js",
|
|
@@ -125,11 +125,10 @@
|
|
|
125
125
|
"./templates/renderers": "./templates/renderers/index.js",
|
|
126
126
|
"./templates/resolvers": "./templates/resolvers/index.js",
|
|
127
127
|
"./templates/types": "./templates/types/index.js",
|
|
128
|
+
"./testing": "./testing/index.js",
|
|
128
129
|
"./text": "./text/index.js",
|
|
129
130
|
"./threading": "./threading/index.js",
|
|
130
131
|
"./types": "./types/index.js",
|
|
131
|
-
"./typst": "./typst/index.js",
|
|
132
|
-
"./unit-test": "./unit-test/index.js",
|
|
133
132
|
"./utils": "./utils/index.js",
|
|
134
133
|
"./utils/array": "./utils/array/index.js",
|
|
135
134
|
"./utils/async-hook": "./utils/async-hook/index.js",
|
|
@@ -153,7 +152,6 @@
|
|
|
153
152
|
"peerDependencies": {
|
|
154
153
|
"@genkit-ai/google-genai": "^1.28",
|
|
155
154
|
"@google-cloud/storage": "^7.19",
|
|
156
|
-
"@google/genai": "^1.40",
|
|
157
155
|
"@toon-format/toon": "^2.1.0",
|
|
158
156
|
"@tstdl/angular": "^0.93",
|
|
159
157
|
"@zxcvbn-ts/core": "^3.0",
|
|
@@ -164,8 +162,8 @@
|
|
|
164
162
|
"file-type": "^21.3",
|
|
165
163
|
"genkit": "^1.28",
|
|
166
164
|
"handlebars": "^4.7",
|
|
167
|
-
"@aws-sdk/client-s3": "^3.
|
|
168
|
-
"@aws-sdk/s3-request-presigner": "^3.
|
|
165
|
+
"@aws-sdk/client-s3": "^3.990",
|
|
166
|
+
"@aws-sdk/s3-request-presigner": "^3.990",
|
|
169
167
|
"mjml": "^4.18",
|
|
170
168
|
"nodemailer": "^8.0",
|
|
171
169
|
"pg": "^8.18",
|
|
@@ -173,7 +171,7 @@
|
|
|
173
171
|
"preact": "^10.28",
|
|
174
172
|
"preact-render-to-string": "^6.6",
|
|
175
173
|
"sharp": "^0.34",
|
|
176
|
-
"undici": "^7.
|
|
174
|
+
"undici": "^7.22",
|
|
177
175
|
"urlpattern-polyfill": "^10.1",
|
|
178
176
|
"zod": "^3.25"
|
|
179
177
|
},
|
|
@@ -1,26 +1,23 @@
|
|
|
1
|
-
import { afterAll, describe, expect, it } from 'vitest';
|
|
1
|
+
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
2
2
|
import { RateLimiterProvider } from '../../rate-limit/index.js';
|
|
3
|
-
import { setupIntegrationTest } from '../../
|
|
3
|
+
import { setupIntegrationTest } from '../../testing/index.js';
|
|
4
4
|
import { timeout } from '../../utils/timing.js';
|
|
5
5
|
describe('PostgresRateLimiter Integration Tests', () => {
|
|
6
6
|
let injector;
|
|
7
7
|
let rateLimiter;
|
|
8
8
|
const limiterName = `test-limiter-${Date.now()}`;
|
|
9
|
-
async
|
|
10
|
-
|
|
11
|
-
({ injector } = await setupIntegrationTest({ modules: { rateLimiter: true } }));
|
|
12
|
-
}
|
|
9
|
+
beforeAll(async () => {
|
|
10
|
+
({ injector } = await setupIntegrationTest({ modules: { rateLimiter: true } }));
|
|
13
11
|
const rateLimiterProvider = injector.resolve(RateLimiterProvider);
|
|
14
|
-
|
|
12
|
+
rateLimiter = rateLimiterProvider.get(limiterName, {
|
|
15
13
|
burstCapacity: 10,
|
|
16
14
|
refillInterval: 1000, // 10 tokens per second -> 1 token per 100ms
|
|
17
15
|
});
|
|
18
|
-
}
|
|
16
|
+
});
|
|
19
17
|
afterAll(async () => {
|
|
20
18
|
await injector?.dispose();
|
|
21
19
|
}, 15000);
|
|
22
20
|
it('should acquire tokens successfully', async () => {
|
|
23
|
-
rateLimiter = await getLimiter();
|
|
24
21
|
const resource = 'res-1';
|
|
25
22
|
const result = await rateLimiter.tryAcquire(resource, 5);
|
|
26
23
|
expect(result).toBe(true);
|
|
@@ -30,7 +27,6 @@ describe('PostgresRateLimiter Integration Tests', () => {
|
|
|
30
27
|
expect(result3).toBe(false);
|
|
31
28
|
});
|
|
32
29
|
it('should refill tokens over time', async () => {
|
|
33
|
-
rateLimiter = await getLimiter();
|
|
34
30
|
const resource = 'res-2';
|
|
35
31
|
await rateLimiter.tryAcquire(resource, 10);
|
|
36
32
|
expect(await rateLimiter.tryAcquire(resource, 1)).toBe(false);
|
|
@@ -40,7 +36,6 @@ describe('PostgresRateLimiter Integration Tests', () => {
|
|
|
40
36
|
expect(await rateLimiter.tryAcquire(resource, 1)).toBe(false);
|
|
41
37
|
});
|
|
42
38
|
it('should refund tokens', async () => {
|
|
43
|
-
rateLimiter = await getLimiter();
|
|
44
39
|
const resource = 'res-3';
|
|
45
40
|
await rateLimiter.tryAcquire(resource, 10);
|
|
46
41
|
expect(await rateLimiter.tryAcquire(resource, 1)).toBe(false);
|
|
@@ -49,14 +44,12 @@ describe('PostgresRateLimiter Integration Tests', () => {
|
|
|
49
44
|
expect(await rateLimiter.tryAcquire(resource, 1)).toBe(false);
|
|
50
45
|
});
|
|
51
46
|
it('should handle fractional tokens', async () => {
|
|
52
|
-
rateLimiter = await getLimiter();
|
|
53
47
|
const resource = 'res-4';
|
|
54
48
|
await rateLimiter.tryAcquire(resource, 9.5);
|
|
55
49
|
expect(await rateLimiter.tryAcquire(resource, 1)).toBe(false);
|
|
56
50
|
expect(await rateLimiter.tryAcquire(resource, 0.5)).toBe(true);
|
|
57
51
|
});
|
|
58
52
|
it('should handle concurrent acquisitions', async () => {
|
|
59
|
-
rateLimiter = await getLimiter();
|
|
60
53
|
const resource = 'res-concurrent';
|
|
61
54
|
// Initialize
|
|
62
55
|
await rateLimiter.tryAcquire(resource, 0);
|
|
@@ -65,19 +58,16 @@ describe('PostgresRateLimiter Integration Tests', () => {
|
|
|
65
58
|
expect(successCount).toBe(10);
|
|
66
59
|
}, 15000);
|
|
67
60
|
it('should always allow zero or negative cost', async () => {
|
|
68
|
-
rateLimiter = await getLimiter();
|
|
69
61
|
const resource = 'res-zero';
|
|
70
62
|
expect(await rateLimiter.tryAcquire(resource, 0)).toBe(true);
|
|
71
63
|
expect(await rateLimiter.tryAcquire(resource, -1)).toBe(true);
|
|
72
64
|
});
|
|
73
65
|
it('should reject cost greater than burst capacity', async () => {
|
|
74
|
-
rateLimiter = await getLimiter();
|
|
75
66
|
const resource = 'res-large';
|
|
76
67
|
// Burst capacity is 10
|
|
77
68
|
expect(await rateLimiter.tryAcquire(resource, 11)).toBe(false);
|
|
78
69
|
});
|
|
79
70
|
it('should cap tokens at burst capacity on refill', async () => {
|
|
80
|
-
rateLimiter = await getLimiter();
|
|
81
71
|
const resource = 'res-refill-cap';
|
|
82
72
|
// Drain
|
|
83
73
|
await rateLimiter.tryAcquire(resource, 10);
|
package/renderer/d2.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export type D2RenderOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* The layout engine to use.
|
|
4
|
+
* @default 'dagre'
|
|
5
|
+
*/
|
|
6
|
+
layout?: string;
|
|
7
|
+
/**
|
|
8
|
+
* The theme ID to use.
|
|
9
|
+
* @default 0
|
|
10
|
+
*/
|
|
11
|
+
theme?: number;
|
|
12
|
+
/**
|
|
13
|
+
* The dark theme ID to use.
|
|
14
|
+
*/
|
|
15
|
+
darkTheme?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Pixels padded around the rendered diagram.
|
|
18
|
+
* @default 100
|
|
19
|
+
*/
|
|
20
|
+
pad?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Render the diagram to look like it was sketched by hand.
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
sketch?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Center the SVG in the containing viewbox.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
center?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* if given, multiple boards are packaged as 1 SVG which transitions through each board at the interval (in milliseconds).
|
|
33
|
+
* Can only be used with SVG exports.
|
|
34
|
+
* @default 0
|
|
35
|
+
*/
|
|
36
|
+
animateInterval?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Omit XML tag (<?xml ...?>) from output SVG files.
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
noXmlTag?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Add a salt value to ensure the output uses unique IDs.
|
|
44
|
+
*/
|
|
45
|
+
salt?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Omit D2 version from generated image.
|
|
48
|
+
* @default false
|
|
49
|
+
*/
|
|
50
|
+
omitVersion?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Target board to render.
|
|
53
|
+
* @default '*'
|
|
54
|
+
*/
|
|
55
|
+
target?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Scale the output. E.g., 0.5 to halve the default size.
|
|
58
|
+
* @default -1
|
|
59
|
+
*/
|
|
60
|
+
scale?: number;
|
|
61
|
+
/**
|
|
62
|
+
* The output format for the rendered diagram.
|
|
63
|
+
* @default 'svg'
|
|
64
|
+
*/
|
|
65
|
+
format?: 'svg' | 'png' | 'ascii' | 'txt' | 'pdf' | 'pptx' | 'gif';
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Renders D2 source code to a file in the specified format.
|
|
69
|
+
*
|
|
70
|
+
* ## WARNING
|
|
71
|
+
* **This function should not be used with untrusted D2 source, as it can lead to arbitrary code execution on the system.**
|
|
72
|
+
*
|
|
73
|
+
* Requires d2 to be installed on the system.
|
|
74
|
+
* @param source The D2 source code to render
|
|
75
|
+
* @param options Rendering options
|
|
76
|
+
*/
|
|
77
|
+
export declare function renderD2(source: string, options?: D2RenderOptions): Promise<Uint8Array<ArrayBuffer>>;
|
package/renderer/d2.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { spawnCommand } from '../process/spawn.js';
|
|
2
|
+
import { decodeText } from '../utils/encoding.js';
|
|
3
|
+
import { isDefined } from '../utils/type-guards.js';
|
|
4
|
+
/**
|
|
5
|
+
* Renders D2 source code to a file in the specified format.
|
|
6
|
+
*
|
|
7
|
+
* ## WARNING
|
|
8
|
+
* **This function should not be used with untrusted D2 source, as it can lead to arbitrary code execution on the system.**
|
|
9
|
+
*
|
|
10
|
+
* Requires d2 to be installed on the system.
|
|
11
|
+
* @param source The D2 source code to render
|
|
12
|
+
* @param options Rendering options
|
|
13
|
+
*/
|
|
14
|
+
export async function renderD2(source, options) {
|
|
15
|
+
const format = options?.format ?? 'svg';
|
|
16
|
+
const args = ['-', '-', '--stdout-format', format];
|
|
17
|
+
if (isDefined(options?.layout)) {
|
|
18
|
+
args.push('--layout', options.layout);
|
|
19
|
+
}
|
|
20
|
+
if (isDefined(options?.theme)) {
|
|
21
|
+
args.push('--theme', options.theme.toString());
|
|
22
|
+
}
|
|
23
|
+
if (isDefined(options?.darkTheme)) {
|
|
24
|
+
args.push('--dark-theme', options.darkTheme.toString());
|
|
25
|
+
}
|
|
26
|
+
if (isDefined(options?.pad)) {
|
|
27
|
+
args.push('--pad', options.pad.toString());
|
|
28
|
+
}
|
|
29
|
+
if (options?.sketch == true) {
|
|
30
|
+
args.push('--sketch');
|
|
31
|
+
}
|
|
32
|
+
if (options?.center == true) {
|
|
33
|
+
args.push('--center');
|
|
34
|
+
}
|
|
35
|
+
if (isDefined(options?.animateInterval)) {
|
|
36
|
+
args.push('--animate-interval', options.animateInterval.toString());
|
|
37
|
+
}
|
|
38
|
+
if (options?.noXmlTag == true) {
|
|
39
|
+
args.push('--no-xml-tag');
|
|
40
|
+
}
|
|
41
|
+
if (isDefined(options?.salt)) {
|
|
42
|
+
args.push('--salt', options.salt);
|
|
43
|
+
}
|
|
44
|
+
if (options?.omitVersion == true) {
|
|
45
|
+
args.push('--omit-version');
|
|
46
|
+
}
|
|
47
|
+
if (isDefined(options?.target)) {
|
|
48
|
+
args.push('--target', options.target);
|
|
49
|
+
}
|
|
50
|
+
if (isDefined(options?.scale)) {
|
|
51
|
+
args.push('--scale', options.scale.toString());
|
|
52
|
+
}
|
|
53
|
+
const process = await spawnCommand('d2', args);
|
|
54
|
+
const [{ code, output, error }] = await Promise.all([
|
|
55
|
+
process.waitRead('binary', { throwOnNonZeroExitCode: false }),
|
|
56
|
+
process.write(source),
|
|
57
|
+
]);
|
|
58
|
+
const errorString = decodeText(error);
|
|
59
|
+
if (code !== 0) {
|
|
60
|
+
throw new Error(`
|
|
61
|
+
D2 rendering failed with exit code ${code}.
|
|
62
|
+
|
|
63
|
+
Error Output:
|
|
64
|
+
${errorString}
|
|
65
|
+
`.trim());
|
|
66
|
+
}
|
|
67
|
+
return output;
|
|
68
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export type GraphvizRenderOptions = {
|
|
2
|
+
/**
|
|
3
|
+
* The layout engine to use.
|
|
4
|
+
* @default 'dot'
|
|
5
|
+
*/
|
|
6
|
+
engine?: 'dot' | 'neato' | 'fdp' | 'sfdp' | 'twopi' | 'circo';
|
|
7
|
+
/**
|
|
8
|
+
* The output format for the rendered diagram.
|
|
9
|
+
* @default 'svg'
|
|
10
|
+
*/
|
|
11
|
+
format?: 'svg' | 'png' | 'pdf' | 'jpg' | 'gif' | 'bmp' | 'eps' | 'ps' | 'tiff' | 'webp' | 'canon' | 'dot' | 'xdot' | 'plain' | 'plain-ext';
|
|
12
|
+
/**
|
|
13
|
+
* Set graph attributes (equivalent to -Gname=val)
|
|
14
|
+
*/
|
|
15
|
+
graphAttributes?: Record<string, string>;
|
|
16
|
+
/**
|
|
17
|
+
* Set node attributes (equivalent to -Nname=val)
|
|
18
|
+
*/
|
|
19
|
+
nodeAttributes?: Record<string, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Set edge attributes (equivalent to -Ename=val)
|
|
22
|
+
*/
|
|
23
|
+
edgeAttributes?: Record<string, string>;
|
|
24
|
+
/**
|
|
25
|
+
* Scale input by 'scale' (equivalent to -s[scale])
|
|
26
|
+
*/
|
|
27
|
+
scale?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Invert y coordinate in output (equivalent to -y)
|
|
30
|
+
*/
|
|
31
|
+
invertY?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Set level of message suppression (equivalent to -q[quiet])
|
|
34
|
+
*/
|
|
35
|
+
quiet?: boolean | number;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Renders Graphviz (DOT) source code to a file in the specified format.
|
|
39
|
+
*
|
|
40
|
+
* ## WARNING
|
|
41
|
+
* **This function should not be used with untrusted Graphviz source, as it can lead to arbitrary code execution on the system.**
|
|
42
|
+
*
|
|
43
|
+
* Requires Graphviz to be installed on the system.
|
|
44
|
+
* @param source The Graphviz source code to render
|
|
45
|
+
* @param options Rendering options
|
|
46
|
+
*/
|
|
47
|
+
export declare function renderGraphviz(source: string, options?: GraphvizRenderOptions): Promise<Uint8Array<ArrayBuffer>>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { spawnCommand } from '../process/spawn.js';
|
|
2
|
+
import { decodeText } from '../utils/encoding.js';
|
|
3
|
+
import { isDefined } from '../utils/type-guards.js';
|
|
4
|
+
/**
|
|
5
|
+
* Renders Graphviz (DOT) source code to a file in the specified format.
|
|
6
|
+
*
|
|
7
|
+
* ## WARNING
|
|
8
|
+
* **This function should not be used with untrusted Graphviz source, as it can lead to arbitrary code execution on the system.**
|
|
9
|
+
*
|
|
10
|
+
* Requires Graphviz to be installed on the system.
|
|
11
|
+
* @param source The Graphviz source code to render
|
|
12
|
+
* @param options Rendering options
|
|
13
|
+
*/
|
|
14
|
+
export async function renderGraphviz(source, options) {
|
|
15
|
+
const engine = options?.engine ?? 'dot';
|
|
16
|
+
const format = options?.format ?? 'svg';
|
|
17
|
+
const args = [`-T${format}`];
|
|
18
|
+
if (isDefined(options?.graphAttributes)) {
|
|
19
|
+
for (const [name, val] of Object.entries(options.graphAttributes)) {
|
|
20
|
+
args.push(`-G${name}=${val}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (isDefined(options?.nodeAttributes)) {
|
|
24
|
+
for (const [name, val] of Object.entries(options.nodeAttributes)) {
|
|
25
|
+
args.push(`-N${name}=${val}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (isDefined(options?.edgeAttributes)) {
|
|
29
|
+
for (const [name, val] of Object.entries(options.edgeAttributes)) {
|
|
30
|
+
args.push(`-E${name}=${val}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (isDefined(options?.scale)) {
|
|
34
|
+
args.push(`-s${options.scale}`);
|
|
35
|
+
}
|
|
36
|
+
if (options?.invertY == true) {
|
|
37
|
+
args.push('-y');
|
|
38
|
+
}
|
|
39
|
+
if (isDefined(options?.quiet)) {
|
|
40
|
+
const level = (options.quiet == true) ? '' : options.quiet.toString();
|
|
41
|
+
args.push(`-q${level}`);
|
|
42
|
+
}
|
|
43
|
+
const process = await spawnCommand(engine, args);
|
|
44
|
+
const [{ code, output, error }] = await Promise.all([
|
|
45
|
+
process.waitRead('binary', { throwOnNonZeroExitCode: false }),
|
|
46
|
+
process.write(source),
|
|
47
|
+
]);
|
|
48
|
+
const errorString = decodeText(error);
|
|
49
|
+
if (code !== 0) {
|
|
50
|
+
throw new Error(`
|
|
51
|
+
Graphviz rendering failed with exit code ${code}.
|
|
52
|
+
|
|
53
|
+
Error Output:
|
|
54
|
+
${errorString}
|
|
55
|
+
`.trim());
|
|
56
|
+
}
|
|
57
|
+
return output;
|
|
58
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { LiteralUnion } from 'type-fest';
|
|
2
|
+
export type TypstRenderOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* The root directory for resolving imports in the Typst source. If not specified, imports will be resolved relative to the location of the source file.
|
|
5
|
+
*/
|
|
6
|
+
root?: string;
|
|
7
|
+
/**
|
|
8
|
+
* The output format for the rendered document.
|
|
9
|
+
* Note: `docx` output uses pandoc under the hood, which does not support all Typst features.
|
|
10
|
+
* @default 'pdf'
|
|
11
|
+
*/
|
|
12
|
+
format?: 'pdf' | 'png' | 'svg' | 'html' | 'docx';
|
|
13
|
+
/**
|
|
14
|
+
* Which pages to render.
|
|
15
|
+
*/
|
|
16
|
+
pages?: (string | number | {
|
|
17
|
+
from?: number;
|
|
18
|
+
to?: number;
|
|
19
|
+
})[];
|
|
20
|
+
/**
|
|
21
|
+
* Add string key-value pairs visible through `sys.inputs`
|
|
22
|
+
*/
|
|
23
|
+
inputs?: Record<string, string>;
|
|
24
|
+
/**
|
|
25
|
+
* The document's creation date formatted as a UNIX timestamp in milliseconds.
|
|
26
|
+
*/
|
|
27
|
+
creationTimestamp?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Adds additional directories that are recursively searched for fonts.
|
|
30
|
+
*/
|
|
31
|
+
fontPaths?: string[];
|
|
32
|
+
/**
|
|
33
|
+
* Ensures system fonts won't be searched, unless explicitly included via `fontPaths`.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
ignoreSystemFonts?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The PPI (pixels per inch) to use for PNG export.
|
|
39
|
+
* @default 144
|
|
40
|
+
*/
|
|
41
|
+
ppi?: number;
|
|
42
|
+
/**
|
|
43
|
+
* One (or multiple comma-separated) PDF standards that Typst will enforce conformance with.
|
|
44
|
+
*/
|
|
45
|
+
pdfStandard?: LiteralUnion<'1.4' | '1.5' | '1.6' | '1.7' | '2.0' | 'a-1b' | 'a-1a' | 'a-2b' | 'a-2u' | 'a-2a' | 'a-3b' | 'a-3u' | 'a-3a' | 'a-4' | 'a-4f' | 'a-4e' | 'ua-1', string>;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Renders Typst source code to a file in the specified format.
|
|
49
|
+
*
|
|
50
|
+
* ## WARNING
|
|
51
|
+
* **This function should not be used with untrusted typst source, as it can lead to arbitrary code execution on the system.**
|
|
52
|
+
*
|
|
53
|
+
* Requires typst to be installed on the system.
|
|
54
|
+
* @param source
|
|
55
|
+
* @param options
|
|
56
|
+
*/
|
|
57
|
+
export declare function renderTypst(source: string, options?: TypstRenderOptions): Promise<Uint8Array<ArrayBuffer>>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { spawnCommand } from '../process/spawn.js';
|
|
2
|
+
import { decodeText } from '../utils/encoding.js';
|
|
3
|
+
import { isDefined, isNumber, isString } from '../utils/type-guards.js';
|
|
4
|
+
/**
|
|
5
|
+
* Renders Typst source code to a file in the specified format.
|
|
6
|
+
*
|
|
7
|
+
* ## WARNING
|
|
8
|
+
* **This function should not be used with untrusted typst source, as it can lead to arbitrary code execution on the system.**
|
|
9
|
+
*
|
|
10
|
+
* Requires typst to be installed on the system.
|
|
11
|
+
* @param source
|
|
12
|
+
* @param options
|
|
13
|
+
*/
|
|
14
|
+
export async function renderTypst(source, options) {
|
|
15
|
+
const format = options?.format ?? 'pdf';
|
|
16
|
+
const command = (format == 'docx') ? 'pandoc' : 'typst';
|
|
17
|
+
let args = (format == 'docx')
|
|
18
|
+
? ['--from', 'typst', '--to', 'docx', '--output']
|
|
19
|
+
: ['compile', '--format', format];
|
|
20
|
+
if (command == 'typst') {
|
|
21
|
+
if (isDefined(options?.root)) {
|
|
22
|
+
args.push('--root', options.root);
|
|
23
|
+
}
|
|
24
|
+
if (isDefined(options?.creationTimestamp)) {
|
|
25
|
+
args.push('--creation-timestamp', Math.floor(options.creationTimestamp / 1000).toString());
|
|
26
|
+
}
|
|
27
|
+
if (isDefined(options?.fontPaths)) {
|
|
28
|
+
for (const fontPath of options.fontPaths) {
|
|
29
|
+
args.push('--font-path', fontPath);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (options?.ignoreSystemFonts == true) {
|
|
33
|
+
args.push('--ignore-system-fonts');
|
|
34
|
+
}
|
|
35
|
+
if (isDefined(options?.ppi)) {
|
|
36
|
+
args.push('--ppi', options.ppi.toString());
|
|
37
|
+
}
|
|
38
|
+
if (isDefined(options?.pdfStandard)) {
|
|
39
|
+
args.push('--pdf-standard', options.pdfStandard);
|
|
40
|
+
}
|
|
41
|
+
if (isDefined(options?.pages)) {
|
|
42
|
+
const pageParts = options.pages.map((page) => (isNumber(page) || isString(page))
|
|
43
|
+
? page.toString()
|
|
44
|
+
: `${page.from ?? ''}-${page.to ?? ''}`);
|
|
45
|
+
args.push('--pages', pageParts.join(','));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
args.push('-', '-');
|
|
49
|
+
const process = await spawnCommand(command, args);
|
|
50
|
+
const [{ code, output, error }] = await Promise.all([
|
|
51
|
+
process.waitRead('binary', { throwOnNonZeroExitCode: false }),
|
|
52
|
+
process.write(source),
|
|
53
|
+
]);
|
|
54
|
+
const errorString = decodeText(error);
|
|
55
|
+
if (code !== 0) {
|
|
56
|
+
throw new Error(`
|
|
57
|
+
Typst compilation failed with exit code ${code}.\n
|
|
58
|
+
Error Output:\n${errorString}
|
|
59
|
+
`.trim());
|
|
60
|
+
}
|
|
61
|
+
return output;
|
|
62
|
+
}
|
|
@@ -13,6 +13,9 @@ type Response<T> = {
|
|
|
13
13
|
type: 'done';
|
|
14
14
|
} | {
|
|
15
15
|
type: 'void';
|
|
16
|
+
} | {
|
|
17
|
+
type: 'throw';
|
|
18
|
+
error: Error;
|
|
16
19
|
};
|
|
17
20
|
export declare class ReadableStreamRpcAdapter<T> implements RpcAdapter<ReadableStream<T>, void, void, Request, Response<T>> {
|
|
18
21
|
readonly name = "ReadableStream";
|
|
@@ -57,6 +57,10 @@ export class ReadableStreamRpcAdapter {
|
|
|
57
57
|
controller.close();
|
|
58
58
|
break;
|
|
59
59
|
}
|
|
60
|
+
case 'throw': {
|
|
61
|
+
controller.error(response.error);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
60
64
|
default: {
|
|
61
65
|
throw new NotSupportedError(`Type ${response.type} is not supported.`);
|
|
62
66
|
}
|
|
@@ -65,7 +69,7 @@ export class ReadableStreamRpcAdapter {
|
|
|
65
69
|
async cancel(reason) {
|
|
66
70
|
await channel.request({ type: 'cancel', reason });
|
|
67
71
|
channel.close();
|
|
68
|
-
}
|
|
72
|
+
},
|
|
69
73
|
});
|
|
70
74
|
}
|
|
71
75
|
}
|
package/rpc/rpc.js
CHANGED
|
@@ -19,6 +19,9 @@ const proxyTargets = new WeakSet();
|
|
|
19
19
|
const exposings = new Map();
|
|
20
20
|
const proxyChannels = new WeakMap();
|
|
21
21
|
const channelFinalizationRegistry = new FinalizationRegistry((data) => data.channel.close());
|
|
22
|
+
const rpcSet = Symbol('Rpc.set');
|
|
23
|
+
const rpcDelete = Symbol('Rpc.delete');
|
|
24
|
+
const rpcHas = Symbol('Rpc.has');
|
|
22
25
|
class RpcProxy {
|
|
23
26
|
}
|
|
24
27
|
export const Rpc = {
|
|
@@ -107,13 +110,13 @@ export const Rpc = {
|
|
|
107
110
|
return isDefined(channel);
|
|
108
111
|
},
|
|
109
112
|
async set(proxy, property, value) {
|
|
110
|
-
await
|
|
113
|
+
await proxy[rpcSet](property, value);
|
|
111
114
|
},
|
|
112
115
|
async delete(proxy, property) {
|
|
113
|
-
return await
|
|
116
|
+
return await proxy[rpcDelete](property);
|
|
114
117
|
},
|
|
115
118
|
async has(proxy, property) {
|
|
116
|
-
return await
|
|
119
|
+
return await proxy[rpcHas](property);
|
|
117
120
|
},
|
|
118
121
|
reset() {
|
|
119
122
|
exposings.clear();
|
|
@@ -141,6 +144,28 @@ function createProxy(channel, path = []) {
|
|
|
141
144
|
.then((responseValue) => parseRpcMessageValue(responseValue, endpoint));
|
|
142
145
|
},
|
|
143
146
|
get(_target, property) {
|
|
147
|
+
if (property == rpcSet) {
|
|
148
|
+
return async (prop, value) => {
|
|
149
|
+
const postMessageData = getPostMessageData(value, endpoint);
|
|
150
|
+
return await channel
|
|
151
|
+
.request({ type: 'set', path: [...path, prop], value: postMessageData.value }, postMessageData.transfer)
|
|
152
|
+
.then((responseValue) => parseRpcMessageValue(responseValue, endpoint));
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (property == rpcDelete) {
|
|
156
|
+
return async (prop) => {
|
|
157
|
+
return await channel
|
|
158
|
+
.request({ type: 'deleteProperty', path: [...path, prop] })
|
|
159
|
+
.then((responseValue) => parseRpcMessageValue(responseValue, endpoint));
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (property == rpcHas) {
|
|
163
|
+
return async (prop) => {
|
|
164
|
+
return await channel
|
|
165
|
+
.request({ type: 'has', path: [...path, prop] })
|
|
166
|
+
.then((responseValue) => parseRpcMessageValue(responseValue, endpoint));
|
|
167
|
+
};
|
|
168
|
+
}
|
|
144
169
|
if (property == 'then') {
|
|
145
170
|
if (path.length == 0) {
|
|
146
171
|
return { then: () => proxy };
|
|
@@ -187,6 +187,8 @@ describe('Rpc Integration', () => {
|
|
|
187
187
|
const proxy = await Rpc.connect(clientEndpoint, 'test-service-helpers');
|
|
188
188
|
expect(await Rpc.has(proxy, 'foo')).toBe(true);
|
|
189
189
|
expect(await Rpc.has(proxy, 'nonExistent')).toBe(false);
|
|
190
|
+
// Standard Reflect.has on a proxy with async traps will always be true (truthy promise)
|
|
191
|
+
expect(Reflect.has(proxy, 'nonExistent')).toBe(true);
|
|
190
192
|
const deleteResult = await Rpc.delete(proxy, 'foo');
|
|
191
193
|
expect(deleteResult).toBe(true);
|
|
192
194
|
expect(await Rpc.has(proxy, 'foo')).toBe(false);
|
|
@@ -522,7 +524,7 @@ describe('Rpc Integration', () => {
|
|
|
522
524
|
});
|
|
523
525
|
it('should throw when serializing a marked rpc proxy directly', async () => {
|
|
524
526
|
const { serialize } = await import('../../serializer/index.js');
|
|
525
|
-
const proxyInstance = new Rpc.
|
|
527
|
+
const proxyInstance = new Rpc[internal].RpcProxy();
|
|
526
528
|
expect(() => serialize(proxyInstance)).toThrow(NotSupportedError);
|
|
527
529
|
});
|
|
528
530
|
it('should support serializing an object marked with Rpc.adapt', async () => {
|
|
@@ -8,7 +8,7 @@ export class NullableSchema extends Schema {
|
|
|
8
8
|
schema;
|
|
9
9
|
constructor(schema) {
|
|
10
10
|
if ((schema instanceof NullableSchema) && (schema == schema.schema)) {
|
|
11
|
-
return schema;
|
|
11
|
+
return schema;
|
|
12
12
|
}
|
|
13
13
|
super();
|
|
14
14
|
this.schema = schemaTestableToSchema(schema);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CancellationSignal } from '../cancellation/token.js';
|
|
2
2
|
import { type EnumType } from '../enumeration/enumeration.js';
|
|
3
|
+
import { Injector } from '../injector/index.js';
|
|
3
4
|
import type { Resolvable, resolveArgumentType } from '../injector/interfaces.js';
|
|
4
5
|
import { Logger } from '../logger/logger.js';
|
|
5
6
|
import type { Transaction } from '../orm/server/transaction.js';
|
|
@@ -179,6 +180,7 @@ export declare abstract class TaskQueue<Definitions extends TaskDefinitionMap =
|
|
|
179
180
|
namespace: string;
|
|
180
181
|
}> implements Resolvable<TaskQueueArgument> {
|
|
181
182
|
readonly [resolveArgumentType]: TaskQueueArgument;
|
|
183
|
+
protected readonly injector: Injector;
|
|
182
184
|
protected readonly config: QueueConfig & {
|
|
183
185
|
namespace: string;
|
|
184
186
|
};
|