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