dsh-zen-remote 2.3.3 → 2.3.4
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/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/docs/plugin-bridge.md +14 -7
- package/docs/remote-access.en.md +8 -8
- package/docs/remote-access.md +10 -10
- package/lib/adapters/dsh-better-sidebar/index.js +21 -8
- package/lib/adapters/dsh-better-sidebar/index.js.map +1 -1
- package/lib/adapters/dsh-better-sidebar/surface.js +79 -0
- package/lib/adapters/dsh-better-sidebar/surface.js.map +1 -0
- package/lib/client.js +1 -1
- package/lib/index.js +103 -10
- package/lib/index.js.map +1 -1
- package/lib/intercept.js +23 -1
- package/lib/intercept.js.map +1 -1
- package/lib/merge-streams.js +29 -2
- package/lib/merge-streams.js.map +1 -1
- package/lib/plugin-adapter-core.js +69 -13
- package/lib/plugin-adapter-core.js.map +1 -1
- package/lib/plugin-bridge.js +179 -12
- package/lib/plugin-bridge.js.map +1 -1
- package/lib/plugin-route-intercept.js +631 -79
- package/lib/plugin-route-intercept.js.map +1 -1
- package/lib/plugin-tunnel.js +84 -12
- package/lib/plugin-tunnel.js.map +1 -1
- package/lib/relay-server.js +65 -47
- package/lib/relay-server.js.map +1 -1
- package/lib/types/adapters/dsh-better-sidebar/index.d.ts.map +1 -1
- package/lib/types/adapters/dsh-better-sidebar/surface.d.ts +23 -0
- package/lib/types/adapters/dsh-better-sidebar/surface.d.ts.map +1 -0
- package/lib/types/adapters/types.d.ts +14 -3
- package/lib/types/adapters/types.d.ts.map +1 -1
- package/lib/types/index.d.ts +2 -2
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/intercept.d.ts +19 -0
- package/lib/types/intercept.d.ts.map +1 -1
- package/lib/types/merge-streams.d.ts +12 -0
- package/lib/types/merge-streams.d.ts.map +1 -1
- package/lib/types/plugin-adapter-core.d.ts +24 -11
- package/lib/types/plugin-adapter-core.d.ts.map +1 -1
- package/lib/types/plugin-bridge.d.ts +93 -5
- package/lib/types/plugin-bridge.d.ts.map +1 -1
- package/lib/types/plugin-route-intercept.d.ts +52 -3
- package/lib/types/plugin-route-intercept.d.ts.map +1 -1
- package/lib/types/plugin-tunnel.d.ts +27 -3
- package/lib/types/plugin-tunnel.d.ts.map +1 -1
- package/lib/types/relay-server.d.ts +2 -25
- package/lib/types/relay-server.d.ts.map +1 -1
- package/lib/types/upload-limits.d.ts +67 -0
- package/lib/types/upload-limits.d.ts.map +1 -0
- package/lib/types/wizard/proxy-snippets.d.ts +4 -3
- package/lib/types/wizard/proxy-snippets.d.ts.map +1 -1
- package/lib/upload-limits.js +67 -0
- package/lib/upload-limits.js.map +1 -0
- package/lib/wizard/proxy-snippets.js +5 -4
- package/lib/wizard/proxy-snippets.js.map +1 -1
- package/package.json +2 -2
- package/scripts/check-upload-limits.mjs +167 -0
- package/src/adapters/dsh-better-sidebar/index.ts +21 -9
- package/src/adapters/dsh-better-sidebar/surface.ts +90 -0
- package/src/adapters/types.ts +14 -3
- package/src/client-data/wizard.ts +1 -1
- package/src/index.ts +99 -12
- package/src/intercept.ts +47 -1
- package/src/merge-streams.ts +41 -1
- package/src/plugin-adapter-core.ts +69 -14
- package/src/plugin-bridge.ts +228 -14
- package/src/plugin-route-intercept.ts +677 -82
- package/src/plugin-tunnel.ts +95 -13
- package/src/relay-server.ts +60 -48
- package/src/upload-limits.ts +69 -0
- package/src/wizard/proxy-snippets.ts +5 -4
|
@@ -149,7 +149,9 @@ export interface AdapterHooks {
|
|
|
149
149
|
export interface NormalizedAdapter {
|
|
150
150
|
plugin: string;
|
|
151
151
|
/** The exact versions this adapter was written against; the INSTALLED
|
|
152
|
-
* version must be among them or
|
|
152
|
+
* version must be among them — or its wire surface must be whitelisted in
|
|
153
|
+
* the adapter's `surfaces` table (PB-19) — or the adapter does not
|
|
154
|
+
* register. */
|
|
153
155
|
versions: readonly string[];
|
|
154
156
|
routes: NormalizedAdapterRoute[];
|
|
155
157
|
/** The digest of the ROUTE TABLE (locator and match included) — the
|
|
@@ -160,12 +162,11 @@ export interface NormalizedAdapter {
|
|
|
160
162
|
declaration: NormalizedDeclaration;
|
|
161
163
|
hooks: AdapterHooks;
|
|
162
164
|
}
|
|
163
|
-
/** The body cap an ADAPTER route may declare:
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
* adapter exists to carry
|
|
168
|
-
* two numbers together. */
|
|
165
|
+
/** The body cap an ADAPTER route may declare: the relay's own upload
|
|
166
|
+
* budget (`MAX_UPLOAD_BYTES` in upload-limits.ts), which the better-sidebar
|
|
167
|
+
* upload route rides. The same 500 MiB the cooperative declaration's
|
|
168
|
+
* maxBody allows — both read the one constant since PB-20; raw media
|
|
169
|
+
* uploads are exactly what an adapter exists to carry. */
|
|
169
170
|
export declare const MAX_ADAPTER_BODY_BYTES: number;
|
|
170
171
|
/** Validate one adapter's route table and fold it, together with the
|
|
171
172
|
* INSTALLED plugin version, into the registry-ready form.
|
|
@@ -174,18 +175,30 @@ export declare const MAX_ADAPTER_BODY_BYTES: number;
|
|
|
174
175
|
* absolute paths, off the host-owned `/_dsh/` and `/api` prefixes) — an
|
|
175
176
|
* adapter must not be able to reach anything a declaration cannot. The
|
|
176
177
|
* installed version must be listed EXACTLY (`versions` are what the
|
|
177
|
-
* adapter was written against)
|
|
178
|
+
* adapter was written against) — with ONE out (PB-19): a version outside
|
|
179
|
+
* the list is admitted anyway when `options.surfaceDigest` — the wiring's
|
|
180
|
+
* extraction of the INSTALLED build's wire surface — is a key of the
|
|
181
|
+
* adapter's `surfaces` table; the registration then carries the installed
|
|
182
|
+
* version with the usual route-table digest, so two machines on the same
|
|
183
|
+
* unlisted-but-surface-identical release still agree. A miss refuses with
|
|
184
|
+
* the digest and the table's size in the message, for the logs.
|
|
178
185
|
* @throws with a field-naming message on any illegal shape.
|
|
179
186
|
*/
|
|
180
|
-
export declare function normalizeAdapter(input: unknown, installedVersion: string
|
|
187
|
+
export declare function normalizeAdapter(input: unknown, installedVersion: string, options?: {
|
|
188
|
+
surfaceDigest?: string;
|
|
189
|
+
}): NormalizedAdapter;
|
|
181
190
|
/** The digest of one adapter's route table: sha256 over a canonical JSON of
|
|
182
191
|
* `{plugin, version, routes}` — the locator and the match mode INCLUDED (a
|
|
183
192
|
* different locating rule is a different adapter), hex, first 16 chars.
|
|
184
193
|
* Routes arrive path-sorted, so order never moves the hash. */
|
|
185
194
|
export declare function adapterDigestOf(plugin: string, version: string, routes: NormalizedAdapterRoute[]): string;
|
|
186
|
-
/** The prefix-match rule, shared verbatim by both halves: equality or
|
|
187
|
-
* path
|
|
195
|
+
/** The prefix-match rule, shared verbatim by both halves: equality, or any
|
|
196
|
+
* deeper sub-path (`startsWith(path + '/')`), on the RAW undecoded pathname. */
|
|
188
197
|
export declare function adapterPathMatches(route: NormalizedAdapterRoute, pathname: string): boolean;
|
|
198
|
+
/** Whether {@link adapterPathMatches} hit via a deeper tail whose shape
|
|
199
|
+
* breaks the red line — `false` for a non-match (the caller's routing
|
|
200
|
+
* refusal answers first) and for an equality hit (no tail at all). */
|
|
201
|
+
export declare function adapterTailShapeViolation(route: NormalizedAdapterRoute, pathname: string): boolean;
|
|
189
202
|
/** The adapter route a forwarded request hit, or `undefined`. `local`
|
|
190
203
|
* routes never match here — they stay on the sub-client's own machine in
|
|
191
204
|
* both directions, so the server half must never see (nor serve) them. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-adapter-core.d.ts","sourceRoot":"","sources":["../../src/plugin-adapter-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAa,WAAW,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"plugin-adapter-core.d.ts","sourceRoot":"","sources":["../../src/plugin-adapter-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,12 +11,15 @@
|
|
|
11
11
|
* ({@link createBridgeRegistry}), and the local-vs-server comparison that a
|
|
12
12
|
* later task feeds handshake data into ({@link compareBridges}).
|
|
13
13
|
*
|
|
14
|
-
* Pure logic by design: no DSH imports
|
|
14
|
+
* Pure logic by design: no DSH imports (the one exception is the
|
|
15
|
+
* pure-constants src/upload-limits.ts, itself zero-import), no I/O, no
|
|
16
|
+
* clocks — the digest is
|
|
15
17
|
* the only place node:crypto appears, which is fine because this module only
|
|
16
18
|
* ever runs in the backend process. Nothing here talks to the relay or the
|
|
17
19
|
* network; the handshake side and the request rewrite side are later tasks
|
|
18
20
|
* that consume a {@link BridgeRegistry} through src/index.ts.
|
|
19
21
|
*/
|
|
22
|
+
import { MAX_UPLOAD_BYTES } from './upload-limits.js';
|
|
20
23
|
/** Where a bridged route's caller supplies the session id. `'session'` — the
|
|
21
24
|
* data is scoped to one session, forwarded after the server checks the share.
|
|
22
25
|
* `'server'` — whole-machine data (e.g. every zcode task), which the server
|
|
@@ -25,10 +28,49 @@ export type BridgeScope = 'session' | 'server';
|
|
|
25
28
|
/** The HTTP methods a bridged route may forward (PB-9). 2.1 accepted GET
|
|
26
29
|
* only; the write methods arrived with the `methods` field. */
|
|
27
30
|
export declare const BRIDGE_METHODS: readonly ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"];
|
|
28
|
-
/** The body cap a route may declare (`maxBody`), in bytes
|
|
29
|
-
|
|
31
|
+
/** The body cap a route may declare (`maxBody`), in bytes. This is the SAME
|
|
32
|
+
* single 500 MiB ceiling {@link MAX_UPLOAD_BYTES} defines in
|
|
33
|
+
* src/upload-limits.ts, re-exported under the bridge-local name so existing
|
|
34
|
+
* consumers stay untouched: three ceilings that used to be three numbers —
|
|
35
|
+
* the relay's `/v1/upload` route, the sub-client's streaming upload forward
|
|
36
|
+
* (both reading upload-limits.ts directly) and this bridge `maxBody` cap
|
|
37
|
+
* (hand-copied 64 MiB before declaration-v2) — now share one definition, so
|
|
38
|
+
* they can never drift apart again. */
|
|
39
|
+
export { MAX_UPLOAD_BYTES as MAX_ROUTE_BODY_BYTES };
|
|
30
40
|
/** The body cap a route gets when it declares none: 1 MiB. */
|
|
31
41
|
export declare const DEFAULT_ROUTE_BODY_BYTES: number;
|
|
42
|
+
/** The `fields` form of a route's `rewriteIds` (PB-25a): the DOT PATHS where
|
|
43
|
+
* the response's NEWLY-CREATED session ids sit — ids a creation route mints
|
|
44
|
+
* (`sidechat.start`'s `childId`), which were never in the request and so are
|
|
45
|
+
* invisible to the value deep-scan. Each path walks objects only: segments
|
|
46
|
+
* of `[A-Za-z0-9_-]`, non-empty, no wildcards, no numeric (array-index)
|
|
47
|
+
* segments — array elements stay the value scan's business. */
|
|
48
|
+
export interface BridgeRewriteFields {
|
|
49
|
+
fields: readonly string[];
|
|
50
|
+
}
|
|
51
|
+
/** A route's `rewriteIds` value: `true` — deep-scan the answer for the
|
|
52
|
+
* request's own ids (the 2.4 echo shape) — or the {@link BridgeRewriteFields}
|
|
53
|
+
* object, which adds the position-based rewrite on top. The two are
|
|
54
|
+
* DIFFERENT declarations: each hashes its own way, and an old `true`
|
|
55
|
+
* declaration's digest is bit-for-bit what it always was. */
|
|
56
|
+
export type BridgeRewriteIds = true | BridgeRewriteFields;
|
|
57
|
+
/** Where a bridged route's caller supplies the session id — the `locator`
|
|
58
|
+
* field (declaration-v2). The same three shapes as the adapter core's
|
|
59
|
+
* `AdapterLocator`: `query` names the search parameter; `path-segment`
|
|
60
|
+
* counts segments AFTER the declared path (a `prefix` route's variable
|
|
61
|
+
* part); `json-body` names TOP-LEVEL fields of the parsed JSON request
|
|
62
|
+
* body. A route without a locator keeps the 2.1 behavior: the session id
|
|
63
|
+
* rides the query parameter named `sessionParam`. */
|
|
64
|
+
export type BridgeLocator = {
|
|
65
|
+
in: 'query';
|
|
66
|
+
name: string;
|
|
67
|
+
} | {
|
|
68
|
+
in: 'path-segment';
|
|
69
|
+
index: number;
|
|
70
|
+
} | {
|
|
71
|
+
in: 'json-body';
|
|
72
|
+
fields: string[];
|
|
73
|
+
};
|
|
32
74
|
/** One forwardable route as a plugin declares it. `sessionParam` names the
|
|
33
75
|
* URL query parameter carrying the session id (default `'sessionId'`);
|
|
34
76
|
* `stream` marks routes answered as an event stream rather than one JSON
|
|
@@ -38,7 +80,19 @@ export declare const DEFAULT_ROUTE_BODY_BYTES: number;
|
|
|
38
80
|
* (PB-9) caps the forwarded request body in bytes; omitted means
|
|
39
81
|
* {@link DEFAULT_ROUTE_BODY_BYTES}. `upgrade` (PB-10) marks the route as a
|
|
40
82
|
* WebSocket endpoint carried over the byte tunnel — GET-only, mutually
|
|
41
|
-
* exclusive with `stream`.
|
|
83
|
+
* exclusive with `stream`.
|
|
84
|
+
*
|
|
85
|
+
* The four declaration-v2 fields: `locator` replaces the query-parameter
|
|
86
|
+
* session-id convention with an explicit {@link BridgeLocator} (mutually
|
|
87
|
+
* exclusive with `sessionParam`); `prefix: true` admits the route's
|
|
88
|
+
* variable path tail (sub-paths under `path`) — required for a
|
|
89
|
+
* `path-segment` locator, refused together with `upgrade` for now; `deny:
|
|
90
|
+
* true` marks a route the sub-client refuses to serve from a REMOTE
|
|
91
|
+
* is local-only data); `rewriteIds` asks the sub-client to rewrite
|
|
92
|
+
* real↔virtual session ids inside the JSON it forwards — `true` deep-scans
|
|
93
|
+
* for the request's own ids, `{ fields }` additionally wraps the
|
|
94
|
+
* NEWLY-CREATED ids sitting at the declared positions (PB-25a) — never
|
|
95
|
+
* legal on a `stream` route, whose response is never buffered. */
|
|
42
96
|
export interface BridgeRoute {
|
|
43
97
|
path: string;
|
|
44
98
|
scope: BridgeScope;
|
|
@@ -47,6 +101,10 @@ export interface BridgeRoute {
|
|
|
47
101
|
methods?: readonly string[];
|
|
48
102
|
maxBody?: number;
|
|
49
103
|
upgrade?: boolean;
|
|
104
|
+
locator?: BridgeLocator;
|
|
105
|
+
prefix?: boolean;
|
|
106
|
+
deny?: boolean;
|
|
107
|
+
rewriteIds?: BridgeRewriteIds;
|
|
50
108
|
}
|
|
51
109
|
/** What a plugin hands `zenRemote.bridge(...)` — the raw, unvalidated shape. */
|
|
52
110
|
export interface BridgeDeclaration {
|
|
@@ -59,7 +117,11 @@ export interface BridgeDeclaration {
|
|
|
59
117
|
* explicitly — the distinction is load-bearing for the digest (see the
|
|
60
118
|
* canonical form in {@link normalizeDeclaration}), while consumers read the
|
|
61
119
|
* EFFECTIVE values through {@link routeMethodsOf} / {@link routeMaxBodyOf}
|
|
62
|
-
* / {@link routeUpgradesOf}.
|
|
120
|
+
* / {@link routeUpgradesOf}. The four declaration-v2 fields (`locator`,
|
|
121
|
+
* `prefix`, `deny`, `rewriteIds`) follow the same explicit-only rule, and
|
|
122
|
+
* each carries its own effective reader:
|
|
123
|
+
* {@link routeLocatorOf} / {@link routePrefixOf} / {@link routeDeniesRemoteOf}
|
|
124
|
+
* / {@link routeRewritesIdsOf} / {@link routeRewriteFieldsOf}. */
|
|
63
125
|
export interface NormalizedBridgeRoute {
|
|
64
126
|
path: string;
|
|
65
127
|
scope: BridgeScope;
|
|
@@ -68,6 +130,12 @@ export interface NormalizedBridgeRoute {
|
|
|
68
130
|
methods: string[] | undefined;
|
|
69
131
|
maxBody: number | undefined;
|
|
70
132
|
upgrade: boolean | undefined;
|
|
133
|
+
/** Present only when declared — an ABSENT key (not a `locator: undefined`
|
|
134
|
+
* key) keeps the digest-compatible shape and deep-equality of 2.1 routes. */
|
|
135
|
+
locator?: BridgeLocator;
|
|
136
|
+
prefix?: true;
|
|
137
|
+
deny?: true;
|
|
138
|
+
rewriteIds?: BridgeRewriteIds;
|
|
71
139
|
}
|
|
72
140
|
/** The effective upgrade mark of one normalized route. */
|
|
73
141
|
export declare function routeUpgradesOf(route: NormalizedBridgeRoute): boolean;
|
|
@@ -75,6 +143,26 @@ export declare function routeUpgradesOf(route: NormalizedBridgeRoute): boolean;
|
|
|
75
143
|
export declare function routeMethodsOf(route: NormalizedBridgeRoute): string[];
|
|
76
144
|
/** The effective body cap of one normalized route, in bytes. */
|
|
77
145
|
export declare function routeMaxBodyOf(route: NormalizedBridgeRoute): number;
|
|
146
|
+
/** The effective session-id locator of one normalized route. A route that
|
|
147
|
+
* declared none keeps the 2.1 convention: the session id rides the query
|
|
148
|
+
* parameter named by `sessionParam`. */
|
|
149
|
+
export declare function routeLocatorOf(route: NormalizedBridgeRoute): BridgeLocator;
|
|
150
|
+
/** The effective prefix mark of one normalized route: does the route admit
|
|
151
|
+
* its variable path tail (sub-paths under `path`)? */
|
|
152
|
+
export declare function routePrefixOf(route: NormalizedBridgeRoute): boolean;
|
|
153
|
+
/** The effective remote-deny mark of one normalized route: must this route
|
|
154
|
+
* refuse to serve a REMOTE session (local-only data)? */
|
|
155
|
+
export declare function routeDeniesRemoteOf(route: NormalizedBridgeRoute): boolean;
|
|
156
|
+
/** The effective id-rewrite mark of one normalized route: does the
|
|
157
|
+
* sub-client rewrite real↔virtual session ids while forwarding? Both
|
|
158
|
+
* `rewriteIds` forms enable it (`true` and `{ fields }` alike) — which form
|
|
159
|
+
* decides only whether the POSITION rewrite joins the value scan. */
|
|
160
|
+
export declare function routeRewritesIdsOf(route: NormalizedBridgeRoute): boolean;
|
|
161
|
+
/** The declared field paths of a `{ fields }`-form `rewriteIds` route
|
|
162
|
+
* (PB-25a) — where the response's NEWLY-CREATED session ids sit. `undefined`
|
|
163
|
+
* for a `true` route and for a route without the field: the position
|
|
164
|
+
* rewrite exists only when explicitly declared. */
|
|
165
|
+
export declare function routeRewriteFieldsOf(route: NormalizedBridgeRoute): readonly string[] | undefined;
|
|
78
166
|
/** A declaration after validation: every route field filled, routes sorted
|
|
79
167
|
* by path, and the 16-hex-char digest both ends will compare. */
|
|
80
168
|
export interface NormalizedDeclaration {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-bridge.d.ts","sourceRoot":"","sources":["../../src/plugin-bridge.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plugin-bridge.d.ts","sourceRoot":"","sources":["../../src/plugin-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,9 +9,44 @@
|
|
|
9
9
|
* cannot be served locally (the session lives on the server): the surrogate
|
|
10
10
|
* handler forwards it through `relay.pluginRequest` (PB-3's
|
|
11
11
|
* `relay/v1/plugin`) with the real id restored, and streams the answer
|
|
12
|
-
* back
|
|
12
|
+
* back (PB-21: where the id lives is the route's own declaration — the 2.1
|
|
13
|
+
* query parameter, or a declaration-v2 locator in a prefix route's path
|
|
14
|
+
* segment or the JSON body; the v2 shapes ride the SAME adapter-core
|
|
15
|
+
* locate → classify → rewrite functions the adapters run, and a
|
|
16
|
+
* `prefix: true` route forwards its full matched, rewritten path).
|
|
17
|
+
* Everything else — undeclared routes, local sessions — flows to the
|
|
13
18
|
* original route untouched.
|
|
14
19
|
*
|
|
20
|
+
* PB-22 gives the two remaining declaration-v2 flags their client meaning:
|
|
21
|
+
* a `deny: true` route answers the uniform 503 with reason `route-denied`
|
|
22
|
+
* whenever a REMOTE context touches it — the request locating a virtual id,
|
|
23
|
+
* or the browser's CURRENT session being one (T62's signal) — while a local
|
|
24
|
+
* session passes through exactly as before; a `rewriteIds: true` route's
|
|
25
|
+
* JSON answer is buffered (the 8 MB adapter cap) and deep-scanned, every
|
|
26
|
+
* string EXACTLY equal to one of the request's own real session ids
|
|
27
|
+
* rewritten to its virtual form (`zr~` carries the real id inside, so the
|
|
28
|
+
* request's own hits ARE the read-only mapping — no table is consulted or
|
|
29
|
+
* written), unknown strings passing through untouched.
|
|
30
|
+
*
|
|
31
|
+
* PB-25a adds the position form: `rewriteIds: { fields }` declares the dot
|
|
32
|
+
* paths where the response's NEWLY-CREATED session ids sit (a creation
|
|
33
|
+
* route's `childId` was never in the request, so no value scan can catch
|
|
34
|
+
* it). On top of the value scan, each declared path's non-empty, non-virtual
|
|
35
|
+
* string gains the virtual shell of THIS request's server id; missing paths
|
|
36
|
+
* are no-ops and nothing is ever guessed beyond the declared positions.
|
|
37
|
+
*
|
|
38
|
+
* PB-25b widens the value scan's lookup from the request-local mapping to
|
|
39
|
+
* the request-local mapping UNION the KNOWN-real-session inventory: the
|
|
40
|
+
* merged global streams report every real id the sub-client currently holds
|
|
41
|
+
* (the sidebar's `zr~` rows — subagents.live's object keys, workflows.list
|
|
42
|
+
* rows: ids in the browser's view but not in THIS request), and a string
|
|
43
|
+
* exactly equal to one of those is rewritten too, in the same request-sourced
|
|
44
|
+
* virtual shell. The inventory is READ-ONLY consumption — the scan never
|
|
45
|
+
* touches merge state — and it is read live per answer: a stream refresh
|
|
46
|
+
* replaces its share, and the next answer sees the fresh union (ids that
|
|
47
|
+
* appear between two refreshes wait for the next refresh — the documented
|
|
48
|
+
* ceiling). Without the option the scan is exactly the PB-22 behavior.
|
|
49
|
+
*
|
|
15
50
|
* The un-bridged refusals answer a UNIFORM 503 shape (header
|
|
16
51
|
* `x-zen-remote: unbridged`, JSON body naming the reason) — and, decisive
|
|
17
52
|
* for the security posture, they answer WITHOUT the local plugin handler
|
|
@@ -98,9 +133,23 @@ export interface InstallPluginRouteInterceptOptions {
|
|
|
98
133
|
* read live per call). A VIRTUAL id means a remote session's panel is
|
|
99
134
|
* the request's origin — the signal an adapter route's `deny` hook uses
|
|
100
135
|
* to refuse requests (like better-sidebar's `open.external`) that carry
|
|
101
|
-
* no session field of their own
|
|
102
|
-
*
|
|
136
|
+
* no session field of their own, and (PB-22) the same-origin wall a
|
|
137
|
+
* cooperative route's `deny: true` raises. Absent → deny judges
|
|
138
|
+
* conservatively (only the request's own ids speak). */
|
|
103
139
|
getCurrentSession?: () => string | undefined;
|
|
140
|
+
/** PB-25b: the KNOWN real session ids of this sub-client — the merged
|
|
141
|
+
* global streams' session inventories, unioned by the wiring. Read LIVE
|
|
142
|
+
* per rewriteIds answer, not captured at install: the streams report after
|
|
143
|
+
* the intercept installs, and a stream refresh replaces its share
|
|
144
|
+
* replace-style, so a getter is the only form that sees the fresh union —
|
|
145
|
+
* the same live-read discipline as getServerId/getStatus/getCurrentSession
|
|
146
|
+
* above. A rewriteIds route's value scan rewrites a string exactly equal
|
|
147
|
+
* to a member even when THIS request never carried it (the id already sits
|
|
148
|
+
* in the browser's view — subagents.live's object keys, workflows.list
|
|
149
|
+
* rows), wrapped in THIS request's virtual shell. The set is READ-ONLY
|
|
150
|
+
* consumption: nothing here mutates merge state. Absent → the scan is
|
|
151
|
+
* exactly the request-local PB-22 behavior. */
|
|
152
|
+
getKnownRealIds?: () => ReadonlySet<string>;
|
|
104
153
|
/** Progress logging, wired to the context logger by index.ts. */
|
|
105
154
|
log?: (format: string, ...args: unknown[]) => void;
|
|
106
155
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-route-intercept.d.ts","sourceRoot":"","sources":["../../src/plugin-route-intercept.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"plugin-route-intercept.d.ts","sourceRoot":"","sources":["../../src/plugin-route-intercept.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAGH,OAAO,KAAK,EAAiB,cAAc,EAAE,YAAY,EAAyB,MAAM,oBAAoB,CAAA;AAI5G,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,OAAO,KAAK,EAAE,iBAAiB,EAA8E,MAAM,0BAA0B,CAAA;AAG7I;;;;;4CAK4C;AAC5C,MAAM,MAAM,mBAAmB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAmLjF;wDACwD;AACxD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,mBAAmB,CAS3E;AAED;0EAC0E;AAC1E,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,+BAA+B;IAC9C,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,mBAAmB,CAAA;IAC1B;4BACwB;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAA;IACf,oCAAoC;IACpC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxC;kDAC8C;IAC9C,cAAc,EAAE,wBAAwB,EAAE,CAAA;IAC1C,qCAAqC;IACrC,cAAc,EAAE,MAAM,CAAA;IACtB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,CAAA;IACxB;;oDAEgD;IAChD,uBAAuB,EAAE,MAAM,CAAA;IAC/B,2BAA2B,EAAE,MAAM,CAAA;CACpC;AAED,MAAM,WAAW,kCAAkC;IACjD,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAA;IACjB,wEAAwE;IACxE,QAAQ,EAAE,cAAc,CAAA;IACxB,uEAAuE;IACvE,KAAK,EAAE,WAAW,CAAA;IAClB;;2BAEuB;IACvB,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACrC;qEACiE;IACjE,SAAS,EAAE,MAAM,YAAY,EAAE,CAAA;IAC/B;;0DAEsD;IACtD,QAAQ,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAA;IACvC;;;;;;4DAMwD;IACxD,iBAAiB,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IAC5C;;;;;;;;;;;mDAW+C;IAC/C,eAAe,CAAC,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC,CAAA;IAC3C,iEAAiE;IACjE,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;CACnD;AAED,MAAM,WAAW,0BAA0B;IACzC;4DACwD;IACxD,SAAS,IAAI,IAAI,CAAA;IACjB,WAAW,IAAI,+BAA+B,CAAA;CAC/C;AAkED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,kCAAkC,GAAG,0BAA0B,CAu1CnH"}
|
|
@@ -28,7 +28,10 @@ import type { PluginLoopback } from './plugin-loopback.js';
|
|
|
28
28
|
/** The shared validation verdict for the two plugin routes (PB-3, reused by
|
|
29
29
|
* the tunnel open in PB-10): the whole chain from the coordinate headers to
|
|
30
30
|
* the consent wall, minus each route's own extras (the method check for
|
|
31
|
-
* `v1/plugin`, the upgrade mark here). First failure wins, in this order.
|
|
31
|
+
* `v1/plugin`, the upgrade mark here). First failure wins, in this order.
|
|
32
|
+
* `bufferedBody` carries a json-body route's request bytes (PB-24: the share
|
|
33
|
+
* check must read the located id, so the body is consumed by validating) —
|
|
34
|
+
* the loopback sends THIS buffer, never a re-read of the request. */
|
|
32
35
|
export type PluginCallValidation = {
|
|
33
36
|
ok: true;
|
|
34
37
|
declaration: NormalizedDeclaration;
|
|
@@ -36,16 +39,37 @@ export type PluginCallValidation = {
|
|
|
36
39
|
params: URLSearchParams;
|
|
37
40
|
sessionId: string;
|
|
38
41
|
normalizedQuery: string;
|
|
42
|
+
bufferedBody?: Buffer;
|
|
39
43
|
} | {
|
|
40
44
|
ok: false;
|
|
41
45
|
status: number;
|
|
42
46
|
code: string;
|
|
43
47
|
};
|
|
48
|
+
/** The json-body locator's body reader (PB-24): the caller owns the request
|
|
49
|
+
* stream — `v1/plugin` buffers it bounded by the route's `maxBody` (413 past
|
|
50
|
+
* the cap, mirroring the adapter half's discipline), the tunnel open omits
|
|
51
|
+
* the reader entirely (an open request is empty-bodied by contract, so a
|
|
52
|
+
* body-locating upgrade route can never be validated and refuses). */
|
|
53
|
+
export type PluginCallBodyReader = (maxBody: number) => Promise<{
|
|
54
|
+
kind: 'body';
|
|
55
|
+
buffered: Buffer;
|
|
56
|
+
parsed?: unknown;
|
|
57
|
+
} | {
|
|
58
|
+
kind: 'over';
|
|
59
|
+
} | {
|
|
60
|
+
kind: 'corrupt';
|
|
61
|
+
}>;
|
|
44
62
|
/** Validate one plugin-bridge call's coordinates — the parse-once query
|
|
45
63
|
* discipline (the re-serialization of THIS parse is the only string the
|
|
46
64
|
* tunnel's upgrade request may carry), the share table with its ancestor
|
|
47
65
|
* walk, and the live consent wall. `bridge.getConsent()` throwing reads as
|
|
48
|
-
* unknown consent, and unknown consent stays home.
|
|
66
|
+
* unknown consent, and unknown consent stays home. The share wall reads the
|
|
67
|
+
* route's EFFECTIVE locator (PB-24): the query convention — `sessionParam`
|
|
68
|
+
* folded in by {@link routeLocatorOf} — keeps its exactly-once rule, while a
|
|
69
|
+
* declaration-v2 locator re-locates over the SAME adapter-core rule the
|
|
70
|
+
* sub-client classified with and share-checks EVERY hit; a json-body route's
|
|
71
|
+
* body is consumed by validating (the reader above), and the verdict carries
|
|
72
|
+
* the bytes for the loopback. */
|
|
49
73
|
export declare function validatePluginCall(bridge: {
|
|
50
74
|
registry: BridgeRegistry;
|
|
51
75
|
getConsent: () => Record<string, boolean>;
|
|
@@ -55,7 +79,7 @@ export declare function validatePluginCall(bridge: {
|
|
|
55
79
|
pluginDigest: string;
|
|
56
80
|
routePath: string;
|
|
57
81
|
rawQuery: string;
|
|
58
|
-
}, isAccessible: (sessionId: string) => boolean): PluginCallValidation
|
|
82
|
+
}, isAccessible: (sessionId: string) => boolean, readJsonBody?: PluginCallBodyReader): Promise<PluginCallValidation>;
|
|
59
83
|
/** Largest single downstream data LINE (base64 will inflate by 4/3 — the cap
|
|
60
84
|
* is on the RAW bytes carried, and the line stays well under typical proxy
|
|
61
85
|
* line limits this way). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-tunnel.d.ts","sourceRoot":"","sources":["../../src/plugin-tunnel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"plugin-tunnel.d.ts","sourceRoot":"","sources":["../../src/plugin-tunnel.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,6 +30,7 @@ import type { ShareStore } from './share-store.js';
|
|
|
30
30
|
import type { ServerPluginEntry, BridgeRegistry } from './plugin-bridge.js';
|
|
31
31
|
import { type PluginTunnelRoutes } from './plugin-tunnel.js';
|
|
32
32
|
import type { PluginLoopback } from './plugin-loopback.js';
|
|
33
|
+
import { MAX_UPLOAD_BYTES } from './upload-limits.js';
|
|
33
34
|
import type { NormalizedAdapter } from './plugin-adapter-core.js';
|
|
34
35
|
/**
|
|
35
36
|
* Registration prefix on the host webServer. Deliberately WITHOUT the
|
|
@@ -38,31 +39,7 @@ import type { NormalizedAdapter } from './plugin-adapter-core.js';
|
|
|
38
39
|
* `…/relay//…` shapes and never `…/relay/ping`.
|
|
39
40
|
*/
|
|
40
41
|
export declare const RELAY_PREFIX = "/_dsh/zen-remote/relay";
|
|
41
|
-
|
|
42
|
-
* Body ceiling for the binary upload channel alone (T51): a shared session's
|
|
43
|
-
* non-image file attachments. DSH's own upload route has NO byte cap — the
|
|
44
|
-
* host stores the stream verbatim (`saveFileStreamVerbatim` →
|
|
45
|
-
* `publishImmutableObjectStream`, RT dsh-attachment-local lib/index.js
|
|
46
|
-
* ~699-716; the 20 MiB `maxImageBytes` there covers INLINE images only), so
|
|
47
|
-
* there is no host number to mirror and this relay picks its own: 500 MiB
|
|
48
|
-
* per upload, checked first against `Content-Length` (refused before a byte
|
|
49
|
-
* moves) and then counted while the stream is pumped (a chunked body has no
|
|
50
|
-
* length header — the sub-client's undici forbids hand-set length headers,
|
|
51
|
-
* so the streaming count is the path its uploads normally take). Past the
|
|
52
|
-
* cap the forward is aborted, the rest of the request is drained and the
|
|
53
|
-
* answer is 413 `payload-too-large`.
|
|
54
|
-
*
|
|
55
|
-
* SLOW-LINK BOUND (T51-fix, for the docs): a single legitimate upload is
|
|
56
|
-
* also bounded in TIME. The sub-client's own round-trip budget now caps at
|
|
57
|
-
* 15 minutes (relay-client.ts, the T31-fix rule), but the HOST's HTTP server
|
|
58
|
-
* keeps Node's default 300 s request deadline — that is the binding limit:
|
|
59
|
-
* a 500 MiB body needs roughly 14 Mbps sustained end to end, and a slower
|
|
60
|
-
* link fails the call (the client-side refusal keeps the connection state)
|
|
61
|
-
* rather than hanging. Raising the cap past what that deadline can carry
|
|
62
|
-
* would only move the failure, so 500 MiB is the honest ceiling for the
|
|
63
|
-
* current transport.
|
|
64
|
-
*/
|
|
65
|
-
export declare const MAX_UPLOAD_BYTES: number;
|
|
42
|
+
export { MAX_UPLOAD_BYTES };
|
|
66
43
|
/** The `/api` route the upload channel dispatches into, verbatim from the
|
|
67
44
|
* host's own registration (RT dsh-client-file-upload lib/index.js:73). */
|
|
68
45
|
export declare const UPLOAD_HTTP_PATH = "/api/session/uploadFileBinary";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-server.d.ts","sourceRoot":"","sources":["../../src/relay-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAQH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAWlD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAE3E,OAAO,EAA0C,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACpG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAG1D,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,0BAA0B,CAAA;AAGjF;;;;;GAKG;AACH,eAAO,MAAM,YAAY,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"relay-server.d.ts","sourceRoot":"","sources":["../../src/relay-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one home of every upload/body ceiling this plugin enforces (the
|
|
3
|
+
* upload unification, 2026-10-28). Three paths move bytes through the
|
|
4
|
+
* plugin, each with its own number, and the numbers used to live beside
|
|
5
|
+
* their enforcement sites — where they drifted: the docs still said
|
|
6
|
+
* 100 MiB, the nginx snippet capped at 128m under a 500 MiB relay, and
|
|
7
|
+
* the better-sidebar adapter hand-copied the relay budget (kept in step
|
|
8
|
+
* only by a paired test). Defining them here once makes each number
|
|
9
|
+
* greppable to exactly one place; scripts/check-upload-limits.mjs pins
|
|
10
|
+
* the rest — no second MiB-scale constant definition anywhere in src/,
|
|
11
|
+
* and the docs / nginx snippet stay in sync with MAX_UPLOAD_BYTES.
|
|
12
|
+
*
|
|
13
|
+
* Pure constants, ZERO imports (the virtual-id.ts precedent): the relay
|
|
14
|
+
* server, the phone-upload route, the sub-client's fetch-route intercept,
|
|
15
|
+
* the adapter core and the adapters themselves all import from here — an
|
|
16
|
+
* adapter may only lean on pure utility modules, so anything less pure
|
|
17
|
+
* would have kept the hand-copies alive.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Body ceiling for the binary upload channel alone (T51): a shared session's
|
|
21
|
+
* non-image file attachments. DSH's own upload route has NO byte cap — the
|
|
22
|
+
* host stores the stream verbatim (`saveFileStreamVerbatim` →
|
|
23
|
+
* `publishImmutableObjectStream`, RT dsh-attachment-local lib/index.js
|
|
24
|
+
* ~699-716; the 20 MiB `maxImageBytes` there covers INLINE images only), so
|
|
25
|
+
* there is no host number to mirror and this relay picks its own: 500 MiB
|
|
26
|
+
* per upload, checked first against `Content-Length` (refused before a byte
|
|
27
|
+
* moves) and then counted while the stream is pumped (a chunked body has no
|
|
28
|
+
* length header — the sub-client's undici forbids hand-set length headers,
|
|
29
|
+
* so the streaming count is the path its uploads normally take). Past the
|
|
30
|
+
* cap the forward is aborted, the rest of the request is drained and the
|
|
31
|
+
* answer is 413 `payload-too-large`.
|
|
32
|
+
*
|
|
33
|
+
* SLOW-LINK BOUND (T51-fix, for the docs): a single legitimate upload is
|
|
34
|
+
* also bounded in TIME. The sub-client's own round-trip budget now caps at
|
|
35
|
+
* 15 minutes (relay-client.ts, the T31-fix rule), but the HOST's HTTP server
|
|
36
|
+
* keeps Node's default 300 s request deadline — that is the binding limit:
|
|
37
|
+
* a 500 MiB body needs roughly 14 Mbps sustained end to end, and a slower
|
|
38
|
+
* link fails the call (the client-side refusal keeps the connection state)
|
|
39
|
+
* rather than hanging. Raising the cap past what that deadline can carry
|
|
40
|
+
* would only move the failure, so 500 MiB is the honest ceiling for the
|
|
41
|
+
* current transport.
|
|
42
|
+
*/
|
|
43
|
+
export declare const MAX_UPLOAD_BYTES: number;
|
|
44
|
+
/**
|
|
45
|
+
* Body cap when the plugin row sets no `maxUploadBytes`. This governs ONLY
|
|
46
|
+
* the phone composer's attachment upload (`/_dsh/mobile-nav/upload`) — the
|
|
47
|
+
* remote relay channel reads {@link MAX_UPLOAD_BYTES} and must never be
|
|
48
|
+
* sized from this: `maxUploadBytes` is a user-facing knob for phone picks
|
|
49
|
+
* (default 20 MB), and wiring it into the relay would drop remote
|
|
50
|
+
* attachments from 500 MiB back down to it (a regression the README's
|
|
51
|
+
* 500 MiB promise forbids).
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEFAULT_MAX_UPLOAD_BYTES: number;
|
|
54
|
+
/**
|
|
55
|
+
* Body ceiling for the relay's invoke route alone: the prompt routes carry
|
|
56
|
+
* inline images in their content blocks (`session/prompt` / `subagents/prompt`
|
|
57
|
+
* take base64 `image` parts; DSH admits one image up to 20 MiB by default —
|
|
58
|
+
* `maxImageBytes`, dsh-attachment-local — which base64 inflates to ~27 MiB),
|
|
59
|
+
* so one full-size inline image plus its envelope needs 32 MiB. It is NOT
|
|
60
|
+
* sized for `fileUploads/upload`: the UI's real file uploads ride the HTTP
|
|
61
|
+
* route `api/session/uploadFileBinary` (T41b), not this JSON relay. The
|
|
62
|
+
* buffer only ever grows to the REAL body size; the cap decides
|
|
63
|
+
* accept/refuse, and a body that outgrows it is drained and answered 413
|
|
64
|
+
* like any other oversized read.
|
|
65
|
+
*/
|
|
66
|
+
export declare const MAX_INVOKE_BODY_BYTES: number;
|
|
67
|
+
//# sourceMappingURL=upload-limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-limits.d.ts","sourceRoot":"","sources":["../../src/upload-limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gBAAgB,QAAoB,CAAA;AAEjD;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,QAAmB,CAAA;AAExD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,QAAmB,CAAA"}
|
|
@@ -31,9 +31,10 @@ export interface SnippetInput {
|
|
|
31
31
|
* nginx: a complete server block. The WebSocket upgrade map sits outside
|
|
32
32
|
* the server (http-level context) — the snippet says so in a comment, the
|
|
33
33
|
* user pastes it into the http/server scope their setup offers. Long
|
|
34
|
-
* idle tunnels need the 3600s read/send timeouts, uploads the
|
|
35
|
-
* client body cap
|
|
36
|
-
*
|
|
34
|
+
* idle tunnels need the 3600s read/send timeouts, uploads the 512m
|
|
35
|
+
* client body cap (nginx's `m` is MiB — 512m covers the relay's 500 MiB
|
|
36
|
+
* upload ceiling with headroom), and streaming the buffering switch — all
|
|
37
|
+
* three are the shapes DSH's relay traffic actually needs.
|
|
37
38
|
*/
|
|
38
39
|
export declare function nginxSnippet(input: SnippetInput): SnippetResult;
|
|
39
40
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-snippets.d.ts","sourceRoot":"","sources":["../../../src/wizard/proxy-snippets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,GAAG,mBAAmB,GAAG,mBAAmB,CAAA;CAAE,CAAA;AAElF,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,MAAM,EAAE,OAAO,CAAA;IACf;4BACwB;IACxB,YAAY,EAAE,OAAO,CAAA;IACrB,iCAAiC;IACjC,YAAY,EAAE,OAAO,CAAA;CACtB;AAiBD
|
|
1
|
+
{"version":3,"file":"proxy-snippets.d.ts","sourceRoot":"","sources":["../../../src/wizard/proxy-snippets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,GAAG,mBAAmB,GAAG,mBAAmB,CAAA;CAAE,CAAA;AAElF,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,MAAM,EAAE,OAAO,CAAA;IACf;4BACwB;IACxB,YAAY,EAAE,OAAO,CAAA;IACrB,iCAAiC;IACjC,YAAY,EAAE,OAAO,CAAA;CACtB;AAiBD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAiC/D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CAW/D;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAC7B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,mBAAmB,GAAG,mBAAmB,CAAA;CAAE,CAAA;AAEnE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAAE,YAAY,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,GAAG,WAAW,CAa/F"}
|