@tomflow/proflow-dev-tunnel 0.1.17 → 0.1.19
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/CHANGELOG.md +12 -0
- package/DOCS.md +1 -1
- package/SETUP.md +3 -3
- package/dist/deployment/adapter.d.ts +22 -22
- package/dist/deployment/adapter.js +6 -11
- package/dist/deployment/descriptor.d.ts +1 -1
- package/dist/deployment/descriptor.js +1 -1
- package/dist/src/resource-adapter.js +30 -23
- package/package.json +3 -3
- package/proflow.module.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @tomflow/proflow-dev-tunnel
|
|
2
2
|
|
|
3
|
+
## 0.1.19
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Repack the Deployment Closeout release from freshly rebuilt artifacts and enforce build + publishability before every canonical publish.
|
|
8
|
+
|
|
9
|
+
## 0.1.18
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Harden Deployment Closeout: fail closed on partial installs and package-manager conflicts, normalize Git workspace isolation, make Dev Tunnel status fast and resumable without fabricating login failures, and align Browser Extension setup/conformance behavior.
|
|
14
|
+
|
|
3
15
|
## 0.1.17
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/DOCS.md
CHANGED
package/SETUP.md
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
Responsible: AI
|
|
6
6
|
|
|
7
|
-
Interactive executable: `platform setup
|
|
7
|
+
Interactive executable: `platform setup`
|
|
8
8
|
|
|
9
|
-
Non-interactive executable: `
|
|
9
|
+
Non-interactive executable: `platform setup --workspace <path>`
|
|
10
10
|
|
|
11
11
|
Required inputs: none
|
|
12
12
|
|
|
@@ -25,6 +25,6 @@ Automatic flow:
|
|
|
25
25
|
→ 持久化并发布 tunnelId/publicBaseUrl
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Verify: `
|
|
28
|
+
Verify: `platform status`
|
|
29
29
|
|
|
30
30
|
Success condition: `dev-tunnel.setupStatus=READY`.
|
|
@@ -27,7 +27,7 @@ export declare function createDevTunnelBehaviorAdapter(dependencies?: {
|
|
|
27
27
|
readonly ok: true;
|
|
28
28
|
readonly status: "SUCCEEDED";
|
|
29
29
|
readonly moduleRef: "dev-tunnel";
|
|
30
|
-
readonly moduleVersion: "0.1.
|
|
30
|
+
readonly moduleVersion: "0.1.19";
|
|
31
31
|
};
|
|
32
32
|
observedEffects: never[];
|
|
33
33
|
}>;
|
|
@@ -37,14 +37,14 @@ export declare function createDevTunnelBehaviorAdapter(dependencies?: {
|
|
|
37
37
|
readonly ok: true;
|
|
38
38
|
readonly status: "SUCCEEDED";
|
|
39
39
|
readonly moduleRef: "dev-tunnel";
|
|
40
|
-
readonly moduleVersion: "0.1.
|
|
40
|
+
readonly moduleVersion: "0.1.19";
|
|
41
41
|
};
|
|
42
42
|
observedEffects: string[];
|
|
43
43
|
} | {
|
|
44
44
|
result: {
|
|
45
45
|
contract: "deployment.result.v1";
|
|
46
46
|
moduleRef: "dev-tunnel";
|
|
47
|
-
moduleVersion: "0.1.
|
|
47
|
+
moduleVersion: "0.1.19";
|
|
48
48
|
ok: false;
|
|
49
49
|
status: "FAILED";
|
|
50
50
|
error: {
|
|
@@ -61,7 +61,7 @@ export declare function createDevTunnelBehaviorAdapter(dependencies?: {
|
|
|
61
61
|
ok: true;
|
|
62
62
|
status: "SUCCEEDED";
|
|
63
63
|
moduleRef: "dev-tunnel";
|
|
64
|
-
moduleVersion: "0.1.
|
|
64
|
+
moduleVersion: "0.1.19";
|
|
65
65
|
data: {
|
|
66
66
|
setupStatus: "ACTION_REQUIRED" | "READY";
|
|
67
67
|
runtimeStatus: "FAILED" | "RUNNING" | "STOPPED";
|
|
@@ -88,7 +88,7 @@ export declare function createDevTunnelBehaviorAdapter(dependencies?: {
|
|
|
88
88
|
ok: true;
|
|
89
89
|
status: "SUCCEEDED";
|
|
90
90
|
moduleRef: "dev-tunnel";
|
|
91
|
-
moduleVersion: "0.1.
|
|
91
|
+
moduleVersion: "0.1.19";
|
|
92
92
|
data: {
|
|
93
93
|
docs: string;
|
|
94
94
|
};
|
|
@@ -99,7 +99,7 @@ export declare function createDevTunnelBehaviorAdapter(dependencies?: {
|
|
|
99
99
|
result: {
|
|
100
100
|
contract: "deployment.result.v1";
|
|
101
101
|
moduleRef: "dev-tunnel";
|
|
102
|
-
moduleVersion: "0.1.
|
|
102
|
+
moduleVersion: "0.1.19";
|
|
103
103
|
ok: false;
|
|
104
104
|
status: "FAILED";
|
|
105
105
|
error: {
|
|
@@ -115,7 +115,7 @@ export declare function createDevTunnelBehaviorAdapter(dependencies?: {
|
|
|
115
115
|
ok: true;
|
|
116
116
|
status: "SUCCEEDED";
|
|
117
117
|
moduleRef: "dev-tunnel";
|
|
118
|
-
moduleVersion: "0.1.
|
|
118
|
+
moduleVersion: "0.1.19";
|
|
119
119
|
data: import("../src/resource-adapter.ts").DevTunnelObservation;
|
|
120
120
|
};
|
|
121
121
|
observedEffects: string[];
|
|
@@ -126,14 +126,14 @@ export declare function createDevTunnelBehaviorAdapter(dependencies?: {
|
|
|
126
126
|
readonly ok: true;
|
|
127
127
|
readonly status: "SUCCEEDED";
|
|
128
128
|
readonly moduleRef: "dev-tunnel";
|
|
129
|
-
readonly moduleVersion: "0.1.
|
|
129
|
+
readonly moduleVersion: "0.1.19";
|
|
130
130
|
};
|
|
131
131
|
observedEffects: string[];
|
|
132
132
|
} | {
|
|
133
133
|
result: {
|
|
134
134
|
contract: "deployment.result.v1";
|
|
135
135
|
moduleRef: "dev-tunnel";
|
|
136
|
-
moduleVersion: "0.1.
|
|
136
|
+
moduleVersion: "0.1.19";
|
|
137
137
|
ok: false;
|
|
138
138
|
status: "FAILED";
|
|
139
139
|
error: {
|
|
@@ -148,7 +148,7 @@ export declare function createDevTunnelBehaviorAdapter(dependencies?: {
|
|
|
148
148
|
result: {
|
|
149
149
|
contract: "deployment.result.v1";
|
|
150
150
|
moduleRef: "dev-tunnel";
|
|
151
|
-
moduleVersion: "0.1.
|
|
151
|
+
moduleVersion: "0.1.19";
|
|
152
152
|
ok: false;
|
|
153
153
|
status: "FAILED";
|
|
154
154
|
error: {
|
|
@@ -164,7 +164,7 @@ export declare function createDevTunnelBehaviorAdapter(dependencies?: {
|
|
|
164
164
|
ok: true;
|
|
165
165
|
status: "SUCCEEDED";
|
|
166
166
|
moduleRef: "dev-tunnel";
|
|
167
|
-
moduleVersion: "0.1.
|
|
167
|
+
moduleVersion: "0.1.19";
|
|
168
168
|
data: SetupState;
|
|
169
169
|
};
|
|
170
170
|
observedEffects: string[];
|
|
@@ -177,7 +177,7 @@ export declare const behaviorAdapter: {
|
|
|
177
177
|
readonly ok: true;
|
|
178
178
|
readonly status: "SUCCEEDED";
|
|
179
179
|
readonly moduleRef: "dev-tunnel";
|
|
180
|
-
readonly moduleVersion: "0.1.
|
|
180
|
+
readonly moduleVersion: "0.1.19";
|
|
181
181
|
};
|
|
182
182
|
observedEffects: never[];
|
|
183
183
|
}>;
|
|
@@ -187,14 +187,14 @@ export declare const behaviorAdapter: {
|
|
|
187
187
|
readonly ok: true;
|
|
188
188
|
readonly status: "SUCCEEDED";
|
|
189
189
|
readonly moduleRef: "dev-tunnel";
|
|
190
|
-
readonly moduleVersion: "0.1.
|
|
190
|
+
readonly moduleVersion: "0.1.19";
|
|
191
191
|
};
|
|
192
192
|
observedEffects: string[];
|
|
193
193
|
} | {
|
|
194
194
|
result: {
|
|
195
195
|
contract: "deployment.result.v1";
|
|
196
196
|
moduleRef: "dev-tunnel";
|
|
197
|
-
moduleVersion: "0.1.
|
|
197
|
+
moduleVersion: "0.1.19";
|
|
198
198
|
ok: false;
|
|
199
199
|
status: "FAILED";
|
|
200
200
|
error: {
|
|
@@ -211,7 +211,7 @@ export declare const behaviorAdapter: {
|
|
|
211
211
|
ok: true;
|
|
212
212
|
status: "SUCCEEDED";
|
|
213
213
|
moduleRef: "dev-tunnel";
|
|
214
|
-
moduleVersion: "0.1.
|
|
214
|
+
moduleVersion: "0.1.19";
|
|
215
215
|
data: {
|
|
216
216
|
setupStatus: "ACTION_REQUIRED" | "READY";
|
|
217
217
|
runtimeStatus: "FAILED" | "RUNNING" | "STOPPED";
|
|
@@ -238,7 +238,7 @@ export declare const behaviorAdapter: {
|
|
|
238
238
|
ok: true;
|
|
239
239
|
status: "SUCCEEDED";
|
|
240
240
|
moduleRef: "dev-tunnel";
|
|
241
|
-
moduleVersion: "0.1.
|
|
241
|
+
moduleVersion: "0.1.19";
|
|
242
242
|
data: {
|
|
243
243
|
docs: string;
|
|
244
244
|
};
|
|
@@ -249,7 +249,7 @@ export declare const behaviorAdapter: {
|
|
|
249
249
|
result: {
|
|
250
250
|
contract: "deployment.result.v1";
|
|
251
251
|
moduleRef: "dev-tunnel";
|
|
252
|
-
moduleVersion: "0.1.
|
|
252
|
+
moduleVersion: "0.1.19";
|
|
253
253
|
ok: false;
|
|
254
254
|
status: "FAILED";
|
|
255
255
|
error: {
|
|
@@ -265,7 +265,7 @@ export declare const behaviorAdapter: {
|
|
|
265
265
|
ok: true;
|
|
266
266
|
status: "SUCCEEDED";
|
|
267
267
|
moduleRef: "dev-tunnel";
|
|
268
|
-
moduleVersion: "0.1.
|
|
268
|
+
moduleVersion: "0.1.19";
|
|
269
269
|
data: import("../src/resource-adapter.ts").DevTunnelObservation;
|
|
270
270
|
};
|
|
271
271
|
observedEffects: string[];
|
|
@@ -276,14 +276,14 @@ export declare const behaviorAdapter: {
|
|
|
276
276
|
readonly ok: true;
|
|
277
277
|
readonly status: "SUCCEEDED";
|
|
278
278
|
readonly moduleRef: "dev-tunnel";
|
|
279
|
-
readonly moduleVersion: "0.1.
|
|
279
|
+
readonly moduleVersion: "0.1.19";
|
|
280
280
|
};
|
|
281
281
|
observedEffects: string[];
|
|
282
282
|
} | {
|
|
283
283
|
result: {
|
|
284
284
|
contract: "deployment.result.v1";
|
|
285
285
|
moduleRef: "dev-tunnel";
|
|
286
|
-
moduleVersion: "0.1.
|
|
286
|
+
moduleVersion: "0.1.19";
|
|
287
287
|
ok: false;
|
|
288
288
|
status: "FAILED";
|
|
289
289
|
error: {
|
|
@@ -298,7 +298,7 @@ export declare const behaviorAdapter: {
|
|
|
298
298
|
result: {
|
|
299
299
|
contract: "deployment.result.v1";
|
|
300
300
|
moduleRef: "dev-tunnel";
|
|
301
|
-
moduleVersion: "0.1.
|
|
301
|
+
moduleVersion: "0.1.19";
|
|
302
302
|
ok: false;
|
|
303
303
|
status: "FAILED";
|
|
304
304
|
error: {
|
|
@@ -314,7 +314,7 @@ export declare const behaviorAdapter: {
|
|
|
314
314
|
ok: true;
|
|
315
315
|
status: "SUCCEEDED";
|
|
316
316
|
moduleRef: "dev-tunnel";
|
|
317
|
-
moduleVersion: "0.1.
|
|
317
|
+
moduleVersion: "0.1.19";
|
|
318
318
|
data: SetupState;
|
|
319
319
|
};
|
|
320
320
|
observedEffects: string[];
|
|
@@ -150,7 +150,7 @@ const baseBehaviorAdapter = {
|
|
|
150
150
|
code: "TUNNEL_SETUP_REQUIRED",
|
|
151
151
|
message: "尚未完成持久 Tunnel 自动配置",
|
|
152
152
|
relatedModuleRefs: [],
|
|
153
|
-
nextCommand: "platform setup
|
|
153
|
+
nextCommand: "platform setup",
|
|
154
154
|
},
|
|
155
155
|
],
|
|
156
156
|
},
|
|
@@ -159,11 +159,8 @@ const baseBehaviorAdapter = {
|
|
|
159
159
|
};
|
|
160
160
|
}
|
|
161
161
|
const rt = runtime(context, state);
|
|
162
|
-
const login = await rt.loginStatus();
|
|
163
162
|
const observed = await rt.status();
|
|
164
|
-
const configured = state
|
|
165
|
-
typeof state.publicBaseUrl === "string" &&
|
|
166
|
-
login === "LOGGED_IN";
|
|
163
|
+
const configured = state.phase === "READY" && typeof state.publicBaseUrl === "string";
|
|
167
164
|
const runtimeStatus = observed.state === "RUNNING"
|
|
168
165
|
? "RUNNING"
|
|
169
166
|
: observed.state === "STOPPED"
|
|
@@ -186,12 +183,10 @@ const baseBehaviorAdapter = {
|
|
|
186
183
|
? [
|
|
187
184
|
{
|
|
188
185
|
scope: "SETUP",
|
|
189
|
-
code: "
|
|
190
|
-
message:
|
|
191
|
-
? `远程连接配置已保存,当前阶段 ${state.phase};重新运行 Platform setup 将从此处恢复`
|
|
192
|
-
: "Dev Tunnel CLI 尚未登录或配置未保存",
|
|
186
|
+
code: "TUNNEL_SETUP_INCOMPLETE",
|
|
187
|
+
message: `远程连接配置已保存,当前阶段 ${state.phase};重新运行 Platform setup 将从此处恢复`,
|
|
193
188
|
relatedModuleRefs: [],
|
|
194
|
-
nextCommand: "platform setup
|
|
189
|
+
nextCommand: "platform setup",
|
|
195
190
|
},
|
|
196
191
|
]
|
|
197
192
|
: []),
|
|
@@ -202,7 +197,7 @@ const baseBehaviorAdapter = {
|
|
|
202
197
|
code: "TUNNEL_RUNTIME_FAILED",
|
|
203
198
|
message: "Tunnel 运行状态检查失败",
|
|
204
199
|
relatedModuleRefs: [],
|
|
205
|
-
nextCommand: "
|
|
200
|
+
nextCommand: "platform status",
|
|
206
201
|
},
|
|
207
202
|
]
|
|
208
203
|
: []),
|
|
@@ -3,7 +3,7 @@ export declare const descriptor: {
|
|
|
3
3
|
readonly contractVersion: "1.0.0";
|
|
4
4
|
readonly moduleRef: "dev-tunnel";
|
|
5
5
|
readonly packageName: "@tomflow/proflow-dev-tunnel";
|
|
6
|
-
readonly moduleVersion: "0.1.
|
|
6
|
+
readonly moduleVersion: "0.1.19";
|
|
7
7
|
readonly kind: "external-resource";
|
|
8
8
|
readonly templateVersion: "1.0.0";
|
|
9
9
|
readonly platformCompatibility: ">=1.0.0 <2.0.0";
|
|
@@ -3,7 +3,7 @@ export const descriptor = {
|
|
|
3
3
|
contractVersion: "1.0.0",
|
|
4
4
|
moduleRef: "dev-tunnel",
|
|
5
5
|
packageName: "@tomflow/proflow-dev-tunnel",
|
|
6
|
-
moduleVersion: "0.1.
|
|
6
|
+
moduleVersion: "0.1.19",
|
|
7
7
|
kind: "external-resource",
|
|
8
8
|
templateVersion: "1.0.0",
|
|
9
9
|
platformCompatibility: ">=1.0.0 <2.0.0",
|
|
@@ -10,7 +10,17 @@ const START_CONFIRM_MS = 500;
|
|
|
10
10
|
function defaultCommandRunner(command, args, options) {
|
|
11
11
|
if (options?.interactive) {
|
|
12
12
|
return new Promise((resolve) => {
|
|
13
|
-
const child = spawn(command, args, {
|
|
13
|
+
const child = spawn(command, args, {
|
|
14
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
15
|
+
});
|
|
16
|
+
let stdout = "";
|
|
17
|
+
let stderr = "";
|
|
18
|
+
child.stdout?.on("data", (chunk) => {
|
|
19
|
+
stdout += chunk.toString();
|
|
20
|
+
});
|
|
21
|
+
child.stderr?.on("data", (chunk) => {
|
|
22
|
+
stderr += chunk.toString();
|
|
23
|
+
});
|
|
14
24
|
let timedOut = false;
|
|
15
25
|
const timer = setTimeout(() => {
|
|
16
26
|
timedOut = true;
|
|
@@ -18,14 +28,14 @@ function defaultCommandRunner(command, args, options) {
|
|
|
18
28
|
}, options.timeoutMs ?? 600_000);
|
|
19
29
|
child.once("error", (error) => {
|
|
20
30
|
clearTimeout(timer);
|
|
21
|
-
resolve({ exitCode: null, stdout
|
|
31
|
+
resolve({ exitCode: null, stdout, stderr: error.message });
|
|
22
32
|
});
|
|
23
33
|
child.once("exit", (code) => {
|
|
24
34
|
clearTimeout(timer);
|
|
25
35
|
resolve({
|
|
26
36
|
exitCode: timedOut ? null : code,
|
|
27
|
-
stdout
|
|
28
|
-
stderr: timedOut ? "command timed out" :
|
|
37
|
+
stdout,
|
|
38
|
+
stderr: timedOut ? "command timed out" : stderr,
|
|
29
39
|
});
|
|
30
40
|
});
|
|
31
41
|
});
|
|
@@ -394,14 +404,11 @@ export function createDevTunnelRuntime(input) {
|
|
|
394
404
|
return "UNKNOWN";
|
|
395
405
|
}
|
|
396
406
|
};
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
...(publicBaseUrl === undefined ? {} : { publicBaseUrl }),
|
|
403
|
-
};
|
|
404
|
-
};
|
|
407
|
+
const observation = (state, login = "UNKNOWN") => ({
|
|
408
|
+
state,
|
|
409
|
+
login,
|
|
410
|
+
...(publicBaseUrl === undefined ? {} : { publicBaseUrl }),
|
|
411
|
+
});
|
|
405
412
|
const ownedPersistedPid = async () => {
|
|
406
413
|
if (!processStateFile || !tunnelId)
|
|
407
414
|
return undefined;
|
|
@@ -417,24 +424,24 @@ export function createDevTunnelRuntime(input) {
|
|
|
417
424
|
command,
|
|
418
425
|
async status() {
|
|
419
426
|
if (await ownedPersistedPid())
|
|
420
|
-
return
|
|
427
|
+
return observation("RUNNING");
|
|
421
428
|
if (child?.pid && processAlive(child.pid))
|
|
422
|
-
return
|
|
423
|
-
return
|
|
429
|
+
return observation("RUNNING");
|
|
430
|
+
return observation("UNKNOWN");
|
|
424
431
|
},
|
|
425
432
|
loginStatus: () => observeLogin(),
|
|
426
433
|
publicBaseUrl: () => publicBaseUrl,
|
|
427
434
|
async start() {
|
|
428
435
|
const login = await observeLogin();
|
|
429
436
|
if (login !== "LOGGED_IN")
|
|
430
|
-
return
|
|
437
|
+
return observation("UNKNOWN", login);
|
|
431
438
|
if (tunnelId === undefined) {
|
|
432
439
|
throw new TypeError("tunnelId is required to host the configured persistent tunnel");
|
|
433
440
|
}
|
|
434
441
|
if (await ownedPersistedPid())
|
|
435
|
-
return
|
|
442
|
+
return observation("RUNNING", login);
|
|
436
443
|
if (child?.pid && processAlive(child.pid))
|
|
437
|
-
return
|
|
444
|
+
return observation("RUNNING", login);
|
|
438
445
|
const spawned = spawn(command, ["host", tunnelId], {
|
|
439
446
|
stdio: "ignore",
|
|
440
447
|
detached: true,
|
|
@@ -483,7 +490,7 @@ export function createDevTunnelRuntime(input) {
|
|
|
483
490
|
}
|
|
484
491
|
}
|
|
485
492
|
spawned.unref();
|
|
486
|
-
return
|
|
493
|
+
return observation("RUNNING", login);
|
|
487
494
|
},
|
|
488
495
|
async stop() {
|
|
489
496
|
const persistedPid = await ownedPersistedPid();
|
|
@@ -492,20 +499,20 @@ export function createDevTunnelRuntime(input) {
|
|
|
492
499
|
if (processStateFile)
|
|
493
500
|
await rm(processStateFile, { force: true });
|
|
494
501
|
child = undefined;
|
|
495
|
-
return
|
|
502
|
+
return observation("STOPPED");
|
|
496
503
|
}
|
|
497
504
|
try {
|
|
498
505
|
process.kill(pid, "SIGTERM");
|
|
499
506
|
}
|
|
500
507
|
catch {
|
|
501
|
-
return
|
|
508
|
+
return observation("UNKNOWN");
|
|
502
509
|
}
|
|
503
510
|
if (!(await waitForProcessExit(pid)))
|
|
504
|
-
return
|
|
511
|
+
return observation("UNKNOWN");
|
|
505
512
|
if (processStateFile)
|
|
506
513
|
await rm(processStateFile, { force: true });
|
|
507
514
|
child = undefined;
|
|
508
|
-
return
|
|
515
|
+
return observation("STOPPED");
|
|
509
516
|
},
|
|
510
517
|
async restart() {
|
|
511
518
|
const stopped = await this.stop();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomflow/proflow-dev-tunnel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"zod": "4.1.12",
|
|
26
|
-
"@tomflow/proflow-
|
|
27
|
-
"@tomflow/proflow-
|
|
26
|
+
"@tomflow/proflow-devtunnel-cli": "^0.1.0",
|
|
27
|
+
"@tomflow/proflow-module-contract": "^0.1.13"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@tomflow/proflow-deployment-conformance": "^0.1.13"
|
package/proflow.module.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"contractVersion": "1.0.0",
|
|
4
4
|
"moduleRef": "dev-tunnel",
|
|
5
5
|
"packageName": "@tomflow/proflow-dev-tunnel",
|
|
6
|
-
"moduleVersion": "0.1.
|
|
6
|
+
"moduleVersion": "0.1.19",
|
|
7
7
|
"kind": "external-resource",
|
|
8
8
|
"templateVersion": "1.0.0",
|
|
9
9
|
"platformCompatibility": ">=1.0.0 <2.0.0",
|