yap2app 1.1.8 → 1.1.9
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/bin/cli.bundle.js +11 -95
- package/bin/cli.js +11 -95
- package/bridge.js +9 -96
- package/package.json +1 -1
package/bin/cli.bundle.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
#!/usr/bin/env node
|
|
2
3
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
3
4
|
var __create = Object.create;
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
@@ -3552,7 +3553,7 @@ var require_schemes = __commonJS({
|
|
|
3552
3553
|
serialize: httpSerialize
|
|
3553
3554
|
}
|
|
3554
3555
|
);
|
|
3555
|
-
var
|
|
3556
|
+
var https = (
|
|
3556
3557
|
/** @type {SchemeHandler} */
|
|
3557
3558
|
{
|
|
3558
3559
|
scheme: "https",
|
|
@@ -3601,7 +3602,7 @@ var require_schemes = __commonJS({
|
|
|
3601
3602
|
/** @type {Record<SchemeName, SchemeHandler>} */
|
|
3602
3603
|
{
|
|
3603
3604
|
http: http2,
|
|
3604
|
-
https
|
|
3605
|
+
https,
|
|
3605
3606
|
ws,
|
|
3606
3607
|
wss,
|
|
3607
3608
|
urn,
|
|
@@ -7026,7 +7027,6 @@ if (!Promise.allSettled) {
|
|
|
7026
7027
|
|
|
7027
7028
|
// bridge.js
|
|
7028
7029
|
import http from "http";
|
|
7029
|
-
import https from "https";
|
|
7030
7030
|
import fsSync2 from "fs";
|
|
7031
7031
|
import path2 from "path";
|
|
7032
7032
|
import util2 from "util";
|
|
@@ -7580,9 +7580,8 @@ var fs2 = fsSync2.promises || {
|
|
|
7580
7580
|
};
|
|
7581
7581
|
var PORT = Number(process.env.YAP2APP_PORT) || 10420;
|
|
7582
7582
|
var PROJECT_ROOT = process.cwd();
|
|
7583
|
-
var
|
|
7584
|
-
var
|
|
7585
|
-
var CLI_VERSION = "1.1.8";
|
|
7583
|
+
var PAIR_CODE = (process.env.YAP2APP_PAIR_CODE || "Y2A-" + Math.floor(1e3 + Math.random() * 9e3)).toUpperCase();
|
|
7584
|
+
var CLI_VERSION = "1.1.9";
|
|
7586
7585
|
function safeResolvePath(baseDir, relativePath) {
|
|
7587
7586
|
const cleanRel = (relativePath || "").replace(/^[\\\/]+/, "");
|
|
7588
7587
|
const resolved = path2.resolve(baseDir, cleanRel);
|
|
@@ -7592,45 +7591,6 @@ function safeResolvePath(baseDir, relativePath) {
|
|
|
7592
7591
|
}
|
|
7593
7592
|
return resolved;
|
|
7594
7593
|
}
|
|
7595
|
-
function sendCloudRelayRequest(method, endpoint, payload) {
|
|
7596
|
-
return new Promise((resolve) => {
|
|
7597
|
-
try {
|
|
7598
|
-
const url = new URL(`${CLOUD_RELAY_URL}${endpoint}`);
|
|
7599
|
-
const body = payload ? JSON.stringify(payload) : "";
|
|
7600
|
-
const req = https.request({
|
|
7601
|
-
hostname: url.hostname,
|
|
7602
|
-
port: 443,
|
|
7603
|
-
path: url.pathname + url.search,
|
|
7604
|
-
method,
|
|
7605
|
-
headers: {
|
|
7606
|
-
"Content-Type": "application/json",
|
|
7607
|
-
"Content-Length": Buffer.byteLength(body),
|
|
7608
|
-
"User-Agent": `yap2app-cli/${CLI_VERSION}`
|
|
7609
|
-
},
|
|
7610
|
-
timeout: 6e3
|
|
7611
|
-
}, (res) => {
|
|
7612
|
-
let respData = "";
|
|
7613
|
-
res.on("data", (chunk) => respData += chunk);
|
|
7614
|
-
res.on("end", () => {
|
|
7615
|
-
try {
|
|
7616
|
-
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, status: res.statusCode, data: JSON.parse(respData || "{}") });
|
|
7617
|
-
} catch {
|
|
7618
|
-
resolve({ ok: false, status: res.statusCode, data: null });
|
|
7619
|
-
}
|
|
7620
|
-
});
|
|
7621
|
-
});
|
|
7622
|
-
req.on("error", () => resolve({ ok: false, status: 0, data: null }));
|
|
7623
|
-
req.on("timeout", () => {
|
|
7624
|
-
req.destroy();
|
|
7625
|
-
resolve({ ok: false, status: 0, data: null });
|
|
7626
|
-
});
|
|
7627
|
-
if (body) req.write(body);
|
|
7628
|
-
req.end();
|
|
7629
|
-
} catch {
|
|
7630
|
-
resolve({ ok: false, status: 0, data: null });
|
|
7631
|
-
}
|
|
7632
|
-
});
|
|
7633
|
-
}
|
|
7634
7594
|
function getCorsHeaders(req) {
|
|
7635
7595
|
const origin = req?.headers?.origin || "*";
|
|
7636
7596
|
const requestedHeaders = req?.headers?.["access-control-request-headers"] || "*";
|
|
@@ -7800,11 +7760,10 @@ server.on("error", (err) => {
|
|
|
7800
7760
|
if (err && err.code === "EADDRINUSE") {
|
|
7801
7761
|
console.log(`
|
|
7802
7762
|
---------------------------------------------------------------`);
|
|
7803
|
-
console.log(`Yap2App Bridge`);
|
|
7804
|
-
console.log(`
|
|
7763
|
+
console.log(`Yap2App Local Bridge v${CLI_VERSION}`);
|
|
7764
|
+
console.log(`Local Endpoint: http://127.0.0.1:${PORT}`);
|
|
7805
7765
|
console.log(`Active Workspace: ${PROJECT_ROOT}`);
|
|
7806
|
-
console.log(`
|
|
7807
|
-
console.log(`Web Studio: ${CLOUD_RELAY_URL}`);
|
|
7766
|
+
console.log(`Status: Already active & ready on port ${PORT}`);
|
|
7808
7767
|
console.log(`---------------------------------------------------------------
|
|
7809
7768
|
`);
|
|
7810
7769
|
console.log(`Bridge is running.`);
|
|
@@ -7819,15 +7778,14 @@ async function startBridge(port = PORT) {
|
|
|
7819
7778
|
server.listen(port, "0.0.0.0", () => {
|
|
7820
7779
|
console.log(`
|
|
7821
7780
|
---------------------------------------------------------------`);
|
|
7822
|
-
console.log(`Yap2App Bridge v${CLI_VERSION}`);
|
|
7781
|
+
console.log(`Yap2App Local Bridge v${CLI_VERSION}`);
|
|
7823
7782
|
console.log(`Local Endpoint: http://127.0.0.1:${port}`);
|
|
7824
7783
|
console.log(`Active Workspace: ${PROJECT_ROOT}`);
|
|
7825
|
-
console.log(`
|
|
7826
|
-
console.log(`Web Studio: ${CLOUD_RELAY_URL}`);
|
|
7784
|
+
console.log(`Web Studio: https://yap2app-dot-cybage-hackathon.uc.r.appspot.com`);
|
|
7827
7785
|
console.log(`---------------------------------------------------------------
|
|
7828
7786
|
`);
|
|
7829
7787
|
console.log(`Bridge is running.`);
|
|
7830
|
-
console.log(`Open Web Studio in your browser to
|
|
7788
|
+
console.log(`Open Web Studio in your browser to automatically connect and sync.`);
|
|
7831
7789
|
console.log(`Press Ctrl/Cmd+C to stop.
|
|
7832
7790
|
`);
|
|
7833
7791
|
});
|
|
@@ -7838,50 +7796,8 @@ async function startBridge(port = PORT) {
|
|
|
7838
7796
|
console.log(` Yap2App will automatically scaffold directories and write files when synced from Web Studio.
|
|
7839
7797
|
`);
|
|
7840
7798
|
}
|
|
7841
|
-
await sendCloudRelayRequest("POST", "/api/v1/bridge/heartbeat", {
|
|
7842
|
-
pair_code: PAIR_CODE,
|
|
7843
|
-
project_name: path2.basename(PROJECT_ROOT),
|
|
7844
|
-
project_root: PROJECT_ROOT,
|
|
7845
|
-
framework: initialContext.framework,
|
|
7846
|
-
context: initialContext,
|
|
7847
|
-
version: CLI_VERSION
|
|
7848
|
-
});
|
|
7849
7799
|
} catch (e) {
|
|
7850
7800
|
}
|
|
7851
|
-
setInterval(async () => {
|
|
7852
|
-
try {
|
|
7853
|
-
const context = await scanCodebase(PROJECT_ROOT);
|
|
7854
|
-
const hbResult = await sendCloudRelayRequest("POST", "/api/v1/bridge/heartbeat", {
|
|
7855
|
-
pair_code: PAIR_CODE,
|
|
7856
|
-
project_name: path2.basename(PROJECT_ROOT),
|
|
7857
|
-
project_root: PROJECT_ROOT,
|
|
7858
|
-
framework: context.framework,
|
|
7859
|
-
context,
|
|
7860
|
-
version: CLI_VERSION
|
|
7861
|
-
});
|
|
7862
|
-
if (hbResult && hbResult.data && hbResult.data.pending_writes_count > 0) {
|
|
7863
|
-
const pollResult = await sendCloudRelayRequest("GET", `/api/v1/bridge/poll-writes?pair_code=${PAIR_CODE}`);
|
|
7864
|
-
const tasks = pollResult.data && pollResult.data.pending_tasks || [];
|
|
7865
|
-
for (const task of tasks) {
|
|
7866
|
-
const written = [];
|
|
7867
|
-
for (const file of task.files || []) {
|
|
7868
|
-
const fullPath = safeResolvePath(PROJECT_ROOT, file.path);
|
|
7869
|
-
await fs2.mkdir(path2.dirname(fullPath), { recursive: true });
|
|
7870
|
-
await fs2.writeFile(fullPath, file.content, "utf8");
|
|
7871
|
-
console.log(` [bridge] Wrote ${file.path}`);
|
|
7872
|
-
written.push(file.path);
|
|
7873
|
-
}
|
|
7874
|
-
await sendCloudRelayRequest("POST", "/api/v1/bridge/complete-write", {
|
|
7875
|
-
task_id: task.task_id,
|
|
7876
|
-
success: true,
|
|
7877
|
-
written,
|
|
7878
|
-
message: `Wrote ${written.length} file(s) directly to ${path2.basename(PROJECT_ROOT)}`
|
|
7879
|
-
});
|
|
7880
|
-
}
|
|
7881
|
-
}
|
|
7882
|
-
} catch {
|
|
7883
|
-
}
|
|
7884
|
-
}, 3500);
|
|
7885
7801
|
}
|
|
7886
7802
|
var isDirectRun = Boolean(typeof process !== "undefined" && process.argv && process.argv[1] && (process.argv[1].endsWith("bridge.js") || process.argv[1].endsWith("bridge")));
|
|
7887
7803
|
if (isDirectRun) {
|
package/bin/cli.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
#!/usr/bin/env node
|
|
2
3
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
3
4
|
var __create = Object.create;
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
@@ -3552,7 +3553,7 @@ var require_schemes = __commonJS({
|
|
|
3552
3553
|
serialize: httpSerialize
|
|
3553
3554
|
}
|
|
3554
3555
|
);
|
|
3555
|
-
var
|
|
3556
|
+
var https = (
|
|
3556
3557
|
/** @type {SchemeHandler} */
|
|
3557
3558
|
{
|
|
3558
3559
|
scheme: "https",
|
|
@@ -3601,7 +3602,7 @@ var require_schemes = __commonJS({
|
|
|
3601
3602
|
/** @type {Record<SchemeName, SchemeHandler>} */
|
|
3602
3603
|
{
|
|
3603
3604
|
http: http2,
|
|
3604
|
-
https
|
|
3605
|
+
https,
|
|
3605
3606
|
ws,
|
|
3606
3607
|
wss,
|
|
3607
3608
|
urn,
|
|
@@ -7026,7 +7027,6 @@ if (!Promise.allSettled) {
|
|
|
7026
7027
|
|
|
7027
7028
|
// bridge.js
|
|
7028
7029
|
import http from "http";
|
|
7029
|
-
import https from "https";
|
|
7030
7030
|
import fsSync2 from "fs";
|
|
7031
7031
|
import path2 from "path";
|
|
7032
7032
|
import util2 from "util";
|
|
@@ -7580,9 +7580,8 @@ var fs2 = fsSync2.promises || {
|
|
|
7580
7580
|
};
|
|
7581
7581
|
var PORT = Number(process.env.YAP2APP_PORT) || 10420;
|
|
7582
7582
|
var PROJECT_ROOT = process.cwd();
|
|
7583
|
-
var
|
|
7584
|
-
var
|
|
7585
|
-
var CLI_VERSION = "1.1.8";
|
|
7583
|
+
var PAIR_CODE = (process.env.YAP2APP_PAIR_CODE || "Y2A-" + Math.floor(1e3 + Math.random() * 9e3)).toUpperCase();
|
|
7584
|
+
var CLI_VERSION = "1.1.9";
|
|
7586
7585
|
function safeResolvePath(baseDir, relativePath) {
|
|
7587
7586
|
const cleanRel = (relativePath || "").replace(/^[\\\/]+/, "");
|
|
7588
7587
|
const resolved = path2.resolve(baseDir, cleanRel);
|
|
@@ -7592,45 +7591,6 @@ function safeResolvePath(baseDir, relativePath) {
|
|
|
7592
7591
|
}
|
|
7593
7592
|
return resolved;
|
|
7594
7593
|
}
|
|
7595
|
-
function sendCloudRelayRequest(method, endpoint, payload) {
|
|
7596
|
-
return new Promise((resolve) => {
|
|
7597
|
-
try {
|
|
7598
|
-
const url = new URL(`${CLOUD_RELAY_URL}${endpoint}`);
|
|
7599
|
-
const body = payload ? JSON.stringify(payload) : "";
|
|
7600
|
-
const req = https.request({
|
|
7601
|
-
hostname: url.hostname,
|
|
7602
|
-
port: 443,
|
|
7603
|
-
path: url.pathname + url.search,
|
|
7604
|
-
method,
|
|
7605
|
-
headers: {
|
|
7606
|
-
"Content-Type": "application/json",
|
|
7607
|
-
"Content-Length": Buffer.byteLength(body),
|
|
7608
|
-
"User-Agent": `yap2app-cli/${CLI_VERSION}`
|
|
7609
|
-
},
|
|
7610
|
-
timeout: 6e3
|
|
7611
|
-
}, (res) => {
|
|
7612
|
-
let respData = "";
|
|
7613
|
-
res.on("data", (chunk) => respData += chunk);
|
|
7614
|
-
res.on("end", () => {
|
|
7615
|
-
try {
|
|
7616
|
-
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, status: res.statusCode, data: JSON.parse(respData || "{}") });
|
|
7617
|
-
} catch {
|
|
7618
|
-
resolve({ ok: false, status: res.statusCode, data: null });
|
|
7619
|
-
}
|
|
7620
|
-
});
|
|
7621
|
-
});
|
|
7622
|
-
req.on("error", () => resolve({ ok: false, status: 0, data: null }));
|
|
7623
|
-
req.on("timeout", () => {
|
|
7624
|
-
req.destroy();
|
|
7625
|
-
resolve({ ok: false, status: 0, data: null });
|
|
7626
|
-
});
|
|
7627
|
-
if (body) req.write(body);
|
|
7628
|
-
req.end();
|
|
7629
|
-
} catch {
|
|
7630
|
-
resolve({ ok: false, status: 0, data: null });
|
|
7631
|
-
}
|
|
7632
|
-
});
|
|
7633
|
-
}
|
|
7634
7594
|
function getCorsHeaders(req) {
|
|
7635
7595
|
const origin = req?.headers?.origin || "*";
|
|
7636
7596
|
const requestedHeaders = req?.headers?.["access-control-request-headers"] || "*";
|
|
@@ -7800,11 +7760,10 @@ server.on("error", (err) => {
|
|
|
7800
7760
|
if (err && err.code === "EADDRINUSE") {
|
|
7801
7761
|
console.log(`
|
|
7802
7762
|
---------------------------------------------------------------`);
|
|
7803
|
-
console.log(`Yap2App Bridge`);
|
|
7804
|
-
console.log(`
|
|
7763
|
+
console.log(`Yap2App Local Bridge v${CLI_VERSION}`);
|
|
7764
|
+
console.log(`Local Endpoint: http://127.0.0.1:${PORT}`);
|
|
7805
7765
|
console.log(`Active Workspace: ${PROJECT_ROOT}`);
|
|
7806
|
-
console.log(`
|
|
7807
|
-
console.log(`Web Studio: ${CLOUD_RELAY_URL}`);
|
|
7766
|
+
console.log(`Status: Already active & ready on port ${PORT}`);
|
|
7808
7767
|
console.log(`---------------------------------------------------------------
|
|
7809
7768
|
`);
|
|
7810
7769
|
console.log(`Bridge is running.`);
|
|
@@ -7819,15 +7778,14 @@ async function startBridge(port = PORT) {
|
|
|
7819
7778
|
server.listen(port, "0.0.0.0", () => {
|
|
7820
7779
|
console.log(`
|
|
7821
7780
|
---------------------------------------------------------------`);
|
|
7822
|
-
console.log(`Yap2App Bridge v${CLI_VERSION}`);
|
|
7781
|
+
console.log(`Yap2App Local Bridge v${CLI_VERSION}`);
|
|
7823
7782
|
console.log(`Local Endpoint: http://127.0.0.1:${port}`);
|
|
7824
7783
|
console.log(`Active Workspace: ${PROJECT_ROOT}`);
|
|
7825
|
-
console.log(`
|
|
7826
|
-
console.log(`Web Studio: ${CLOUD_RELAY_URL}`);
|
|
7784
|
+
console.log(`Web Studio: https://yap2app-dot-cybage-hackathon.uc.r.appspot.com`);
|
|
7827
7785
|
console.log(`---------------------------------------------------------------
|
|
7828
7786
|
`);
|
|
7829
7787
|
console.log(`Bridge is running.`);
|
|
7830
|
-
console.log(`Open Web Studio in your browser to
|
|
7788
|
+
console.log(`Open Web Studio in your browser to automatically connect and sync.`);
|
|
7831
7789
|
console.log(`Press Ctrl/Cmd+C to stop.
|
|
7832
7790
|
`);
|
|
7833
7791
|
});
|
|
@@ -7838,50 +7796,8 @@ async function startBridge(port = PORT) {
|
|
|
7838
7796
|
console.log(` Yap2App will automatically scaffold directories and write files when synced from Web Studio.
|
|
7839
7797
|
`);
|
|
7840
7798
|
}
|
|
7841
|
-
await sendCloudRelayRequest("POST", "/api/v1/bridge/heartbeat", {
|
|
7842
|
-
pair_code: PAIR_CODE,
|
|
7843
|
-
project_name: path2.basename(PROJECT_ROOT),
|
|
7844
|
-
project_root: PROJECT_ROOT,
|
|
7845
|
-
framework: initialContext.framework,
|
|
7846
|
-
context: initialContext,
|
|
7847
|
-
version: CLI_VERSION
|
|
7848
|
-
});
|
|
7849
7799
|
} catch (e) {
|
|
7850
7800
|
}
|
|
7851
|
-
setInterval(async () => {
|
|
7852
|
-
try {
|
|
7853
|
-
const context = await scanCodebase(PROJECT_ROOT);
|
|
7854
|
-
const hbResult = await sendCloudRelayRequest("POST", "/api/v1/bridge/heartbeat", {
|
|
7855
|
-
pair_code: PAIR_CODE,
|
|
7856
|
-
project_name: path2.basename(PROJECT_ROOT),
|
|
7857
|
-
project_root: PROJECT_ROOT,
|
|
7858
|
-
framework: context.framework,
|
|
7859
|
-
context,
|
|
7860
|
-
version: CLI_VERSION
|
|
7861
|
-
});
|
|
7862
|
-
if (hbResult && hbResult.data && hbResult.data.pending_writes_count > 0) {
|
|
7863
|
-
const pollResult = await sendCloudRelayRequest("GET", `/api/v1/bridge/poll-writes?pair_code=${PAIR_CODE}`);
|
|
7864
|
-
const tasks = pollResult.data && pollResult.data.pending_tasks || [];
|
|
7865
|
-
for (const task of tasks) {
|
|
7866
|
-
const written = [];
|
|
7867
|
-
for (const file of task.files || []) {
|
|
7868
|
-
const fullPath = safeResolvePath(PROJECT_ROOT, file.path);
|
|
7869
|
-
await fs2.mkdir(path2.dirname(fullPath), { recursive: true });
|
|
7870
|
-
await fs2.writeFile(fullPath, file.content, "utf8");
|
|
7871
|
-
console.log(` [bridge] Wrote ${file.path}`);
|
|
7872
|
-
written.push(file.path);
|
|
7873
|
-
}
|
|
7874
|
-
await sendCloudRelayRequest("POST", "/api/v1/bridge/complete-write", {
|
|
7875
|
-
task_id: task.task_id,
|
|
7876
|
-
success: true,
|
|
7877
|
-
written,
|
|
7878
|
-
message: `Wrote ${written.length} file(s) directly to ${path2.basename(PROJECT_ROOT)}`
|
|
7879
|
-
});
|
|
7880
|
-
}
|
|
7881
|
-
}
|
|
7882
|
-
} catch {
|
|
7883
|
-
}
|
|
7884
|
-
}, 3500);
|
|
7885
7801
|
}
|
|
7886
7802
|
var isDirectRun = Boolean(typeof process !== "undefined" && process.argv && process.argv[1] && (process.argv[1].endsWith("bridge.js") || process.argv[1].endsWith("bridge")));
|
|
7887
7803
|
if (isDirectRun) {
|
package/bridge.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import http from 'http';
|
|
2
|
-
import https from 'https';
|
|
3
2
|
import fsSync from 'fs';
|
|
4
3
|
import path from 'path';
|
|
5
4
|
import util from 'util';
|
|
@@ -15,9 +14,8 @@ const fs = fsSync.promises || {
|
|
|
15
14
|
|
|
16
15
|
const PORT = Number(process.env.YAP2APP_PORT) || 10420;
|
|
17
16
|
const PROJECT_ROOT = process.cwd();
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const CLI_VERSION = '1.1.8';
|
|
17
|
+
const PAIR_CODE = (process.env.YAP2APP_PAIR_CODE || ('Y2A-' + Math.floor(1000 + Math.random() * 9000))).toUpperCase();
|
|
18
|
+
const CLI_VERSION = '1.1.9';
|
|
21
19
|
|
|
22
20
|
/**
|
|
23
21
|
* Validates and resolves relative file paths strictly inside PROJECT_ROOT.
|
|
@@ -33,44 +31,6 @@ function safeResolvePath(baseDir, relativePath) {
|
|
|
33
31
|
return resolved;
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
// Helper to send outbound HTTPS requests to the Yap2App Cloud Relay
|
|
37
|
-
function sendCloudRelayRequest(method, endpoint, payload) {
|
|
38
|
-
return new Promise((resolve) => {
|
|
39
|
-
try {
|
|
40
|
-
const url = new URL(`${CLOUD_RELAY_URL}${endpoint}`);
|
|
41
|
-
const body = payload ? JSON.stringify(payload) : '';
|
|
42
|
-
const req = https.request({
|
|
43
|
-
hostname: url.hostname,
|
|
44
|
-
port: 443,
|
|
45
|
-
path: url.pathname + url.search,
|
|
46
|
-
method: method,
|
|
47
|
-
headers: {
|
|
48
|
-
'Content-Type': 'application/json',
|
|
49
|
-
'Content-Length': Buffer.byteLength(body),
|
|
50
|
-
'User-Agent': `yap2app-cli/${CLI_VERSION}`
|
|
51
|
-
},
|
|
52
|
-
timeout: 6000
|
|
53
|
-
}, (res) => {
|
|
54
|
-
let respData = '';
|
|
55
|
-
res.on('data', chunk => respData += chunk);
|
|
56
|
-
res.on('end', () => {
|
|
57
|
-
try {
|
|
58
|
-
resolve({ ok: res.statusCode >= 200 && res.statusCode < 300, status: res.statusCode, data: JSON.parse(respData || '{}') });
|
|
59
|
-
} catch {
|
|
60
|
-
resolve({ ok: false, status: res.statusCode, data: null });
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
req.on('error', () => resolve({ ok: false, status: 0, data: null }));
|
|
65
|
-
req.on('timeout', () => { req.destroy(); resolve({ ok: false, status: 0, data: null }); });
|
|
66
|
-
if (body) req.write(body);
|
|
67
|
-
req.end();
|
|
68
|
-
} catch {
|
|
69
|
-
resolve({ ok: false, status: 0, data: null });
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
34
|
// Bulletproof W3C Private Network Access (PNA) and Dynamic Origin CORS Headers
|
|
75
35
|
function getCorsHeaders(req) {
|
|
76
36
|
const origin = req?.headers?.origin || '*';
|
|
@@ -281,11 +241,10 @@ const server = http.createServer(async (req, res) => {
|
|
|
281
241
|
server.on('error', (err) => {
|
|
282
242
|
if (err && err.code === 'EADDRINUSE') {
|
|
283
243
|
console.log(`\n---------------------------------------------------------------`);
|
|
284
|
-
console.log(`Yap2App Bridge`);
|
|
285
|
-
console.log(`
|
|
244
|
+
console.log(`Yap2App Local Bridge v${CLI_VERSION}`);
|
|
245
|
+
console.log(`Local Endpoint: http://127.0.0.1:${PORT}`);
|
|
286
246
|
console.log(`Active Workspace: ${PROJECT_ROOT}`);
|
|
287
|
-
console.log(`
|
|
288
|
-
console.log(`Web Studio: ${CLOUD_RELAY_URL}`);
|
|
247
|
+
console.log(`Status: Already active & ready on port ${PORT}`);
|
|
289
248
|
console.log(`---------------------------------------------------------------\n`);
|
|
290
249
|
console.log(`Bridge is running.`);
|
|
291
250
|
console.log(`Open Web Studio in your browser to sync components to this workspace.`);
|
|
@@ -298,70 +257,24 @@ server.on('error', (err) => {
|
|
|
298
257
|
export async function startBridge(port = PORT) {
|
|
299
258
|
server.listen(port, '0.0.0.0', () => {
|
|
300
259
|
console.log(`\n---------------------------------------------------------------`);
|
|
301
|
-
console.log(`Yap2App Bridge v${CLI_VERSION}`);
|
|
260
|
+
console.log(`Yap2App Local Bridge v${CLI_VERSION}`);
|
|
302
261
|
console.log(`Local Endpoint: http://127.0.0.1:${port}`);
|
|
303
262
|
console.log(`Active Workspace: ${PROJECT_ROOT}`);
|
|
304
|
-
console.log(`
|
|
305
|
-
console.log(`Web Studio: ${CLOUD_RELAY_URL}`);
|
|
263
|
+
console.log(`Web Studio: https://yap2app-dot-cybage-hackathon.uc.r.appspot.com`);
|
|
306
264
|
console.log(`---------------------------------------------------------------\n`);
|
|
307
265
|
console.log(`Bridge is running.`);
|
|
308
|
-
console.log(`Open Web Studio in your browser to
|
|
266
|
+
console.log(`Open Web Studio in your browser to automatically connect and sync.`);
|
|
309
267
|
console.log(`Press Ctrl/Cmd+C to stop.\n`);
|
|
310
268
|
});
|
|
311
269
|
|
|
312
|
-
// Initial scan
|
|
270
|
+
// Initial scan notice
|
|
313
271
|
try {
|
|
314
272
|
const initialContext = await scanCodebase(PROJECT_ROOT);
|
|
315
273
|
if (initialContext && initialContext.total_files_count === 0) {
|
|
316
274
|
console.log(` ℹ️ Fresh workspace detected (0 code files).`);
|
|
317
275
|
console.log(` Yap2App will automatically scaffold directories and write files when synced from Web Studio.\n`);
|
|
318
276
|
}
|
|
319
|
-
await sendCloudRelayRequest('POST', '/api/v1/bridge/heartbeat', {
|
|
320
|
-
pair_code: PAIR_CODE,
|
|
321
|
-
project_name: path.basename(PROJECT_ROOT),
|
|
322
|
-
project_root: PROJECT_ROOT,
|
|
323
|
-
framework: initialContext.framework,
|
|
324
|
-
context: initialContext,
|
|
325
|
-
version: CLI_VERSION
|
|
326
|
-
});
|
|
327
277
|
} catch (e) {}
|
|
328
|
-
|
|
329
|
-
// Periodic Cloud Relay heartbeat & write execution loop (every 3.5 seconds)
|
|
330
|
-
setInterval(async () => {
|
|
331
|
-
try {
|
|
332
|
-
const context = await scanCodebase(PROJECT_ROOT);
|
|
333
|
-
const hbResult = await sendCloudRelayRequest('POST', '/api/v1/bridge/heartbeat', {
|
|
334
|
-
pair_code: PAIR_CODE,
|
|
335
|
-
project_name: path.basename(PROJECT_ROOT),
|
|
336
|
-
project_root: PROJECT_ROOT,
|
|
337
|
-
framework: context.framework,
|
|
338
|
-
context: context,
|
|
339
|
-
version: CLI_VERSION
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
// If pending write tasks, fetch and execute them on local disk
|
|
343
|
-
if (hbResult && hbResult.data && hbResult.data.pending_writes_count > 0) {
|
|
344
|
-
const pollResult = await sendCloudRelayRequest('GET', `/api/v1/bridge/poll-writes?pair_code=${PAIR_CODE}`);
|
|
345
|
-
const tasks = (pollResult.data && pollResult.data.pending_tasks) || [];
|
|
346
|
-
for (const task of tasks) {
|
|
347
|
-
const written = [];
|
|
348
|
-
for (const file of (task.files || [])) {
|
|
349
|
-
const fullPath = safeResolvePath(PROJECT_ROOT, file.path);
|
|
350
|
-
await fs.mkdir(path.dirname(fullPath), { recursive: true });
|
|
351
|
-
await fs.writeFile(fullPath, file.content, 'utf8');
|
|
352
|
-
console.log(` [bridge] Wrote ${file.path}`);
|
|
353
|
-
written.push(file.path);
|
|
354
|
-
}
|
|
355
|
-
await sendCloudRelayRequest('POST', '/api/v1/bridge/complete-write', {
|
|
356
|
-
task_id: task.task_id,
|
|
357
|
-
success: true,
|
|
358
|
-
written,
|
|
359
|
-
message: `Wrote ${written.length} file(s) directly to ${path.basename(PROJECT_ROOT)}`
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
} catch {}
|
|
364
|
-
}, 3500);
|
|
365
278
|
}
|
|
366
279
|
|
|
367
280
|
// Direct execution
|