percher 0.5.7 → 0.5.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/dist/bin/percher.js +1936 -750
- package/dist/package.json +1 -1
- package/dist/src/commands/apps.d.ts.map +1 -1
- package/dist/src/commands/apps.js +40 -0
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/migrate.d.ts.map +1 -1
- package/dist/src/commands/migrate.js +67 -0
- package/dist/src/commands/migrate.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/percher.js
CHANGED
|
@@ -3604,8 +3604,8 @@ var require_streamx = __commonJS((exports, module) => {
|
|
|
3604
3604
|
return this;
|
|
3605
3605
|
},
|
|
3606
3606
|
next() {
|
|
3607
|
-
return new Promise(function(
|
|
3608
|
-
promiseResolve =
|
|
3607
|
+
return new Promise(function(resolve7, reject) {
|
|
3608
|
+
promiseResolve = resolve7;
|
|
3609
3609
|
promiseReject = reject;
|
|
3610
3610
|
const data2 = stream.read();
|
|
3611
3611
|
if (data2 !== null)
|
|
@@ -3642,14 +3642,14 @@ var require_streamx = __commonJS((exports, module) => {
|
|
|
3642
3642
|
}
|
|
3643
3643
|
function destroy(err) {
|
|
3644
3644
|
stream.destroy(err);
|
|
3645
|
-
return new Promise((
|
|
3645
|
+
return new Promise((resolve7, reject) => {
|
|
3646
3646
|
if (stream._duplexState & DESTROYED)
|
|
3647
|
-
return
|
|
3647
|
+
return resolve7({ value: undefined, done: true });
|
|
3648
3648
|
stream.once("close", function() {
|
|
3649
3649
|
if (err)
|
|
3650
3650
|
reject(err);
|
|
3651
3651
|
else
|
|
3652
|
-
|
|
3652
|
+
resolve7({ value: undefined, done: true });
|
|
3653
3653
|
});
|
|
3654
3654
|
});
|
|
3655
3655
|
}
|
|
@@ -3701,8 +3701,8 @@ var require_streamx = __commonJS((exports, module) => {
|
|
|
3701
3701
|
return Promise.resolve(true);
|
|
3702
3702
|
if (state.drains === null)
|
|
3703
3703
|
state.drains = [];
|
|
3704
|
-
return new Promise((
|
|
3705
|
-
state.drains.push({ writes, resolve:
|
|
3704
|
+
return new Promise((resolve7) => {
|
|
3705
|
+
state.drains.push({ writes, resolve: resolve7 });
|
|
3706
3706
|
});
|
|
3707
3707
|
}
|
|
3708
3708
|
write(data2) {
|
|
@@ -3816,11 +3816,11 @@ var require_streamx = __commonJS((exports, module) => {
|
|
|
3816
3816
|
cb(null);
|
|
3817
3817
|
}
|
|
3818
3818
|
function pipelinePromise(...streams) {
|
|
3819
|
-
return new Promise((
|
|
3819
|
+
return new Promise((resolve7, reject) => {
|
|
3820
3820
|
return pipeline(...streams, (err) => {
|
|
3821
3821
|
if (err)
|
|
3822
3822
|
return reject(err);
|
|
3823
|
-
|
|
3823
|
+
resolve7();
|
|
3824
3824
|
});
|
|
3825
3825
|
});
|
|
3826
3826
|
}
|
|
@@ -4534,16 +4534,16 @@ var require_extract = __commonJS((exports, module) => {
|
|
|
4534
4534
|
entryCallback = null;
|
|
4535
4535
|
cb(err);
|
|
4536
4536
|
}
|
|
4537
|
-
function onnext(
|
|
4537
|
+
function onnext(resolve7, reject) {
|
|
4538
4538
|
if (error48) {
|
|
4539
4539
|
return reject(error48);
|
|
4540
4540
|
}
|
|
4541
4541
|
if (entryStream) {
|
|
4542
|
-
|
|
4542
|
+
resolve7({ value: entryStream, done: false });
|
|
4543
4543
|
entryStream = null;
|
|
4544
4544
|
return;
|
|
4545
4545
|
}
|
|
4546
|
-
promiseResolve =
|
|
4546
|
+
promiseResolve = resolve7;
|
|
4547
4547
|
promiseReject = reject;
|
|
4548
4548
|
consumeCallback(null);
|
|
4549
4549
|
if (extract._finished && promiseResolve) {
|
|
@@ -4574,14 +4574,14 @@ var require_extract = __commonJS((exports, module) => {
|
|
|
4574
4574
|
function destroy(err) {
|
|
4575
4575
|
extract.destroy(err);
|
|
4576
4576
|
consumeCallback(err);
|
|
4577
|
-
return new Promise((
|
|
4577
|
+
return new Promise((resolve7, reject) => {
|
|
4578
4578
|
if (extract.destroyed)
|
|
4579
|
-
return
|
|
4579
|
+
return resolve7({ value: undefined, done: true });
|
|
4580
4580
|
extract.once("close", function() {
|
|
4581
4581
|
if (err)
|
|
4582
4582
|
reject(err);
|
|
4583
4583
|
else
|
|
4584
|
-
|
|
4584
|
+
resolve7({ value: undefined, done: true });
|
|
4585
4585
|
});
|
|
4586
4586
|
});
|
|
4587
4587
|
}
|
|
@@ -5069,11 +5069,11 @@ var require_tslib = __commonJS((exports, module) => {
|
|
|
5069
5069
|
};
|
|
5070
5070
|
__awaiter = function(thisArg, _arguments, P, generator) {
|
|
5071
5071
|
function adopt(value) {
|
|
5072
|
-
return value instanceof P ? value : new P(function(
|
|
5073
|
-
|
|
5072
|
+
return value instanceof P ? value : new P(function(resolve7) {
|
|
5073
|
+
resolve7(value);
|
|
5074
5074
|
});
|
|
5075
5075
|
}
|
|
5076
|
-
return new (P || (P = Promise))(function(
|
|
5076
|
+
return new (P || (P = Promise))(function(resolve7, reject) {
|
|
5077
5077
|
function fulfilled(value) {
|
|
5078
5078
|
try {
|
|
5079
5079
|
step(generator.next(value));
|
|
@@ -5089,7 +5089,7 @@ var require_tslib = __commonJS((exports, module) => {
|
|
|
5089
5089
|
}
|
|
5090
5090
|
}
|
|
5091
5091
|
function step(result) {
|
|
5092
|
-
result.done ?
|
|
5092
|
+
result.done ? resolve7(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
5093
5093
|
}
|
|
5094
5094
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
5095
5095
|
});
|
|
@@ -5318,14 +5318,14 @@ var require_tslib = __commonJS((exports, module) => {
|
|
|
5318
5318
|
}, i);
|
|
5319
5319
|
function verb(n) {
|
|
5320
5320
|
i[n] = o[n] && function(v) {
|
|
5321
|
-
return new Promise(function(
|
|
5322
|
-
v = o[n](v), settle(
|
|
5321
|
+
return new Promise(function(resolve7, reject) {
|
|
5322
|
+
v = o[n](v), settle(resolve7, reject, v.done, v.value);
|
|
5323
5323
|
});
|
|
5324
5324
|
};
|
|
5325
5325
|
}
|
|
5326
|
-
function settle(
|
|
5326
|
+
function settle(resolve7, reject, d, v) {
|
|
5327
5327
|
Promise.resolve(v).then(function(v2) {
|
|
5328
|
-
|
|
5328
|
+
resolve7({ value: v2, done: d });
|
|
5329
5329
|
}, reject);
|
|
5330
5330
|
}
|
|
5331
5331
|
};
|
|
@@ -8824,7 +8824,7 @@ var require_util = __commonJS((exports) => {
|
|
|
8824
8824
|
}
|
|
8825
8825
|
path = url2.path;
|
|
8826
8826
|
}
|
|
8827
|
-
var
|
|
8827
|
+
var isAbsolute3 = exports.isAbsolute(path);
|
|
8828
8828
|
var parts = path.split(/\/+/);
|
|
8829
8829
|
for (var part, up = 0, i = parts.length - 1;i >= 0; i--) {
|
|
8830
8830
|
part = parts[i];
|
|
@@ -8844,7 +8844,7 @@ var require_util = __commonJS((exports) => {
|
|
|
8844
8844
|
}
|
|
8845
8845
|
path = parts.join("/");
|
|
8846
8846
|
if (path === "") {
|
|
8847
|
-
path =
|
|
8847
|
+
path = isAbsolute3 ? "/" : ".";
|
|
8848
8848
|
}
|
|
8849
8849
|
if (url2) {
|
|
8850
8850
|
url2.path = path;
|
|
@@ -8853,7 +8853,7 @@ var require_util = __commonJS((exports) => {
|
|
|
8853
8853
|
return path;
|
|
8854
8854
|
}
|
|
8855
8855
|
exports.normalize = normalize2;
|
|
8856
|
-
function
|
|
8856
|
+
function join18(aRoot, aPath) {
|
|
8857
8857
|
if (aRoot === "") {
|
|
8858
8858
|
aRoot = ".";
|
|
8859
8859
|
}
|
|
@@ -8885,11 +8885,11 @@ var require_util = __commonJS((exports) => {
|
|
|
8885
8885
|
}
|
|
8886
8886
|
return joined;
|
|
8887
8887
|
}
|
|
8888
|
-
exports.join =
|
|
8888
|
+
exports.join = join18;
|
|
8889
8889
|
exports.isAbsolute = function(aPath) {
|
|
8890
8890
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
8891
8891
|
};
|
|
8892
|
-
function
|
|
8892
|
+
function relative4(aRoot, aPath) {
|
|
8893
8893
|
if (aRoot === "") {
|
|
8894
8894
|
aRoot = ".";
|
|
8895
8895
|
}
|
|
@@ -8908,7 +8908,7 @@ var require_util = __commonJS((exports) => {
|
|
|
8908
8908
|
}
|
|
8909
8909
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
|
8910
8910
|
}
|
|
8911
|
-
exports.relative =
|
|
8911
|
+
exports.relative = relative4;
|
|
8912
8912
|
var supportsNullProto = function() {
|
|
8913
8913
|
var obj = Object.create(null);
|
|
8914
8914
|
return !("__proto__" in obj);
|
|
@@ -9058,7 +9058,7 @@ var require_util = __commonJS((exports) => {
|
|
|
9058
9058
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
9059
9059
|
}
|
|
9060
9060
|
}
|
|
9061
|
-
sourceURL =
|
|
9061
|
+
sourceURL = join18(urlGenerate(parsed), sourceURL);
|
|
9062
9062
|
}
|
|
9063
9063
|
return normalize2(sourceURL);
|
|
9064
9064
|
}
|
|
@@ -19563,10 +19563,10 @@ else`, adjustClause(path.call(print, "alternate"), options));
|
|
|
19563
19563
|
}
|
|
19564
19564
|
case "ForStatement": {
|
|
19565
19565
|
var init2 = path.call(print, "init");
|
|
19566
|
-
var
|
|
19566
|
+
var sep4 = init2.length > 1 ? `;
|
|
19567
19567
|
` : "; ";
|
|
19568
19568
|
var forParen = "for (";
|
|
19569
|
-
var indented = (0, lines_1.fromString)(
|
|
19569
|
+
var indented = (0, lines_1.fromString)(sep4).join([init2, path.call(print, "test"), path.call(print, "update")]).indentTail(forParen.length);
|
|
19570
19570
|
var head = (0, lines_1.concat)([forParen, indented, ")"]);
|
|
19571
19571
|
var clause = adjustClause(path.call(print, "body"), options);
|
|
19572
19572
|
parts.push(head);
|
|
@@ -85237,6 +85237,462 @@ var require_core3 = __commonJS((exports, module) => {
|
|
|
85237
85237
|
module.exports = enrichCore(core2, getParser());
|
|
85238
85238
|
});
|
|
85239
85239
|
|
|
85240
|
+
// ../../node_modules/.bun/isexe@2.0.0/node_modules/isexe/windows.js
|
|
85241
|
+
var require_windows = __commonJS((exports, module) => {
|
|
85242
|
+
module.exports = isexe;
|
|
85243
|
+
isexe.sync = sync;
|
|
85244
|
+
var fs = __require("fs");
|
|
85245
|
+
function checkPathExt(path, options) {
|
|
85246
|
+
var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
|
|
85247
|
+
if (!pathext) {
|
|
85248
|
+
return true;
|
|
85249
|
+
}
|
|
85250
|
+
pathext = pathext.split(";");
|
|
85251
|
+
if (pathext.indexOf("") !== -1) {
|
|
85252
|
+
return true;
|
|
85253
|
+
}
|
|
85254
|
+
for (var i = 0;i < pathext.length; i++) {
|
|
85255
|
+
var p = pathext[i].toLowerCase();
|
|
85256
|
+
if (p && path.substr(-p.length).toLowerCase() === p) {
|
|
85257
|
+
return true;
|
|
85258
|
+
}
|
|
85259
|
+
}
|
|
85260
|
+
return false;
|
|
85261
|
+
}
|
|
85262
|
+
function checkStat(stat, path, options) {
|
|
85263
|
+
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
85264
|
+
return false;
|
|
85265
|
+
}
|
|
85266
|
+
return checkPathExt(path, options);
|
|
85267
|
+
}
|
|
85268
|
+
function isexe(path, options, cb) {
|
|
85269
|
+
fs.stat(path, function(er, stat) {
|
|
85270
|
+
cb(er, er ? false : checkStat(stat, path, options));
|
|
85271
|
+
});
|
|
85272
|
+
}
|
|
85273
|
+
function sync(path, options) {
|
|
85274
|
+
return checkStat(fs.statSync(path), path, options);
|
|
85275
|
+
}
|
|
85276
|
+
});
|
|
85277
|
+
|
|
85278
|
+
// ../../node_modules/.bun/isexe@2.0.0/node_modules/isexe/mode.js
|
|
85279
|
+
var require_mode = __commonJS((exports, module) => {
|
|
85280
|
+
module.exports = isexe;
|
|
85281
|
+
isexe.sync = sync;
|
|
85282
|
+
var fs = __require("fs");
|
|
85283
|
+
function isexe(path, options, cb) {
|
|
85284
|
+
fs.stat(path, function(er, stat) {
|
|
85285
|
+
cb(er, er ? false : checkStat(stat, options));
|
|
85286
|
+
});
|
|
85287
|
+
}
|
|
85288
|
+
function sync(path, options) {
|
|
85289
|
+
return checkStat(fs.statSync(path), options);
|
|
85290
|
+
}
|
|
85291
|
+
function checkStat(stat, options) {
|
|
85292
|
+
return stat.isFile() && checkMode(stat, options);
|
|
85293
|
+
}
|
|
85294
|
+
function checkMode(stat, options) {
|
|
85295
|
+
var mod = stat.mode;
|
|
85296
|
+
var uid = stat.uid;
|
|
85297
|
+
var gid = stat.gid;
|
|
85298
|
+
var myUid = options.uid !== undefined ? options.uid : process.getuid && process.getuid();
|
|
85299
|
+
var myGid = options.gid !== undefined ? options.gid : process.getgid && process.getgid();
|
|
85300
|
+
var u = parseInt("100", 8);
|
|
85301
|
+
var g = parseInt("010", 8);
|
|
85302
|
+
var o = parseInt("001", 8);
|
|
85303
|
+
var ug = u | g;
|
|
85304
|
+
var ret = mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
|
|
85305
|
+
return ret;
|
|
85306
|
+
}
|
|
85307
|
+
});
|
|
85308
|
+
|
|
85309
|
+
// ../../node_modules/.bun/isexe@2.0.0/node_modules/isexe/index.js
|
|
85310
|
+
var require_isexe = __commonJS((exports, module) => {
|
|
85311
|
+
var fs = __require("fs");
|
|
85312
|
+
var core2;
|
|
85313
|
+
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
85314
|
+
core2 = require_windows();
|
|
85315
|
+
} else {
|
|
85316
|
+
core2 = require_mode();
|
|
85317
|
+
}
|
|
85318
|
+
module.exports = isexe;
|
|
85319
|
+
isexe.sync = sync;
|
|
85320
|
+
function isexe(path, options, cb) {
|
|
85321
|
+
if (typeof options === "function") {
|
|
85322
|
+
cb = options;
|
|
85323
|
+
options = {};
|
|
85324
|
+
}
|
|
85325
|
+
if (!cb) {
|
|
85326
|
+
if (typeof Promise !== "function") {
|
|
85327
|
+
throw new TypeError("callback not provided");
|
|
85328
|
+
}
|
|
85329
|
+
return new Promise(function(resolve7, reject) {
|
|
85330
|
+
isexe(path, options || {}, function(er, is) {
|
|
85331
|
+
if (er) {
|
|
85332
|
+
reject(er);
|
|
85333
|
+
} else {
|
|
85334
|
+
resolve7(is);
|
|
85335
|
+
}
|
|
85336
|
+
});
|
|
85337
|
+
});
|
|
85338
|
+
}
|
|
85339
|
+
core2(path, options || {}, function(er, is) {
|
|
85340
|
+
if (er) {
|
|
85341
|
+
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
85342
|
+
er = null;
|
|
85343
|
+
is = false;
|
|
85344
|
+
}
|
|
85345
|
+
}
|
|
85346
|
+
cb(er, is);
|
|
85347
|
+
});
|
|
85348
|
+
}
|
|
85349
|
+
function sync(path, options) {
|
|
85350
|
+
try {
|
|
85351
|
+
return core2.sync(path, options || {});
|
|
85352
|
+
} catch (er) {
|
|
85353
|
+
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
85354
|
+
return false;
|
|
85355
|
+
} else {
|
|
85356
|
+
throw er;
|
|
85357
|
+
}
|
|
85358
|
+
}
|
|
85359
|
+
}
|
|
85360
|
+
});
|
|
85361
|
+
|
|
85362
|
+
// ../../node_modules/.bun/which@2.0.2/node_modules/which/which.js
|
|
85363
|
+
var require_which = __commonJS((exports, module) => {
|
|
85364
|
+
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
85365
|
+
var path = __require("path");
|
|
85366
|
+
var COLON = isWindows ? ";" : ":";
|
|
85367
|
+
var isexe = require_isexe();
|
|
85368
|
+
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
85369
|
+
var getPathInfo = (cmd, opt) => {
|
|
85370
|
+
const colon = opt.colon || COLON;
|
|
85371
|
+
const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [
|
|
85372
|
+
...isWindows ? [process.cwd()] : [],
|
|
85373
|
+
...(opt.path || process.env.PATH || "").split(colon)
|
|
85374
|
+
];
|
|
85375
|
+
const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
|
|
85376
|
+
const pathExt = isWindows ? pathExtExe.split(colon) : [""];
|
|
85377
|
+
if (isWindows) {
|
|
85378
|
+
if (cmd.indexOf(".") !== -1 && pathExt[0] !== "")
|
|
85379
|
+
pathExt.unshift("");
|
|
85380
|
+
}
|
|
85381
|
+
return {
|
|
85382
|
+
pathEnv,
|
|
85383
|
+
pathExt,
|
|
85384
|
+
pathExtExe
|
|
85385
|
+
};
|
|
85386
|
+
};
|
|
85387
|
+
var which = (cmd, opt, cb) => {
|
|
85388
|
+
if (typeof opt === "function") {
|
|
85389
|
+
cb = opt;
|
|
85390
|
+
opt = {};
|
|
85391
|
+
}
|
|
85392
|
+
if (!opt)
|
|
85393
|
+
opt = {};
|
|
85394
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
85395
|
+
const found = [];
|
|
85396
|
+
const step = (i) => new Promise((resolve7, reject) => {
|
|
85397
|
+
if (i === pathEnv.length)
|
|
85398
|
+
return opt.all && found.length ? resolve7(found) : reject(getNotFoundError(cmd));
|
|
85399
|
+
const ppRaw = pathEnv[i];
|
|
85400
|
+
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
85401
|
+
const pCmd = path.join(pathPart, cmd);
|
|
85402
|
+
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
85403
|
+
resolve7(subStep(p, i, 0));
|
|
85404
|
+
});
|
|
85405
|
+
const subStep = (p, i, ii) => new Promise((resolve7, reject) => {
|
|
85406
|
+
if (ii === pathExt.length)
|
|
85407
|
+
return resolve7(step(i + 1));
|
|
85408
|
+
const ext = pathExt[ii];
|
|
85409
|
+
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
85410
|
+
if (!er && is) {
|
|
85411
|
+
if (opt.all)
|
|
85412
|
+
found.push(p + ext);
|
|
85413
|
+
else
|
|
85414
|
+
return resolve7(p + ext);
|
|
85415
|
+
}
|
|
85416
|
+
return resolve7(subStep(p, i, ii + 1));
|
|
85417
|
+
});
|
|
85418
|
+
});
|
|
85419
|
+
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
85420
|
+
};
|
|
85421
|
+
var whichSync = (cmd, opt) => {
|
|
85422
|
+
opt = opt || {};
|
|
85423
|
+
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
85424
|
+
const found = [];
|
|
85425
|
+
for (let i = 0;i < pathEnv.length; i++) {
|
|
85426
|
+
const ppRaw = pathEnv[i];
|
|
85427
|
+
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
85428
|
+
const pCmd = path.join(pathPart, cmd);
|
|
85429
|
+
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
85430
|
+
for (let j = 0;j < pathExt.length; j++) {
|
|
85431
|
+
const cur = p + pathExt[j];
|
|
85432
|
+
try {
|
|
85433
|
+
const is = isexe.sync(cur, { pathExt: pathExtExe });
|
|
85434
|
+
if (is) {
|
|
85435
|
+
if (opt.all)
|
|
85436
|
+
found.push(cur);
|
|
85437
|
+
else
|
|
85438
|
+
return cur;
|
|
85439
|
+
}
|
|
85440
|
+
} catch (ex) {}
|
|
85441
|
+
}
|
|
85442
|
+
}
|
|
85443
|
+
if (opt.all && found.length)
|
|
85444
|
+
return found;
|
|
85445
|
+
if (opt.nothrow)
|
|
85446
|
+
return null;
|
|
85447
|
+
throw getNotFoundError(cmd);
|
|
85448
|
+
};
|
|
85449
|
+
module.exports = which;
|
|
85450
|
+
which.sync = whichSync;
|
|
85451
|
+
});
|
|
85452
|
+
|
|
85453
|
+
// ../../node_modules/.bun/path-key@3.1.1/node_modules/path-key/index.js
|
|
85454
|
+
var require_path_key = __commonJS((exports, module) => {
|
|
85455
|
+
var pathKey = (options = {}) => {
|
|
85456
|
+
const environment = options.env || process.env;
|
|
85457
|
+
const platform = options.platform || process.platform;
|
|
85458
|
+
if (platform !== "win32") {
|
|
85459
|
+
return "PATH";
|
|
85460
|
+
}
|
|
85461
|
+
return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
|
|
85462
|
+
};
|
|
85463
|
+
module.exports = pathKey;
|
|
85464
|
+
module.exports.default = pathKey;
|
|
85465
|
+
});
|
|
85466
|
+
|
|
85467
|
+
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
|
|
85468
|
+
var require_resolveCommand = __commonJS((exports, module) => {
|
|
85469
|
+
var path = __require("path");
|
|
85470
|
+
var which = require_which();
|
|
85471
|
+
var getPathKey = require_path_key();
|
|
85472
|
+
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
85473
|
+
const env = parsed.options.env || process.env;
|
|
85474
|
+
const cwd = process.cwd();
|
|
85475
|
+
const hasCustomCwd = parsed.options.cwd != null;
|
|
85476
|
+
const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled;
|
|
85477
|
+
if (shouldSwitchCwd) {
|
|
85478
|
+
try {
|
|
85479
|
+
process.chdir(parsed.options.cwd);
|
|
85480
|
+
} catch (err) {}
|
|
85481
|
+
}
|
|
85482
|
+
let resolved;
|
|
85483
|
+
try {
|
|
85484
|
+
resolved = which.sync(parsed.command, {
|
|
85485
|
+
path: env[getPathKey({ env })],
|
|
85486
|
+
pathExt: withoutPathExt ? path.delimiter : undefined
|
|
85487
|
+
});
|
|
85488
|
+
} catch (e) {} finally {
|
|
85489
|
+
if (shouldSwitchCwd) {
|
|
85490
|
+
process.chdir(cwd);
|
|
85491
|
+
}
|
|
85492
|
+
}
|
|
85493
|
+
if (resolved) {
|
|
85494
|
+
resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
85495
|
+
}
|
|
85496
|
+
return resolved;
|
|
85497
|
+
}
|
|
85498
|
+
function resolveCommand(parsed) {
|
|
85499
|
+
return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
|
|
85500
|
+
}
|
|
85501
|
+
module.exports = resolveCommand;
|
|
85502
|
+
});
|
|
85503
|
+
|
|
85504
|
+
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/escape.js
|
|
85505
|
+
var require_escape = __commonJS((exports, module) => {
|
|
85506
|
+
var metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
|
|
85507
|
+
function escapeCommand(arg) {
|
|
85508
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
85509
|
+
return arg;
|
|
85510
|
+
}
|
|
85511
|
+
function escapeArgument(arg, doubleEscapeMetaChars) {
|
|
85512
|
+
arg = `${arg}`;
|
|
85513
|
+
arg = arg.replace(/(?=(\\+?)?)\1"/g, "$1$1\\\"");
|
|
85514
|
+
arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
|
|
85515
|
+
arg = `"${arg}"`;
|
|
85516
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
85517
|
+
if (doubleEscapeMetaChars) {
|
|
85518
|
+
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
85519
|
+
}
|
|
85520
|
+
return arg;
|
|
85521
|
+
}
|
|
85522
|
+
exports.command = escapeCommand;
|
|
85523
|
+
exports.argument = escapeArgument;
|
|
85524
|
+
});
|
|
85525
|
+
|
|
85526
|
+
// ../../node_modules/.bun/shebang-regex@3.0.0/node_modules/shebang-regex/index.js
|
|
85527
|
+
var require_shebang_regex = __commonJS((exports, module) => {
|
|
85528
|
+
module.exports = /^#!(.*)/;
|
|
85529
|
+
});
|
|
85530
|
+
|
|
85531
|
+
// ../../node_modules/.bun/shebang-command@2.0.0/node_modules/shebang-command/index.js
|
|
85532
|
+
var require_shebang_command = __commonJS((exports, module) => {
|
|
85533
|
+
var shebangRegex = require_shebang_regex();
|
|
85534
|
+
module.exports = (string4 = "") => {
|
|
85535
|
+
const match = string4.match(shebangRegex);
|
|
85536
|
+
if (!match) {
|
|
85537
|
+
return null;
|
|
85538
|
+
}
|
|
85539
|
+
const [path, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
85540
|
+
const binary = path.split("/").pop();
|
|
85541
|
+
if (binary === "env") {
|
|
85542
|
+
return argument;
|
|
85543
|
+
}
|
|
85544
|
+
return argument ? `${binary} ${argument}` : binary;
|
|
85545
|
+
};
|
|
85546
|
+
});
|
|
85547
|
+
|
|
85548
|
+
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
|
|
85549
|
+
var require_readShebang = __commonJS((exports, module) => {
|
|
85550
|
+
var fs = __require("fs");
|
|
85551
|
+
var shebangCommand = require_shebang_command();
|
|
85552
|
+
function readShebang(command) {
|
|
85553
|
+
const size = 150;
|
|
85554
|
+
const buffer = Buffer.alloc(size);
|
|
85555
|
+
let fd;
|
|
85556
|
+
try {
|
|
85557
|
+
fd = fs.openSync(command, "r");
|
|
85558
|
+
fs.readSync(fd, buffer, 0, size, 0);
|
|
85559
|
+
fs.closeSync(fd);
|
|
85560
|
+
} catch (e) {}
|
|
85561
|
+
return shebangCommand(buffer.toString());
|
|
85562
|
+
}
|
|
85563
|
+
module.exports = readShebang;
|
|
85564
|
+
});
|
|
85565
|
+
|
|
85566
|
+
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
|
|
85567
|
+
var require_parse2 = __commonJS((exports, module) => {
|
|
85568
|
+
var path = __require("path");
|
|
85569
|
+
var resolveCommand = require_resolveCommand();
|
|
85570
|
+
var escape = require_escape();
|
|
85571
|
+
var readShebang = require_readShebang();
|
|
85572
|
+
var isWin = process.platform === "win32";
|
|
85573
|
+
var isExecutableRegExp = /\.(?:com|exe)$/i;
|
|
85574
|
+
var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
|
85575
|
+
function detectShebang(parsed) {
|
|
85576
|
+
parsed.file = resolveCommand(parsed);
|
|
85577
|
+
const shebang = parsed.file && readShebang(parsed.file);
|
|
85578
|
+
if (shebang) {
|
|
85579
|
+
parsed.args.unshift(parsed.file);
|
|
85580
|
+
parsed.command = shebang;
|
|
85581
|
+
return resolveCommand(parsed);
|
|
85582
|
+
}
|
|
85583
|
+
return parsed.file;
|
|
85584
|
+
}
|
|
85585
|
+
function parseNonShell(parsed) {
|
|
85586
|
+
if (!isWin) {
|
|
85587
|
+
return parsed;
|
|
85588
|
+
}
|
|
85589
|
+
const commandFile = detectShebang(parsed);
|
|
85590
|
+
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
85591
|
+
if (parsed.options.forceShell || needsShell) {
|
|
85592
|
+
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
85593
|
+
parsed.command = path.normalize(parsed.command);
|
|
85594
|
+
parsed.command = escape.command(parsed.command);
|
|
85595
|
+
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
85596
|
+
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
85597
|
+
parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
|
|
85598
|
+
parsed.command = process.env.comspec || "cmd.exe";
|
|
85599
|
+
parsed.options.windowsVerbatimArguments = true;
|
|
85600
|
+
}
|
|
85601
|
+
return parsed;
|
|
85602
|
+
}
|
|
85603
|
+
function parse6(command, args, options) {
|
|
85604
|
+
if (args && !Array.isArray(args)) {
|
|
85605
|
+
options = args;
|
|
85606
|
+
args = null;
|
|
85607
|
+
}
|
|
85608
|
+
args = args ? args.slice(0) : [];
|
|
85609
|
+
options = Object.assign({}, options);
|
|
85610
|
+
const parsed = {
|
|
85611
|
+
command,
|
|
85612
|
+
args,
|
|
85613
|
+
options,
|
|
85614
|
+
file: undefined,
|
|
85615
|
+
original: {
|
|
85616
|
+
command,
|
|
85617
|
+
args
|
|
85618
|
+
}
|
|
85619
|
+
};
|
|
85620
|
+
return options.shell ? parsed : parseNonShell(parsed);
|
|
85621
|
+
}
|
|
85622
|
+
module.exports = parse6;
|
|
85623
|
+
});
|
|
85624
|
+
|
|
85625
|
+
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/enoent.js
|
|
85626
|
+
var require_enoent = __commonJS((exports, module) => {
|
|
85627
|
+
var isWin = process.platform === "win32";
|
|
85628
|
+
function notFoundError(original, syscall) {
|
|
85629
|
+
return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
|
|
85630
|
+
code: "ENOENT",
|
|
85631
|
+
errno: "ENOENT",
|
|
85632
|
+
syscall: `${syscall} ${original.command}`,
|
|
85633
|
+
path: original.command,
|
|
85634
|
+
spawnargs: original.args
|
|
85635
|
+
});
|
|
85636
|
+
}
|
|
85637
|
+
function hookChildProcess(cp, parsed) {
|
|
85638
|
+
if (!isWin) {
|
|
85639
|
+
return;
|
|
85640
|
+
}
|
|
85641
|
+
const originalEmit = cp.emit;
|
|
85642
|
+
cp.emit = function(name, arg1) {
|
|
85643
|
+
if (name === "exit") {
|
|
85644
|
+
const err = verifyENOENT(arg1, parsed);
|
|
85645
|
+
if (err) {
|
|
85646
|
+
return originalEmit.call(cp, "error", err);
|
|
85647
|
+
}
|
|
85648
|
+
}
|
|
85649
|
+
return originalEmit.apply(cp, arguments);
|
|
85650
|
+
};
|
|
85651
|
+
}
|
|
85652
|
+
function verifyENOENT(status, parsed) {
|
|
85653
|
+
if (isWin && status === 1 && !parsed.file) {
|
|
85654
|
+
return notFoundError(parsed.original, "spawn");
|
|
85655
|
+
}
|
|
85656
|
+
return null;
|
|
85657
|
+
}
|
|
85658
|
+
function verifyENOENTSync(status, parsed) {
|
|
85659
|
+
if (isWin && status === 1 && !parsed.file) {
|
|
85660
|
+
return notFoundError(parsed.original, "spawnSync");
|
|
85661
|
+
}
|
|
85662
|
+
return null;
|
|
85663
|
+
}
|
|
85664
|
+
module.exports = {
|
|
85665
|
+
hookChildProcess,
|
|
85666
|
+
verifyENOENT,
|
|
85667
|
+
verifyENOENTSync,
|
|
85668
|
+
notFoundError
|
|
85669
|
+
};
|
|
85670
|
+
});
|
|
85671
|
+
|
|
85672
|
+
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/index.js
|
|
85673
|
+
var require_cross_spawn = __commonJS((exports, module) => {
|
|
85674
|
+
var cp = __require("child_process");
|
|
85675
|
+
var parse6 = require_parse2();
|
|
85676
|
+
var enoent = require_enoent();
|
|
85677
|
+
function spawn(command, args, options) {
|
|
85678
|
+
const parsed = parse6(command, args, options);
|
|
85679
|
+
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
85680
|
+
enoent.hookChildProcess(spawned, parsed);
|
|
85681
|
+
return spawned;
|
|
85682
|
+
}
|
|
85683
|
+
function spawnSync(command, args, options) {
|
|
85684
|
+
const parsed = parse6(command, args, options);
|
|
85685
|
+
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
85686
|
+
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
85687
|
+
return result;
|
|
85688
|
+
}
|
|
85689
|
+
module.exports = spawn;
|
|
85690
|
+
module.exports.spawn = spawn;
|
|
85691
|
+
module.exports.sync = spawnSync;
|
|
85692
|
+
module.exports._parse = parse6;
|
|
85693
|
+
module.exports._enoent = enoent;
|
|
85694
|
+
});
|
|
85695
|
+
|
|
85240
85696
|
// ../../node_modules/.bun/qrcode@1.5.4/node_modules/qrcode/lib/can-promise.js
|
|
85241
85697
|
var require_can_promise = __commonJS((exports, module) => {
|
|
85242
85698
|
module.exports = function() {
|
|
@@ -86112,7 +86568,7 @@ var require_regex = __commonJS((exports) => {
|
|
|
86112
86568
|
});
|
|
86113
86569
|
|
|
86114
86570
|
// ../../node_modules/.bun/qrcode@1.5.4/node_modules/qrcode/lib/core/mode.js
|
|
86115
|
-
var
|
|
86571
|
+
var require_mode2 = __commonJS((exports) => {
|
|
86116
86572
|
var VersionCheck = require_version_check();
|
|
86117
86573
|
var Regex = require_regex();
|
|
86118
86574
|
exports.NUMERIC = {
|
|
@@ -86203,7 +86659,7 @@ var require_version = __commonJS((exports) => {
|
|
|
86203
86659
|
var Utils = require_utils();
|
|
86204
86660
|
var ECCode = require_error_correction_code();
|
|
86205
86661
|
var ECLevel = require_error_correction_level();
|
|
86206
|
-
var Mode =
|
|
86662
|
+
var Mode = require_mode2();
|
|
86207
86663
|
var VersionCheck = require_version_check();
|
|
86208
86664
|
var G18 = 1 << 12 | 1 << 11 | 1 << 10 | 1 << 9 | 1 << 8 | 1 << 5 | 1 << 2 | 1 << 0;
|
|
86209
86665
|
var G18_BCH = Utils.getBCHDigit(G18);
|
|
@@ -86311,7 +86767,7 @@ var require_format_info = __commonJS((exports) => {
|
|
|
86311
86767
|
|
|
86312
86768
|
// ../../node_modules/.bun/qrcode@1.5.4/node_modules/qrcode/lib/core/numeric-data.js
|
|
86313
86769
|
var require_numeric_data = __commonJS((exports, module) => {
|
|
86314
|
-
var Mode =
|
|
86770
|
+
var Mode = require_mode2();
|
|
86315
86771
|
function NumericData(data2) {
|
|
86316
86772
|
this.mode = Mode.NUMERIC;
|
|
86317
86773
|
this.data = data2.toString();
|
|
@@ -86344,7 +86800,7 @@ var require_numeric_data = __commonJS((exports, module) => {
|
|
|
86344
86800
|
|
|
86345
86801
|
// ../../node_modules/.bun/qrcode@1.5.4/node_modules/qrcode/lib/core/alphanumeric-data.js
|
|
86346
86802
|
var require_alphanumeric_data = __commonJS((exports, module) => {
|
|
86347
|
-
var Mode =
|
|
86803
|
+
var Mode = require_mode2();
|
|
86348
86804
|
var ALPHA_NUM_CHARS = [
|
|
86349
86805
|
"0",
|
|
86350
86806
|
"1",
|
|
@@ -86421,7 +86877,7 @@ var require_alphanumeric_data = __commonJS((exports, module) => {
|
|
|
86421
86877
|
|
|
86422
86878
|
// ../../node_modules/.bun/qrcode@1.5.4/node_modules/qrcode/lib/core/byte-data.js
|
|
86423
86879
|
var require_byte_data = __commonJS((exports, module) => {
|
|
86424
|
-
var Mode =
|
|
86880
|
+
var Mode = require_mode2();
|
|
86425
86881
|
function ByteData(data2) {
|
|
86426
86882
|
this.mode = Mode.BYTE;
|
|
86427
86883
|
if (typeof data2 === "string") {
|
|
@@ -86449,7 +86905,7 @@ var require_byte_data = __commonJS((exports, module) => {
|
|
|
86449
86905
|
|
|
86450
86906
|
// ../../node_modules/.bun/qrcode@1.5.4/node_modules/qrcode/lib/core/kanji-data.js
|
|
86451
86907
|
var require_kanji_data = __commonJS((exports, module) => {
|
|
86452
|
-
var Mode =
|
|
86908
|
+
var Mode = require_mode2();
|
|
86453
86909
|
var Utils = require_utils();
|
|
86454
86910
|
function KanjiData(data2) {
|
|
86455
86911
|
this.mode = Mode.KANJI;
|
|
@@ -86570,7 +87026,7 @@ var require_dijkstra = __commonJS((exports, module) => {
|
|
|
86570
87026
|
|
|
86571
87027
|
// ../../node_modules/.bun/qrcode@1.5.4/node_modules/qrcode/lib/core/segments.js
|
|
86572
87028
|
var require_segments = __commonJS((exports) => {
|
|
86573
|
-
var Mode =
|
|
87029
|
+
var Mode = require_mode2();
|
|
86574
87030
|
var NumericData = require_numeric_data();
|
|
86575
87031
|
var AlphanumericData = require_alphanumeric_data();
|
|
86576
87032
|
var ByteData = require_byte_data();
|
|
@@ -86765,7 +87221,7 @@ var require_qrcode = __commonJS((exports) => {
|
|
|
86765
87221
|
var ReedSolomonEncoder = require_reed_solomon_encoder();
|
|
86766
87222
|
var Version = require_version();
|
|
86767
87223
|
var FormatInfo = require_format_info();
|
|
86768
|
-
var Mode =
|
|
87224
|
+
var Mode = require_mode2();
|
|
86769
87225
|
var Segments = require_segments();
|
|
86770
87226
|
function setupFinderPattern(matrix, version2) {
|
|
86771
87227
|
const size = matrix.size;
|
|
@@ -89384,10 +89840,10 @@ var require_browser = __commonJS((exports) => {
|
|
|
89384
89840
|
text = canvas;
|
|
89385
89841
|
canvas = undefined;
|
|
89386
89842
|
}
|
|
89387
|
-
return new Promise(function(
|
|
89843
|
+
return new Promise(function(resolve11, reject) {
|
|
89388
89844
|
try {
|
|
89389
89845
|
const data2 = QRCode.create(text, opts);
|
|
89390
|
-
|
|
89846
|
+
resolve11(renderFunc(data2, canvas, opts));
|
|
89391
89847
|
} catch (e) {
|
|
89392
89848
|
reject(e);
|
|
89393
89849
|
}
|
|
@@ -89466,11 +89922,11 @@ var require_server = __commonJS((exports) => {
|
|
|
89466
89922
|
}
|
|
89467
89923
|
function render(renderFunc, text, params) {
|
|
89468
89924
|
if (!params.cb) {
|
|
89469
|
-
return new Promise(function(
|
|
89925
|
+
return new Promise(function(resolve11, reject) {
|
|
89470
89926
|
try {
|
|
89471
89927
|
const data2 = QRCode.create(text, params.opts);
|
|
89472
89928
|
return renderFunc(data2, params.opts, function(err, data3) {
|
|
89473
|
-
return err ? reject(err) :
|
|
89929
|
+
return err ? reject(err) : resolve11(data3);
|
|
89474
89930
|
});
|
|
89475
89931
|
} catch (e) {
|
|
89476
89932
|
reject(e);
|
|
@@ -89543,462 +89999,6 @@ var init_qr = __esm(() => {
|
|
|
89543
89999
|
import_qrcode = __toESM(require_server(), 1);
|
|
89544
90000
|
});
|
|
89545
90001
|
|
|
89546
|
-
// ../../node_modules/.bun/isexe@2.0.0/node_modules/isexe/windows.js
|
|
89547
|
-
var require_windows = __commonJS((exports, module) => {
|
|
89548
|
-
module.exports = isexe;
|
|
89549
|
-
isexe.sync = sync;
|
|
89550
|
-
var fs = __require("fs");
|
|
89551
|
-
function checkPathExt(path, options) {
|
|
89552
|
-
var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
|
|
89553
|
-
if (!pathext) {
|
|
89554
|
-
return true;
|
|
89555
|
-
}
|
|
89556
|
-
pathext = pathext.split(";");
|
|
89557
|
-
if (pathext.indexOf("") !== -1) {
|
|
89558
|
-
return true;
|
|
89559
|
-
}
|
|
89560
|
-
for (var i = 0;i < pathext.length; i++) {
|
|
89561
|
-
var p = pathext[i].toLowerCase();
|
|
89562
|
-
if (p && path.substr(-p.length).toLowerCase() === p) {
|
|
89563
|
-
return true;
|
|
89564
|
-
}
|
|
89565
|
-
}
|
|
89566
|
-
return false;
|
|
89567
|
-
}
|
|
89568
|
-
function checkStat(stat2, path, options) {
|
|
89569
|
-
if (!stat2.isSymbolicLink() && !stat2.isFile()) {
|
|
89570
|
-
return false;
|
|
89571
|
-
}
|
|
89572
|
-
return checkPathExt(path, options);
|
|
89573
|
-
}
|
|
89574
|
-
function isexe(path, options, cb) {
|
|
89575
|
-
fs.stat(path, function(er, stat2) {
|
|
89576
|
-
cb(er, er ? false : checkStat(stat2, path, options));
|
|
89577
|
-
});
|
|
89578
|
-
}
|
|
89579
|
-
function sync(path, options) {
|
|
89580
|
-
return checkStat(fs.statSync(path), path, options);
|
|
89581
|
-
}
|
|
89582
|
-
});
|
|
89583
|
-
|
|
89584
|
-
// ../../node_modules/.bun/isexe@2.0.0/node_modules/isexe/mode.js
|
|
89585
|
-
var require_mode2 = __commonJS((exports, module) => {
|
|
89586
|
-
module.exports = isexe;
|
|
89587
|
-
isexe.sync = sync;
|
|
89588
|
-
var fs = __require("fs");
|
|
89589
|
-
function isexe(path, options, cb) {
|
|
89590
|
-
fs.stat(path, function(er, stat2) {
|
|
89591
|
-
cb(er, er ? false : checkStat(stat2, options));
|
|
89592
|
-
});
|
|
89593
|
-
}
|
|
89594
|
-
function sync(path, options) {
|
|
89595
|
-
return checkStat(fs.statSync(path), options);
|
|
89596
|
-
}
|
|
89597
|
-
function checkStat(stat2, options) {
|
|
89598
|
-
return stat2.isFile() && checkMode(stat2, options);
|
|
89599
|
-
}
|
|
89600
|
-
function checkMode(stat2, options) {
|
|
89601
|
-
var mod = stat2.mode;
|
|
89602
|
-
var uid = stat2.uid;
|
|
89603
|
-
var gid = stat2.gid;
|
|
89604
|
-
var myUid = options.uid !== undefined ? options.uid : process.getuid && process.getuid();
|
|
89605
|
-
var myGid = options.gid !== undefined ? options.gid : process.getgid && process.getgid();
|
|
89606
|
-
var u = parseInt("100", 8);
|
|
89607
|
-
var g = parseInt("010", 8);
|
|
89608
|
-
var o = parseInt("001", 8);
|
|
89609
|
-
var ug = u | g;
|
|
89610
|
-
var ret = mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
|
|
89611
|
-
return ret;
|
|
89612
|
-
}
|
|
89613
|
-
});
|
|
89614
|
-
|
|
89615
|
-
// ../../node_modules/.bun/isexe@2.0.0/node_modules/isexe/index.js
|
|
89616
|
-
var require_isexe = __commonJS((exports, module) => {
|
|
89617
|
-
var fs = __require("fs");
|
|
89618
|
-
var core2;
|
|
89619
|
-
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
89620
|
-
core2 = require_windows();
|
|
89621
|
-
} else {
|
|
89622
|
-
core2 = require_mode2();
|
|
89623
|
-
}
|
|
89624
|
-
module.exports = isexe;
|
|
89625
|
-
isexe.sync = sync;
|
|
89626
|
-
function isexe(path, options, cb) {
|
|
89627
|
-
if (typeof options === "function") {
|
|
89628
|
-
cb = options;
|
|
89629
|
-
options = {};
|
|
89630
|
-
}
|
|
89631
|
-
if (!cb) {
|
|
89632
|
-
if (typeof Promise !== "function") {
|
|
89633
|
-
throw new TypeError("callback not provided");
|
|
89634
|
-
}
|
|
89635
|
-
return new Promise(function(resolve9, reject) {
|
|
89636
|
-
isexe(path, options || {}, function(er, is) {
|
|
89637
|
-
if (er) {
|
|
89638
|
-
reject(er);
|
|
89639
|
-
} else {
|
|
89640
|
-
resolve9(is);
|
|
89641
|
-
}
|
|
89642
|
-
});
|
|
89643
|
-
});
|
|
89644
|
-
}
|
|
89645
|
-
core2(path, options || {}, function(er, is) {
|
|
89646
|
-
if (er) {
|
|
89647
|
-
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
89648
|
-
er = null;
|
|
89649
|
-
is = false;
|
|
89650
|
-
}
|
|
89651
|
-
}
|
|
89652
|
-
cb(er, is);
|
|
89653
|
-
});
|
|
89654
|
-
}
|
|
89655
|
-
function sync(path, options) {
|
|
89656
|
-
try {
|
|
89657
|
-
return core2.sync(path, options || {});
|
|
89658
|
-
} catch (er) {
|
|
89659
|
-
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
89660
|
-
return false;
|
|
89661
|
-
} else {
|
|
89662
|
-
throw er;
|
|
89663
|
-
}
|
|
89664
|
-
}
|
|
89665
|
-
}
|
|
89666
|
-
});
|
|
89667
|
-
|
|
89668
|
-
// ../../node_modules/.bun/which@2.0.2/node_modules/which/which.js
|
|
89669
|
-
var require_which = __commonJS((exports, module) => {
|
|
89670
|
-
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
89671
|
-
var path = __require("path");
|
|
89672
|
-
var COLON = isWindows ? ";" : ":";
|
|
89673
|
-
var isexe = require_isexe();
|
|
89674
|
-
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
89675
|
-
var getPathInfo = (cmd, opt) => {
|
|
89676
|
-
const colon = opt.colon || COLON;
|
|
89677
|
-
const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [
|
|
89678
|
-
...isWindows ? [process.cwd()] : [],
|
|
89679
|
-
...(opt.path || process.env.PATH || "").split(colon)
|
|
89680
|
-
];
|
|
89681
|
-
const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
|
|
89682
|
-
const pathExt = isWindows ? pathExtExe.split(colon) : [""];
|
|
89683
|
-
if (isWindows) {
|
|
89684
|
-
if (cmd.indexOf(".") !== -1 && pathExt[0] !== "")
|
|
89685
|
-
pathExt.unshift("");
|
|
89686
|
-
}
|
|
89687
|
-
return {
|
|
89688
|
-
pathEnv,
|
|
89689
|
-
pathExt,
|
|
89690
|
-
pathExtExe
|
|
89691
|
-
};
|
|
89692
|
-
};
|
|
89693
|
-
var which = (cmd, opt, cb) => {
|
|
89694
|
-
if (typeof opt === "function") {
|
|
89695
|
-
cb = opt;
|
|
89696
|
-
opt = {};
|
|
89697
|
-
}
|
|
89698
|
-
if (!opt)
|
|
89699
|
-
opt = {};
|
|
89700
|
-
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
89701
|
-
const found = [];
|
|
89702
|
-
const step = (i) => new Promise((resolve9, reject) => {
|
|
89703
|
-
if (i === pathEnv.length)
|
|
89704
|
-
return opt.all && found.length ? resolve9(found) : reject(getNotFoundError(cmd));
|
|
89705
|
-
const ppRaw = pathEnv[i];
|
|
89706
|
-
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
89707
|
-
const pCmd = path.join(pathPart, cmd);
|
|
89708
|
-
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
89709
|
-
resolve9(subStep(p, i, 0));
|
|
89710
|
-
});
|
|
89711
|
-
const subStep = (p, i, ii) => new Promise((resolve9, reject) => {
|
|
89712
|
-
if (ii === pathExt.length)
|
|
89713
|
-
return resolve9(step(i + 1));
|
|
89714
|
-
const ext = pathExt[ii];
|
|
89715
|
-
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
89716
|
-
if (!er && is) {
|
|
89717
|
-
if (opt.all)
|
|
89718
|
-
found.push(p + ext);
|
|
89719
|
-
else
|
|
89720
|
-
return resolve9(p + ext);
|
|
89721
|
-
}
|
|
89722
|
-
return resolve9(subStep(p, i, ii + 1));
|
|
89723
|
-
});
|
|
89724
|
-
});
|
|
89725
|
-
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
89726
|
-
};
|
|
89727
|
-
var whichSync = (cmd, opt) => {
|
|
89728
|
-
opt = opt || {};
|
|
89729
|
-
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
89730
|
-
const found = [];
|
|
89731
|
-
for (let i = 0;i < pathEnv.length; i++) {
|
|
89732
|
-
const ppRaw = pathEnv[i];
|
|
89733
|
-
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
89734
|
-
const pCmd = path.join(pathPart, cmd);
|
|
89735
|
-
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
89736
|
-
for (let j = 0;j < pathExt.length; j++) {
|
|
89737
|
-
const cur = p + pathExt[j];
|
|
89738
|
-
try {
|
|
89739
|
-
const is = isexe.sync(cur, { pathExt: pathExtExe });
|
|
89740
|
-
if (is) {
|
|
89741
|
-
if (opt.all)
|
|
89742
|
-
found.push(cur);
|
|
89743
|
-
else
|
|
89744
|
-
return cur;
|
|
89745
|
-
}
|
|
89746
|
-
} catch (ex) {}
|
|
89747
|
-
}
|
|
89748
|
-
}
|
|
89749
|
-
if (opt.all && found.length)
|
|
89750
|
-
return found;
|
|
89751
|
-
if (opt.nothrow)
|
|
89752
|
-
return null;
|
|
89753
|
-
throw getNotFoundError(cmd);
|
|
89754
|
-
};
|
|
89755
|
-
module.exports = which;
|
|
89756
|
-
which.sync = whichSync;
|
|
89757
|
-
});
|
|
89758
|
-
|
|
89759
|
-
// ../../node_modules/.bun/path-key@3.1.1/node_modules/path-key/index.js
|
|
89760
|
-
var require_path_key = __commonJS((exports, module) => {
|
|
89761
|
-
var pathKey = (options = {}) => {
|
|
89762
|
-
const environment = options.env || process.env;
|
|
89763
|
-
const platform = options.platform || process.platform;
|
|
89764
|
-
if (platform !== "win32") {
|
|
89765
|
-
return "PATH";
|
|
89766
|
-
}
|
|
89767
|
-
return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
|
|
89768
|
-
};
|
|
89769
|
-
module.exports = pathKey;
|
|
89770
|
-
module.exports.default = pathKey;
|
|
89771
|
-
});
|
|
89772
|
-
|
|
89773
|
-
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
|
|
89774
|
-
var require_resolveCommand = __commonJS((exports, module) => {
|
|
89775
|
-
var path = __require("path");
|
|
89776
|
-
var which = require_which();
|
|
89777
|
-
var getPathKey = require_path_key();
|
|
89778
|
-
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
89779
|
-
const env = parsed.options.env || process.env;
|
|
89780
|
-
const cwd = process.cwd();
|
|
89781
|
-
const hasCustomCwd = parsed.options.cwd != null;
|
|
89782
|
-
const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled;
|
|
89783
|
-
if (shouldSwitchCwd) {
|
|
89784
|
-
try {
|
|
89785
|
-
process.chdir(parsed.options.cwd);
|
|
89786
|
-
} catch (err) {}
|
|
89787
|
-
}
|
|
89788
|
-
let resolved;
|
|
89789
|
-
try {
|
|
89790
|
-
resolved = which.sync(parsed.command, {
|
|
89791
|
-
path: env[getPathKey({ env })],
|
|
89792
|
-
pathExt: withoutPathExt ? path.delimiter : undefined
|
|
89793
|
-
});
|
|
89794
|
-
} catch (e) {} finally {
|
|
89795
|
-
if (shouldSwitchCwd) {
|
|
89796
|
-
process.chdir(cwd);
|
|
89797
|
-
}
|
|
89798
|
-
}
|
|
89799
|
-
if (resolved) {
|
|
89800
|
-
resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
89801
|
-
}
|
|
89802
|
-
return resolved;
|
|
89803
|
-
}
|
|
89804
|
-
function resolveCommand(parsed) {
|
|
89805
|
-
return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
|
|
89806
|
-
}
|
|
89807
|
-
module.exports = resolveCommand;
|
|
89808
|
-
});
|
|
89809
|
-
|
|
89810
|
-
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/escape.js
|
|
89811
|
-
var require_escape = __commonJS((exports, module) => {
|
|
89812
|
-
var metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
|
|
89813
|
-
function escapeCommand(arg) {
|
|
89814
|
-
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
89815
|
-
return arg;
|
|
89816
|
-
}
|
|
89817
|
-
function escapeArgument(arg, doubleEscapeMetaChars) {
|
|
89818
|
-
arg = `${arg}`;
|
|
89819
|
-
arg = arg.replace(/(?=(\\+?)?)\1"/g, "$1$1\\\"");
|
|
89820
|
-
arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
|
|
89821
|
-
arg = `"${arg}"`;
|
|
89822
|
-
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
89823
|
-
if (doubleEscapeMetaChars) {
|
|
89824
|
-
arg = arg.replace(metaCharsRegExp, "^$1");
|
|
89825
|
-
}
|
|
89826
|
-
return arg;
|
|
89827
|
-
}
|
|
89828
|
-
exports.command = escapeCommand;
|
|
89829
|
-
exports.argument = escapeArgument;
|
|
89830
|
-
});
|
|
89831
|
-
|
|
89832
|
-
// ../../node_modules/.bun/shebang-regex@3.0.0/node_modules/shebang-regex/index.js
|
|
89833
|
-
var require_shebang_regex = __commonJS((exports, module) => {
|
|
89834
|
-
module.exports = /^#!(.*)/;
|
|
89835
|
-
});
|
|
89836
|
-
|
|
89837
|
-
// ../../node_modules/.bun/shebang-command@2.0.0/node_modules/shebang-command/index.js
|
|
89838
|
-
var require_shebang_command = __commonJS((exports, module) => {
|
|
89839
|
-
var shebangRegex = require_shebang_regex();
|
|
89840
|
-
module.exports = (string4 = "") => {
|
|
89841
|
-
const match = string4.match(shebangRegex);
|
|
89842
|
-
if (!match) {
|
|
89843
|
-
return null;
|
|
89844
|
-
}
|
|
89845
|
-
const [path, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
89846
|
-
const binary = path.split("/").pop();
|
|
89847
|
-
if (binary === "env") {
|
|
89848
|
-
return argument;
|
|
89849
|
-
}
|
|
89850
|
-
return argument ? `${binary} ${argument}` : binary;
|
|
89851
|
-
};
|
|
89852
|
-
});
|
|
89853
|
-
|
|
89854
|
-
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
|
|
89855
|
-
var require_readShebang = __commonJS((exports, module) => {
|
|
89856
|
-
var fs = __require("fs");
|
|
89857
|
-
var shebangCommand = require_shebang_command();
|
|
89858
|
-
function readShebang(command) {
|
|
89859
|
-
const size = 150;
|
|
89860
|
-
const buffer = Buffer.alloc(size);
|
|
89861
|
-
let fd;
|
|
89862
|
-
try {
|
|
89863
|
-
fd = fs.openSync(command, "r");
|
|
89864
|
-
fs.readSync(fd, buffer, 0, size, 0);
|
|
89865
|
-
fs.closeSync(fd);
|
|
89866
|
-
} catch (e) {}
|
|
89867
|
-
return shebangCommand(buffer.toString());
|
|
89868
|
-
}
|
|
89869
|
-
module.exports = readShebang;
|
|
89870
|
-
});
|
|
89871
|
-
|
|
89872
|
-
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
|
|
89873
|
-
var require_parse2 = __commonJS((exports, module) => {
|
|
89874
|
-
var path = __require("path");
|
|
89875
|
-
var resolveCommand = require_resolveCommand();
|
|
89876
|
-
var escape = require_escape();
|
|
89877
|
-
var readShebang = require_readShebang();
|
|
89878
|
-
var isWin = process.platform === "win32";
|
|
89879
|
-
var isExecutableRegExp = /\.(?:com|exe)$/i;
|
|
89880
|
-
var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
|
89881
|
-
function detectShebang(parsed) {
|
|
89882
|
-
parsed.file = resolveCommand(parsed);
|
|
89883
|
-
const shebang = parsed.file && readShebang(parsed.file);
|
|
89884
|
-
if (shebang) {
|
|
89885
|
-
parsed.args.unshift(parsed.file);
|
|
89886
|
-
parsed.command = shebang;
|
|
89887
|
-
return resolveCommand(parsed);
|
|
89888
|
-
}
|
|
89889
|
-
return parsed.file;
|
|
89890
|
-
}
|
|
89891
|
-
function parseNonShell(parsed) {
|
|
89892
|
-
if (!isWin) {
|
|
89893
|
-
return parsed;
|
|
89894
|
-
}
|
|
89895
|
-
const commandFile = detectShebang(parsed);
|
|
89896
|
-
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
89897
|
-
if (parsed.options.forceShell || needsShell) {
|
|
89898
|
-
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
89899
|
-
parsed.command = path.normalize(parsed.command);
|
|
89900
|
-
parsed.command = escape.command(parsed.command);
|
|
89901
|
-
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
89902
|
-
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
89903
|
-
parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
|
|
89904
|
-
parsed.command = process.env.comspec || "cmd.exe";
|
|
89905
|
-
parsed.options.windowsVerbatimArguments = true;
|
|
89906
|
-
}
|
|
89907
|
-
return parsed;
|
|
89908
|
-
}
|
|
89909
|
-
function parse6(command, args, options) {
|
|
89910
|
-
if (args && !Array.isArray(args)) {
|
|
89911
|
-
options = args;
|
|
89912
|
-
args = null;
|
|
89913
|
-
}
|
|
89914
|
-
args = args ? args.slice(0) : [];
|
|
89915
|
-
options = Object.assign({}, options);
|
|
89916
|
-
const parsed = {
|
|
89917
|
-
command,
|
|
89918
|
-
args,
|
|
89919
|
-
options,
|
|
89920
|
-
file: undefined,
|
|
89921
|
-
original: {
|
|
89922
|
-
command,
|
|
89923
|
-
args
|
|
89924
|
-
}
|
|
89925
|
-
};
|
|
89926
|
-
return options.shell ? parsed : parseNonShell(parsed);
|
|
89927
|
-
}
|
|
89928
|
-
module.exports = parse6;
|
|
89929
|
-
});
|
|
89930
|
-
|
|
89931
|
-
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/enoent.js
|
|
89932
|
-
var require_enoent = __commonJS((exports, module) => {
|
|
89933
|
-
var isWin = process.platform === "win32";
|
|
89934
|
-
function notFoundError(original, syscall) {
|
|
89935
|
-
return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
|
|
89936
|
-
code: "ENOENT",
|
|
89937
|
-
errno: "ENOENT",
|
|
89938
|
-
syscall: `${syscall} ${original.command}`,
|
|
89939
|
-
path: original.command,
|
|
89940
|
-
spawnargs: original.args
|
|
89941
|
-
});
|
|
89942
|
-
}
|
|
89943
|
-
function hookChildProcess(cp, parsed) {
|
|
89944
|
-
if (!isWin) {
|
|
89945
|
-
return;
|
|
89946
|
-
}
|
|
89947
|
-
const originalEmit = cp.emit;
|
|
89948
|
-
cp.emit = function(name, arg1) {
|
|
89949
|
-
if (name === "exit") {
|
|
89950
|
-
const err = verifyENOENT(arg1, parsed);
|
|
89951
|
-
if (err) {
|
|
89952
|
-
return originalEmit.call(cp, "error", err);
|
|
89953
|
-
}
|
|
89954
|
-
}
|
|
89955
|
-
return originalEmit.apply(cp, arguments);
|
|
89956
|
-
};
|
|
89957
|
-
}
|
|
89958
|
-
function verifyENOENT(status, parsed) {
|
|
89959
|
-
if (isWin && status === 1 && !parsed.file) {
|
|
89960
|
-
return notFoundError(parsed.original, "spawn");
|
|
89961
|
-
}
|
|
89962
|
-
return null;
|
|
89963
|
-
}
|
|
89964
|
-
function verifyENOENTSync(status, parsed) {
|
|
89965
|
-
if (isWin && status === 1 && !parsed.file) {
|
|
89966
|
-
return notFoundError(parsed.original, "spawnSync");
|
|
89967
|
-
}
|
|
89968
|
-
return null;
|
|
89969
|
-
}
|
|
89970
|
-
module.exports = {
|
|
89971
|
-
hookChildProcess,
|
|
89972
|
-
verifyENOENT,
|
|
89973
|
-
verifyENOENTSync,
|
|
89974
|
-
notFoundError
|
|
89975
|
-
};
|
|
89976
|
-
});
|
|
89977
|
-
|
|
89978
|
-
// ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/index.js
|
|
89979
|
-
var require_cross_spawn = __commonJS((exports, module) => {
|
|
89980
|
-
var cp = __require("child_process");
|
|
89981
|
-
var parse6 = require_parse2();
|
|
89982
|
-
var enoent = require_enoent();
|
|
89983
|
-
function spawn(command, args, options) {
|
|
89984
|
-
const parsed = parse6(command, args, options);
|
|
89985
|
-
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
89986
|
-
enoent.hookChildProcess(spawned, parsed);
|
|
89987
|
-
return spawned;
|
|
89988
|
-
}
|
|
89989
|
-
function spawnSync(command, args, options) {
|
|
89990
|
-
const parsed = parse6(command, args, options);
|
|
89991
|
-
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
89992
|
-
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
89993
|
-
return result;
|
|
89994
|
-
}
|
|
89995
|
-
module.exports = spawn;
|
|
89996
|
-
module.exports.spawn = spawn;
|
|
89997
|
-
module.exports.sync = spawnSync;
|
|
89998
|
-
module.exports._parse = parse6;
|
|
89999
|
-
module.exports._enoent = enoent;
|
|
90000
|
-
});
|
|
90001
|
-
|
|
90002
90002
|
// ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
90003
90003
|
var require_picocolors = __commonJS((exports, module) => {
|
|
90004
90004
|
var p = process || {};
|
|
@@ -90181,7 +90181,7 @@ __export(exports_prompt_hidden, {
|
|
|
90181
90181
|
});
|
|
90182
90182
|
import { stdin, stdout } from "node:process";
|
|
90183
90183
|
function promptHiddenWithStreams(question, input, output) {
|
|
90184
|
-
return new Promise((
|
|
90184
|
+
return new Promise((resolve11, reject) => {
|
|
90185
90185
|
output.write(`${question} `);
|
|
90186
90186
|
let buf = "";
|
|
90187
90187
|
let done = false;
|
|
@@ -90197,7 +90197,7 @@ function promptHiddenWithStreams(question, input, output) {
|
|
|
90197
90197
|
input.removeListener("error", onError);
|
|
90198
90198
|
output.write(`
|
|
90199
90199
|
`);
|
|
90200
|
-
|
|
90200
|
+
resolve11(buf.replace(/\r$/, ""));
|
|
90201
90201
|
return;
|
|
90202
90202
|
}
|
|
90203
90203
|
buf += ch;
|
|
@@ -90219,7 +90219,7 @@ function promptHiddenWithStreams(question, input, output) {
|
|
|
90219
90219
|
input.removeListener("error", onError);
|
|
90220
90220
|
output.write(`
|
|
90221
90221
|
`);
|
|
90222
|
-
|
|
90222
|
+
resolve11(buf.replace(/\r$/, ""));
|
|
90223
90223
|
};
|
|
90224
90224
|
input.on("data", onData);
|
|
90225
90225
|
input.on("error", onError);
|
|
@@ -90237,7 +90237,7 @@ async function promptHidden(question) {
|
|
|
90237
90237
|
ttyStdin.resume();
|
|
90238
90238
|
ttyStdin.setEncoding("utf8");
|
|
90239
90239
|
try {
|
|
90240
|
-
return await new Promise((
|
|
90240
|
+
return await new Promise((resolve11, reject) => {
|
|
90241
90241
|
stdout.write(`${question} `);
|
|
90242
90242
|
let buf = "";
|
|
90243
90243
|
const onData = (key) => {
|
|
@@ -90247,7 +90247,7 @@ async function promptHidden(question) {
|
|
|
90247
90247
|
ttyStdin.removeListener("data", onData);
|
|
90248
90248
|
stdout.write(`
|
|
90249
90249
|
`);
|
|
90250
|
-
|
|
90250
|
+
resolve11(buf);
|
|
90251
90251
|
return;
|
|
90252
90252
|
}
|
|
90253
90253
|
if (ch === "\x03") {
|
|
@@ -105399,6 +105399,181 @@ var appResourcesInputSchema = exports_external.object({
|
|
|
105399
105399
|
var appTopologyInputSchema = exports_external.object({
|
|
105400
105400
|
app: exports_external.string().optional()
|
|
105401
105401
|
});
|
|
105402
|
+
// ../core/dist/commands/appstore-kit.js
|
|
105403
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
105404
|
+
import { basename, dirname as dirname3, isAbsolute, join as join5, relative, resolve as resolve3, sep } from "node:path";
|
|
105405
|
+
|
|
105406
|
+
// ../core/dist/appstore-artifacts.js
|
|
105407
|
+
var BRAND_GREEN = "#2d6a4f";
|
|
105408
|
+
var ICON_COLOUR_HEX = {
|
|
105409
|
+
green: BRAND_GREEN,
|
|
105410
|
+
terracotta: "#d0653a",
|
|
105411
|
+
blue: "#4a6fa4",
|
|
105412
|
+
purple: "#6e4dba",
|
|
105413
|
+
olive: "#b8923a"
|
|
105414
|
+
};
|
|
105415
|
+
function themeColorForToken(token) {
|
|
105416
|
+
if (token && token in ICON_COLOUR_HEX)
|
|
105417
|
+
return ICON_COLOUR_HEX[token] ?? BRAND_GREEN;
|
|
105418
|
+
return BRAND_GREEN;
|
|
105419
|
+
}
|
|
105420
|
+
function hostFromUrl(url2) {
|
|
105421
|
+
try {
|
|
105422
|
+
return new URL(url2).host;
|
|
105423
|
+
} catch {
|
|
105424
|
+
return url2.replace(/^https?:\/\//, "").replace(/\/.*$/, "");
|
|
105425
|
+
}
|
|
105426
|
+
}
|
|
105427
|
+
function shortName(name) {
|
|
105428
|
+
const cleaned = name.replace(/[^A-Za-z0-9]/g, "");
|
|
105429
|
+
return (cleaned || "App").slice(0, 12);
|
|
105430
|
+
}
|
|
105431
|
+
function manifestStarter({ name, themeColorHex }) {
|
|
105432
|
+
return JSON.stringify({
|
|
105433
|
+
name,
|
|
105434
|
+
short_name: shortName(name),
|
|
105435
|
+
start_url: "/",
|
|
105436
|
+
display: "standalone",
|
|
105437
|
+
background_color: "#ffffff",
|
|
105438
|
+
theme_color: themeColorHex
|
|
105439
|
+
}, null, 2);
|
|
105440
|
+
}
|
|
105441
|
+
function serviceWorkerStarter() {
|
|
105442
|
+
return `// sw.js — minimal offline shell. Drop in at your app root and serve from /sw.js.
|
|
105443
|
+
const CACHE = "app-shell-v1";
|
|
105444
|
+
const SHELL = ["/"];
|
|
105445
|
+
|
|
105446
|
+
self.addEventListener("install", (event) => {
|
|
105447
|
+
event.waitUntil(caches.open(CACHE).then((cache) => cache.addAll(SHELL)));
|
|
105448
|
+
self.skipWaiting();
|
|
105449
|
+
});
|
|
105450
|
+
|
|
105451
|
+
self.addEventListener("activate", (event) => {
|
|
105452
|
+
event.waitUntil(
|
|
105453
|
+
caches.keys().then((keys) =>
|
|
105454
|
+
Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k))),
|
|
105455
|
+
),
|
|
105456
|
+
);
|
|
105457
|
+
self.clients.claim();
|
|
105458
|
+
});
|
|
105459
|
+
|
|
105460
|
+
self.addEventListener("fetch", (event) => {
|
|
105461
|
+
if (event.request.method !== "GET") return;
|
|
105462
|
+
event.respondWith(
|
|
105463
|
+
caches.match(event.request).then((cached) => cached || fetch(event.request)),
|
|
105464
|
+
);
|
|
105465
|
+
});`;
|
|
105466
|
+
}
|
|
105467
|
+
function swRegistrationSnippet() {
|
|
105468
|
+
return `if ("serviceWorker" in navigator) {
|
|
105469
|
+
navigator.serviceWorker.register("/sw.js");
|
|
105470
|
+
}`;
|
|
105471
|
+
}
|
|
105472
|
+
function bubblewrapCommand({ url: url2 }) {
|
|
105473
|
+
const host = hostFromUrl(url2);
|
|
105474
|
+
return `# generate the Android project, pointed at your manifest
|
|
105475
|
+
npx @bubblewrap/cli init --manifest https://${host}/manifest.json
|
|
105476
|
+
npx @bubblewrap/cli build`;
|
|
105477
|
+
}
|
|
105478
|
+
function capacitorConfig({ name, url: url2 }) {
|
|
105479
|
+
const host = hostFromUrl(url2);
|
|
105480
|
+
return `import type { CapacitorConfig } from "@capacitor/cli";
|
|
105481
|
+
const config: CapacitorConfig = {
|
|
105482
|
+
appId: "app.percher.yourapp",
|
|
105483
|
+
appName: ${JSON.stringify(name)},
|
|
105484
|
+
webDir: "dist",
|
|
105485
|
+
server: { url: "https://${host}", cleartext: false },
|
|
105486
|
+
};
|
|
105487
|
+
export default config;`;
|
|
105488
|
+
}
|
|
105489
|
+
function assetlinksJson({ packageName, sha256Fingerprint }) {
|
|
105490
|
+
const pkg = packageName.trim() || "app.percher.yourapp";
|
|
105491
|
+
const fp = sha256Fingerprint.trim() || "<your signing cert SHA-256>";
|
|
105492
|
+
return `[{
|
|
105493
|
+
"relation": ["delegate_permission/common.handle_all_urls"],
|
|
105494
|
+
"target": {
|
|
105495
|
+
"namespace": "android_app",
|
|
105496
|
+
"package_name": ${JSON.stringify(pkg)},
|
|
105497
|
+
"sha256_cert_fingerprints": [${JSON.stringify(fp)}]
|
|
105498
|
+
}
|
|
105499
|
+
}]`;
|
|
105500
|
+
}
|
|
105501
|
+
function appleAppSiteAssociation({ teamId, bundleId }) {
|
|
105502
|
+
const team = teamId.trim() || "TEAMID";
|
|
105503
|
+
const bundle = bundleId.trim() || "app.percher.yourapp";
|
|
105504
|
+
return `{
|
|
105505
|
+
"applinks": {
|
|
105506
|
+
"apps": [],
|
|
105507
|
+
"details": [{ "appID": ${JSON.stringify(`${team}.${bundle}`)}, "paths": ["*"] }]
|
|
105508
|
+
}
|
|
105509
|
+
}`;
|
|
105510
|
+
}
|
|
105511
|
+
|
|
105512
|
+
// ../core/dist/commands/appstore-kit.js
|
|
105513
|
+
var appstoreKitInputSchema = exports_external.object({
|
|
105514
|
+
name: exports_external.string().optional(),
|
|
105515
|
+
url: exports_external.string().optional(),
|
|
105516
|
+
packageName: exports_external.string().optional(),
|
|
105517
|
+
fingerprint: exports_external.string().optional(),
|
|
105518
|
+
teamId: exports_external.string().optional(),
|
|
105519
|
+
bundleId: exports_external.string().optional(),
|
|
105520
|
+
force: exports_external.boolean().optional(),
|
|
105521
|
+
outDir: exports_external.string().optional()
|
|
105522
|
+
});
|
|
105523
|
+
async function appstoreKit(ctx, input = {}) {
|
|
105524
|
+
const name = (input.name ?? readPercherTomlAppName(ctx.cwd) ?? basename(ctx.cwd) ?? "app").trim() || "app";
|
|
105525
|
+
const url2 = input.url?.trim() || `https://${name}.percher.run`;
|
|
105526
|
+
const themeHex = themeColorForToken(null);
|
|
105527
|
+
const base = resolve3(ctx.cwd, input.outDir ?? ".");
|
|
105528
|
+
const baseRel = relative(ctx.cwd, base);
|
|
105529
|
+
if (baseRel.startsWith("..") || isAbsolute(baseRel)) {
|
|
105530
|
+
throw new PercherCoreError("Output directory must stay inside the project", {
|
|
105531
|
+
code: "appstore-kit.bad-out-dir",
|
|
105532
|
+
hint: "Pass a path inside the current project (e.g. --out public), not an absolute or parent path."
|
|
105533
|
+
});
|
|
105534
|
+
}
|
|
105535
|
+
const files = [
|
|
105536
|
+
{ rel: "manifest.json", content: manifestStarter({ name, themeColorHex: themeHex }) },
|
|
105537
|
+
{ rel: "sw.js", content: serviceWorkerStarter() },
|
|
105538
|
+
{ rel: "capacitor.config.ts", content: capacitorConfig({ name, url: url2 }) },
|
|
105539
|
+
{
|
|
105540
|
+
rel: ".well-known/assetlinks.json",
|
|
105541
|
+
content: assetlinksJson({
|
|
105542
|
+
packageName: input.packageName ?? "",
|
|
105543
|
+
sha256Fingerprint: input.fingerprint ?? ""
|
|
105544
|
+
})
|
|
105545
|
+
},
|
|
105546
|
+
{
|
|
105547
|
+
rel: ".well-known/apple-app-site-association",
|
|
105548
|
+
content: appleAppSiteAssociation({
|
|
105549
|
+
teamId: input.teamId ?? "",
|
|
105550
|
+
bundleId: input.bundleId ?? ""
|
|
105551
|
+
})
|
|
105552
|
+
}
|
|
105553
|
+
];
|
|
105554
|
+
const written = [];
|
|
105555
|
+
const skipped = [];
|
|
105556
|
+
for (const f of files) {
|
|
105557
|
+
const abs = join5(base, ...f.rel.split("/"));
|
|
105558
|
+
const display = relative(ctx.cwd, abs).split(sep).join("/");
|
|
105559
|
+
if (existsSync3(abs) && !input.force) {
|
|
105560
|
+
skipped.push(display);
|
|
105561
|
+
continue;
|
|
105562
|
+
}
|
|
105563
|
+
mkdirSync3(dirname3(abs), { recursive: true });
|
|
105564
|
+
writeFileSync3(abs, `${f.content}
|
|
105565
|
+
`, "utf8");
|
|
105566
|
+
written.push(display);
|
|
105567
|
+
}
|
|
105568
|
+
return {
|
|
105569
|
+
appName: name,
|
|
105570
|
+
appUrl: url2,
|
|
105571
|
+
written,
|
|
105572
|
+
skipped,
|
|
105573
|
+
bubblewrapCommand: bubblewrapCommand({ url: url2 }),
|
|
105574
|
+
swRegistration: swRegistrationSnippet()
|
|
105575
|
+
};
|
|
105576
|
+
}
|
|
105402
105577
|
// ../core/dist/commands/billing.js
|
|
105403
105578
|
var billingUpgradeInputSchema = exports_external.object({
|
|
105404
105579
|
plan: exports_external.enum(["starter", "maker", "pro"])
|
|
@@ -105422,22 +105597,22 @@ async function cacheReset(ctx, input = {}) {
|
|
|
105422
105597
|
var capabilitiesInputSchema = exports_external.object({});
|
|
105423
105598
|
// ../client/dist/abortable-sleep.js
|
|
105424
105599
|
function abortableSleep(ms, signal) {
|
|
105425
|
-
return new Promise((
|
|
105600
|
+
return new Promise((resolve4) => {
|
|
105426
105601
|
if (!signal) {
|
|
105427
|
-
setTimeout(
|
|
105602
|
+
setTimeout(resolve4, ms);
|
|
105428
105603
|
return;
|
|
105429
105604
|
}
|
|
105430
105605
|
if (signal.aborted) {
|
|
105431
|
-
|
|
105606
|
+
resolve4();
|
|
105432
105607
|
return;
|
|
105433
105608
|
}
|
|
105434
105609
|
const onAbort = () => {
|
|
105435
105610
|
clearTimeout(t);
|
|
105436
|
-
|
|
105611
|
+
resolve4();
|
|
105437
105612
|
};
|
|
105438
105613
|
const t = setTimeout(() => {
|
|
105439
105614
|
signal.removeEventListener("abort", onAbort);
|
|
105440
|
-
|
|
105615
|
+
resolve4();
|
|
105441
105616
|
}, ms);
|
|
105442
105617
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
105443
105618
|
});
|
|
@@ -105456,9 +105631,9 @@ function isAutoForwardedBuildKey(name) {
|
|
|
105456
105631
|
return AUTO_FORWARD_PREFIXES.some((p) => name.startsWith(p));
|
|
105457
105632
|
}
|
|
105458
105633
|
// ../client/dist/config.js
|
|
105459
|
-
import { existsSync as
|
|
105634
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
105460
105635
|
import { homedir } from "node:os";
|
|
105461
|
-
import { dirname as
|
|
105636
|
+
import { dirname as dirname4, join as join6 } from "node:path";
|
|
105462
105637
|
var DEFAULT_API_URL = "https://api.percher.run";
|
|
105463
105638
|
function home() {
|
|
105464
105639
|
return process.env.HOME ?? process.env.USERPROFILE ?? homedir();
|
|
@@ -105466,12 +105641,12 @@ function home() {
|
|
|
105466
105641
|
function configPath() {
|
|
105467
105642
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
105468
105643
|
if (xdg)
|
|
105469
|
-
return
|
|
105470
|
-
return
|
|
105644
|
+
return join6(xdg, "percher", "config.json");
|
|
105645
|
+
return join6(home(), ".percher", "config.json");
|
|
105471
105646
|
}
|
|
105472
105647
|
function readFile2() {
|
|
105473
105648
|
const p = configPath();
|
|
105474
|
-
if (!
|
|
105649
|
+
if (!existsSync4(p))
|
|
105475
105650
|
return {};
|
|
105476
105651
|
try {
|
|
105477
105652
|
const parsed = JSON.parse(readFileSync4(p, "utf8"));
|
|
@@ -105499,11 +105674,11 @@ function readAnonClaims() {
|
|
|
105499
105674
|
}
|
|
105500
105675
|
function saveConfig(partial2) {
|
|
105501
105676
|
const p = configPath();
|
|
105502
|
-
|
|
105677
|
+
mkdirSync4(dirname4(p), { recursive: true });
|
|
105503
105678
|
const current = readFile2();
|
|
105504
105679
|
const merged = { ...current, ...partial2 };
|
|
105505
105680
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
105506
|
-
|
|
105681
|
+
writeFileSync4(tmp, JSON.stringify(merged, null, 2), "utf8");
|
|
105507
105682
|
renameSync(tmp, p);
|
|
105508
105683
|
}
|
|
105509
105684
|
function getAnonClaim(app) {
|
|
@@ -105907,6 +106082,15 @@ class AppsResource {
|
|
|
105907
106082
|
unsetPreviewBranch(appRef) {
|
|
105908
106083
|
return this.http.deleteJson(`/apps/${encodeURIComponent(appRef)}/preview-branch`);
|
|
105909
106084
|
}
|
|
106085
|
+
listWellKnown(appRef) {
|
|
106086
|
+
return this.http.get(`/apps/${encodeURIComponent(appRef)}/well-known`);
|
|
106087
|
+
}
|
|
106088
|
+
setWellKnown(appRef, kind, content) {
|
|
106089
|
+
return this.http.put(`/apps/${encodeURIComponent(appRef)}/well-known/${encodeURIComponent(kind)}`, { content });
|
|
106090
|
+
}
|
|
106091
|
+
clearWellKnown(appRef, kind) {
|
|
106092
|
+
return this.http.deleteJson(`/apps/${encodeURIComponent(appRef)}/well-known/${encodeURIComponent(kind)}`);
|
|
106093
|
+
}
|
|
105910
106094
|
setDescription(appRef, description) {
|
|
105911
106095
|
return this.http.patch(`/apps/${encodeURIComponent(appRef)}/description`, {
|
|
105912
106096
|
description
|
|
@@ -106582,17 +106766,17 @@ async function claim(ctx, input = {}) {
|
|
|
106582
106766
|
};
|
|
106583
106767
|
}
|
|
106584
106768
|
// ../core/dist/commands/create.js
|
|
106585
|
-
import { join as
|
|
106769
|
+
import { join as join8, resolve as resolve5 } from "node:path";
|
|
106586
106770
|
|
|
106587
106771
|
// ../core/dist/templates.js
|
|
106588
|
-
import { existsSync as
|
|
106589
|
-
import { basename, join as
|
|
106772
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readdirSync, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
106773
|
+
import { basename as basename2, join as join7, normalize, relative as relative2, resolve as resolve4 } from "node:path";
|
|
106590
106774
|
var __dirname = "C:\\dev\\Percher\\packages\\core\\dist";
|
|
106591
|
-
var TEMPLATES_DIR =
|
|
106775
|
+
var TEMPLATES_DIR = resolve4(import.meta.dirname ?? __dirname, "../templates");
|
|
106592
106776
|
var PLACEHOLDER = "__APP_NAME__";
|
|
106593
106777
|
function listTemplates() {
|
|
106594
106778
|
return readdirSync(TEMPLATES_DIR).filter((name) => {
|
|
106595
|
-
const full =
|
|
106779
|
+
const full = join7(TEMPLATES_DIR, name);
|
|
106596
106780
|
return statSync(full).isDirectory();
|
|
106597
106781
|
});
|
|
106598
106782
|
}
|
|
@@ -106602,36 +106786,36 @@ function scaffoldTemplate(input) {
|
|
|
106602
106786
|
if (!available.includes(template)) {
|
|
106603
106787
|
throw new Error(`Unknown template "${template}". Available: ${available.join(", ")}`);
|
|
106604
106788
|
}
|
|
106605
|
-
const absTarget =
|
|
106606
|
-
if (
|
|
106789
|
+
const absTarget = resolve4(targetDir);
|
|
106790
|
+
if (existsSync5(absTarget)) {
|
|
106607
106791
|
const entries = readdirSync(absTarget);
|
|
106608
106792
|
if (entries.length > 0 && !force) {
|
|
106609
106793
|
throw new Error(`Target directory "${absTarget}" is not empty. Use --force to overwrite.`);
|
|
106610
106794
|
}
|
|
106611
106795
|
}
|
|
106612
|
-
const srcDir =
|
|
106796
|
+
const srcDir = join7(TEMPLATES_DIR, template);
|
|
106613
106797
|
const files = [];
|
|
106614
106798
|
function copyDir(src, dest) {
|
|
106615
|
-
|
|
106799
|
+
mkdirSync5(dest, { recursive: true });
|
|
106616
106800
|
for (const entry of readdirSync(src)) {
|
|
106617
|
-
const srcPath =
|
|
106618
|
-
const destPath =
|
|
106619
|
-
const rel =
|
|
106620
|
-
if (rel.startsWith("..") ||
|
|
106801
|
+
const srcPath = join7(src, entry);
|
|
106802
|
+
const destPath = join7(dest, entry);
|
|
106803
|
+
const rel = relative2(absTarget, normalize(destPath));
|
|
106804
|
+
if (rel.startsWith("..") || resolve4(destPath) === resolve4(absTarget, "..", basename2(absTarget))) {
|
|
106621
106805
|
throw new Error(`Template contains path traversal: ${entry}`);
|
|
106622
106806
|
}
|
|
106623
106807
|
if (statSync(srcPath).isDirectory()) {
|
|
106624
106808
|
copyDir(srcPath, destPath);
|
|
106625
106809
|
} else {
|
|
106626
|
-
if (
|
|
106810
|
+
if (existsSync5(destPath) && !force) {
|
|
106627
106811
|
continue;
|
|
106628
106812
|
}
|
|
106629
106813
|
let content = readFileSync5(srcPath, "utf-8");
|
|
106630
106814
|
content = content.replaceAll(PLACEHOLDER, appName);
|
|
106631
106815
|
content = content.replace(/\r\n/g, `
|
|
106632
106816
|
`);
|
|
106633
|
-
|
|
106634
|
-
files.push(
|
|
106817
|
+
writeFileSync5(destPath, content, "utf-8");
|
|
106818
|
+
files.push(relative2(absTarget, destPath).replace(/\\/g, "/"));
|
|
106635
106819
|
}
|
|
106636
106820
|
}
|
|
106637
106821
|
}
|
|
@@ -106656,14 +106840,14 @@ async function create(ctx, input) {
|
|
|
106656
106840
|
}
|
|
106657
106841
|
let targetDir;
|
|
106658
106842
|
if (input.directory) {
|
|
106659
|
-
targetDir =
|
|
106660
|
-
if (!targetDir.startsWith(
|
|
106843
|
+
targetDir = resolve5(ctx.cwd, input.directory);
|
|
106844
|
+
if (!targetDir.startsWith(resolve5(ctx.cwd))) {
|
|
106661
106845
|
throw new PercherCoreError("Directory must be within the current workspace", {
|
|
106662
106846
|
code: "create.failed"
|
|
106663
106847
|
});
|
|
106664
106848
|
}
|
|
106665
106849
|
} else {
|
|
106666
|
-
targetDir =
|
|
106850
|
+
targetDir = join8(ctx.cwd, input.name);
|
|
106667
106851
|
}
|
|
106668
106852
|
try {
|
|
106669
106853
|
const result = scaffoldTemplate({
|
|
@@ -106759,7 +106943,7 @@ async function data(ctx, input = {}) {
|
|
|
106759
106943
|
};
|
|
106760
106944
|
}
|
|
106761
106945
|
// ../core/dist/commands/data-export.js
|
|
106762
|
-
import { resolve as
|
|
106946
|
+
import { resolve as resolve6 } from "node:path";
|
|
106763
106947
|
var dataExportInputSchema = exports_external.object({
|
|
106764
106948
|
app: exports_external.string().optional().describe("App name or id. Defaults to the app in percher.toml."),
|
|
106765
106949
|
out: exports_external.string().optional().describe("Output file path. Defaults to ./<app>-pb-<timestamp>.tar.gz in the current directory.")
|
|
@@ -106775,7 +106959,7 @@ async function dataExport(ctx, input) {
|
|
|
106775
106959
|
ctx.status?.(`Exporting ${appName} data...`);
|
|
106776
106960
|
const stamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
106777
106961
|
const fileName = input.out ?? `${appName}-pb-${stamp}.tar.gz`;
|
|
106778
|
-
const path =
|
|
106962
|
+
const path = resolve6(ctx.cwd, fileName);
|
|
106779
106963
|
const res = await ctx.client.apps.streamDataExport(appName);
|
|
106780
106964
|
const bytes = await writeResponseToFile(res, path);
|
|
106781
106965
|
return {
|
|
@@ -106871,14 +107055,14 @@ async function deploysInspect(ctx, input) {
|
|
|
106871
107055
|
return { deploy, buildLog };
|
|
106872
107056
|
}
|
|
106873
107057
|
// ../core/dist/commands/dev.js
|
|
106874
|
-
import { existsSync as
|
|
106875
|
-
import { join as
|
|
107058
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
107059
|
+
import { join as join11 } from "node:path";
|
|
106876
107060
|
|
|
106877
107061
|
// ../core/dist/tarball.js
|
|
106878
107062
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
106879
107063
|
import { createHash as createHash2 } from "node:crypto";
|
|
106880
|
-
import { existsSync as
|
|
106881
|
-
import { join as
|
|
107064
|
+
import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync2 } from "node:fs";
|
|
107065
|
+
import { join as join9, relative as relative3, sep as sep2 } from "node:path";
|
|
106882
107066
|
import { Readable } from "node:stream";
|
|
106883
107067
|
import { createGzip } from "node:zlib";
|
|
106884
107068
|
|
|
@@ -106904,8 +107088,8 @@ var DEFAULT_IGNORE = [
|
|
|
106904
107088
|
function* walk(dir, baseDir, ig) {
|
|
106905
107089
|
const entries = readdirSync2(dir);
|
|
106906
107090
|
for (const name of entries) {
|
|
106907
|
-
const full =
|
|
106908
|
-
const rel =
|
|
107091
|
+
const full = join9(dir, name);
|
|
107092
|
+
const rel = relative3(baseDir, full).split(sep2).join("/");
|
|
106909
107093
|
if (ig.ignores(rel))
|
|
106910
107094
|
continue;
|
|
106911
107095
|
const stats = statSync2(full);
|
|
@@ -106921,15 +107105,15 @@ function* walk(dir, baseDir, ig) {
|
|
|
106921
107105
|
async function createTarball(options) {
|
|
106922
107106
|
const ig = import_ignore.default();
|
|
106923
107107
|
ig.add(DEFAULT_IGNORE);
|
|
106924
|
-
const gitignorePath =
|
|
106925
|
-
if (
|
|
107108
|
+
const gitignorePath = join9(options.cwd, ".gitignore");
|
|
107109
|
+
if (existsSync6(gitignorePath)) {
|
|
106926
107110
|
ig.add(readFileSync6(gitignorePath, "utf8"));
|
|
106927
107111
|
}
|
|
106928
107112
|
if (options.extraIgnore)
|
|
106929
107113
|
ig.add(options.extraIgnore);
|
|
106930
107114
|
const fileBuffers = [];
|
|
106931
107115
|
for (const rel of walk(options.cwd, options.cwd, ig)) {
|
|
106932
|
-
const data2 = readFileSync6(
|
|
107116
|
+
const data2 = readFileSync6(join9(options.cwd, rel));
|
|
106933
107117
|
fileBuffers.push({ path: rel, size: data2.length, data: data2 });
|
|
106934
107118
|
}
|
|
106935
107119
|
fileBuffers.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
@@ -106948,8 +107132,8 @@ async function createTarball(options) {
|
|
|
106948
107132
|
const pack = $pack();
|
|
106949
107133
|
(async () => {
|
|
106950
107134
|
for (const file2 of fileBuffers) {
|
|
106951
|
-
await new Promise((
|
|
106952
|
-
pack.entry({ name: file2.path, size: file2.data.length }, file2.data, (err) => err ? reject(err) :
|
|
107135
|
+
await new Promise((resolve7, reject) => {
|
|
107136
|
+
pack.entry({ name: file2.path, size: file2.data.length }, file2.data, (err) => err ? reject(err) : resolve7());
|
|
106953
107137
|
});
|
|
106954
107138
|
}
|
|
106955
107139
|
pack.finalize();
|
|
@@ -106969,8 +107153,8 @@ async function createTarball(options) {
|
|
|
106969
107153
|
|
|
106970
107154
|
// ../core/dist/watcher.js
|
|
106971
107155
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
106972
|
-
import { existsSync as
|
|
106973
|
-
import { join as
|
|
107156
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, watch } from "node:fs";
|
|
107157
|
+
import { join as join10, sep as sep3 } from "node:path";
|
|
106974
107158
|
var DEFAULT_IGNORE2 = [
|
|
106975
107159
|
"node_modules",
|
|
106976
107160
|
".git",
|
|
@@ -106990,8 +107174,8 @@ function createWatcher(options) {
|
|
|
106990
107174
|
const debounceMs = options.debounceMs ?? 500;
|
|
106991
107175
|
const ig = import_ignore2.default();
|
|
106992
107176
|
ig.add(DEFAULT_IGNORE2);
|
|
106993
|
-
const gitignorePath =
|
|
106994
|
-
if (
|
|
107177
|
+
const gitignorePath = join10(options.cwd, ".gitignore");
|
|
107178
|
+
if (existsSync7(gitignorePath)) {
|
|
106995
107179
|
ig.add(readFileSync7(gitignorePath, "utf8"));
|
|
106996
107180
|
}
|
|
106997
107181
|
if (options.extraIgnore)
|
|
@@ -107001,7 +107185,7 @@ function createWatcher(options) {
|
|
|
107001
107185
|
const fsWatcher = watch(options.cwd, { recursive: true }, (_event, filename) => {
|
|
107002
107186
|
if (!filename)
|
|
107003
107187
|
return;
|
|
107004
|
-
const rel = filename.split(
|
|
107188
|
+
const rel = filename.split(sep3).join("/");
|
|
107005
107189
|
if (ig.ignores(rel))
|
|
107006
107190
|
return;
|
|
107007
107191
|
pending.add(rel);
|
|
@@ -107030,8 +107214,8 @@ var devInputSchema = exports_external.object({
|
|
|
107030
107214
|
app: exports_external.string().optional()
|
|
107031
107215
|
});
|
|
107032
107216
|
async function loadConfig2(ctx, appOverride) {
|
|
107033
|
-
const tomlPath =
|
|
107034
|
-
if (!
|
|
107217
|
+
const tomlPath = join11(ctx.cwd, "percher.toml");
|
|
107218
|
+
if (!existsSync8(tomlPath)) {
|
|
107035
107219
|
throw new PercherCoreError("No percher.toml found. Run: percher init", {
|
|
107036
107220
|
code: "dev.no-app",
|
|
107037
107221
|
hint: "Create a percher.toml first with `percher init`."
|
|
@@ -107185,12 +107369,12 @@ async function dev(ctx, input, callbacks) {
|
|
|
107185
107369
|
}
|
|
107186
107370
|
});
|
|
107187
107371
|
try {
|
|
107188
|
-
await new Promise((
|
|
107372
|
+
await new Promise((resolve7) => {
|
|
107189
107373
|
if (callbacks.signal.aborted) {
|
|
107190
|
-
|
|
107374
|
+
resolve7();
|
|
107191
107375
|
return;
|
|
107192
107376
|
}
|
|
107193
|
-
callbacks.signal.addEventListener("abort", () =>
|
|
107377
|
+
callbacks.signal.addEventListener("abort", () => resolve7(), { once: true });
|
|
107194
107378
|
});
|
|
107195
107379
|
} finally {
|
|
107196
107380
|
logStream.ctrl?.abort();
|
|
@@ -107225,8 +107409,8 @@ async function diff(ctx, input = {}) {
|
|
|
107225
107409
|
});
|
|
107226
107410
|
}
|
|
107227
107411
|
// ../core/dist/commands/doctor.js
|
|
107228
|
-
import { existsSync as
|
|
107229
|
-
import { join as
|
|
107412
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
107413
|
+
import { join as join13 } from "node:path";
|
|
107230
107414
|
|
|
107231
107415
|
// ../core/dist/error-classifier.js
|
|
107232
107416
|
function extractEnvVarsFromLog(combined) {
|
|
@@ -107771,7 +107955,7 @@ function recoveryFromErrorClass(errorClass, failure = {}) {
|
|
|
107771
107955
|
}
|
|
107772
107956
|
|
|
107773
107957
|
// ../core/dist/commands/publish-failure.js
|
|
107774
|
-
import { join as
|
|
107958
|
+
import { join as join12 } from "node:path";
|
|
107775
107959
|
|
|
107776
107960
|
// ../core/dist/structured-error-codes.js
|
|
107777
107961
|
var MAPPINGS = {
|
|
@@ -107849,7 +108033,7 @@ function trimMessage(raw) {
|
|
|
107849
108033
|
|
|
107850
108034
|
// ../core/dist/commands/publish-failure.js
|
|
107851
108035
|
function tomlPathFor(cwd) {
|
|
107852
|
-
return
|
|
108036
|
+
return join12(cwd, "percher.toml");
|
|
107853
108037
|
}
|
|
107854
108038
|
async function buildFailureError(ctx, app, deployment, signal) {
|
|
107855
108039
|
let buildLogTail;
|
|
@@ -108192,8 +108376,8 @@ async function doctor(ctx, input = {}) {
|
|
|
108192
108376
|
});
|
|
108193
108377
|
return summarize(checks3, { appProvided: !!input.app });
|
|
108194
108378
|
}
|
|
108195
|
-
const tomlPath =
|
|
108196
|
-
const tomlExists =
|
|
108379
|
+
const tomlPath = join13(ctx.cwd, "percher.toml");
|
|
108380
|
+
const tomlExists = existsSync9(tomlPath);
|
|
108197
108381
|
let tomlValid = false;
|
|
108198
108382
|
if (!tomlExists) {
|
|
108199
108383
|
checks3.push({
|
|
@@ -108973,7 +109157,7 @@ async function envList(ctx, input = {}) {
|
|
|
108973
109157
|
import { randomUUID } from "node:crypto";
|
|
108974
109158
|
import { createWriteStream } from "node:fs";
|
|
108975
109159
|
import { rename, unlink } from "node:fs/promises";
|
|
108976
|
-
import { isAbsolute, resolve as resolvePath } from "node:path";
|
|
109160
|
+
import { isAbsolute as isAbsolute2, resolve as resolvePath } from "node:path";
|
|
108977
109161
|
var exportInputSchema = exports_external.object({
|
|
108978
109162
|
app: exports_external.string().optional(),
|
|
108979
109163
|
out: exports_external.string().optional(),
|
|
@@ -108997,7 +109181,7 @@ async function streamToFile(outPath, source) {
|
|
|
108997
109181
|
const tmpPath = `${outPath}.part-${randomUUID()}`;
|
|
108998
109182
|
const out = createWriteStream(tmpPath);
|
|
108999
109183
|
const reader = source.getReader();
|
|
109000
|
-
const closed = new Promise((
|
|
109184
|
+
const closed = new Promise((resolve7) => out.once("close", () => resolve7()));
|
|
109001
109185
|
let onWriteError;
|
|
109002
109186
|
const writeFailed = new Promise((_, reject) => {
|
|
109003
109187
|
onWriteError = reject;
|
|
@@ -109014,14 +109198,14 @@ async function streamToFile(outPath, source) {
|
|
|
109014
109198
|
bytes += value.byteLength;
|
|
109015
109199
|
if (!out.write(value)) {
|
|
109016
109200
|
await Promise.race([
|
|
109017
|
-
new Promise((
|
|
109201
|
+
new Promise((resolve7) => out.once("drain", resolve7)),
|
|
109018
109202
|
writeFailed
|
|
109019
109203
|
]);
|
|
109020
109204
|
}
|
|
109021
109205
|
}
|
|
109022
109206
|
}
|
|
109023
|
-
await new Promise((
|
|
109024
|
-
out.end((err) => err ? reject(err) :
|
|
109207
|
+
await new Promise((resolve7, reject) => {
|
|
109208
|
+
out.end((err) => err ? reject(err) : resolve7());
|
|
109025
109209
|
});
|
|
109026
109210
|
await closed;
|
|
109027
109211
|
} catch (err) {
|
|
@@ -109039,7 +109223,7 @@ async function streamToFile(outPath, source) {
|
|
|
109039
109223
|
return { bytes };
|
|
109040
109224
|
}
|
|
109041
109225
|
function resolveOutPath(ctxCwd, filename) {
|
|
109042
|
-
if (
|
|
109226
|
+
if (isAbsolute2(filename))
|
|
109043
109227
|
return filename;
|
|
109044
109228
|
return resolvePath(ctxCwd, filename);
|
|
109045
109229
|
}
|
|
@@ -109100,8 +109284,8 @@ var forgejoSetupWebhookInputSchema = exports_external.object({
|
|
|
109100
109284
|
app: exports_external.string().optional().describe("App name (overrides percher.toml)")
|
|
109101
109285
|
});
|
|
109102
109286
|
// ../core/dist/commands/generate.js
|
|
109103
|
-
import { existsSync as
|
|
109104
|
-
import { join as
|
|
109287
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
109288
|
+
import { join as join14 } from "node:path";
|
|
109105
109289
|
var generateInputSchema = exports_external.object({
|
|
109106
109290
|
cwd: exports_external.string().optional()
|
|
109107
109291
|
});
|
|
@@ -109187,8 +109371,8 @@ function generateTypeScript(config2) {
|
|
|
109187
109371
|
}
|
|
109188
109372
|
async function generate(ctx, input = {}) {
|
|
109189
109373
|
const cwd = input.cwd ?? ctx.cwd;
|
|
109190
|
-
const tomlPath =
|
|
109191
|
-
if (!
|
|
109374
|
+
const tomlPath = join14(cwd, "percher.toml");
|
|
109375
|
+
if (!existsSync10(tomlPath)) {
|
|
109192
109376
|
throw new PercherCoreError("No percher.toml found", {
|
|
109193
109377
|
code: "dev.no-app",
|
|
109194
109378
|
hint: "Run percher init first."
|
|
@@ -109197,14 +109381,14 @@ async function generate(ctx, input = {}) {
|
|
|
109197
109381
|
const config2 = await parseFile(tomlPath);
|
|
109198
109382
|
const files = [];
|
|
109199
109383
|
const envExample = generateEnvExample(config2);
|
|
109200
|
-
|
|
109384
|
+
writeFileSync6(join14(cwd, ".env.example"), envExample);
|
|
109201
109385
|
files.push(".env.example");
|
|
109202
109386
|
const tsTypes = generateTypeScript(config2);
|
|
109203
|
-
|
|
109387
|
+
writeFileSync6(join14(cwd, "percher.generated.d.ts"), tsTypes);
|
|
109204
109388
|
files.push("percher.generated.d.ts");
|
|
109205
109389
|
const agentInstructions = generateAgentInstructions(config2);
|
|
109206
|
-
|
|
109207
|
-
|
|
109390
|
+
mkdirSync6(join14(cwd, ".percher"), { recursive: true });
|
|
109391
|
+
writeFileSync6(join14(cwd, ".percher", "agent-instructions.md"), agentInstructions);
|
|
109208
109392
|
files.push(".percher/agent-instructions.md");
|
|
109209
109393
|
return { files };
|
|
109210
109394
|
}
|
|
@@ -109353,8 +109537,8 @@ async function githubSetupWebhook(ctx, input) {
|
|
|
109353
109537
|
};
|
|
109354
109538
|
}
|
|
109355
109539
|
// ../core/dist/commands/import-project.js
|
|
109356
|
-
import { existsSync as
|
|
109357
|
-
import { join as
|
|
109540
|
+
import { existsSync as existsSync11, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "node:fs";
|
|
109541
|
+
import { join as join15 } from "node:path";
|
|
109358
109542
|
|
|
109359
109543
|
// ../core/dist/static-docker.js
|
|
109360
109544
|
var STATIC_DOCKER_PORT = 8080;
|
|
@@ -109415,9 +109599,9 @@ var importInputSchema = exports_external.object({
|
|
|
109415
109599
|
app: exports_external.string().optional().describe("App name to import into")
|
|
109416
109600
|
});
|
|
109417
109601
|
function detectProvider(cwd) {
|
|
109418
|
-
if (
|
|
109602
|
+
if (existsSync11(join15(cwd, "vercel.json")))
|
|
109419
109603
|
return "vercel";
|
|
109420
|
-
if (
|
|
109604
|
+
if (existsSync11(join15(cwd, "netlify.toml")))
|
|
109421
109605
|
return "netlify";
|
|
109422
109606
|
return null;
|
|
109423
109607
|
}
|
|
@@ -109435,7 +109619,7 @@ function mapVercelFramework(framework) {
|
|
|
109435
109619
|
return map2[framework ?? ""] ?? { runtime: "node" };
|
|
109436
109620
|
}
|
|
109437
109621
|
function parseVercelJson(cwd) {
|
|
109438
|
-
const raw = readFileSync8(
|
|
109622
|
+
const raw = readFileSync8(join15(cwd, "vercel.json"), "utf-8");
|
|
109439
109623
|
const config2 = JSON.parse(raw);
|
|
109440
109624
|
const warnings = [];
|
|
109441
109625
|
const envVars = [];
|
|
@@ -109489,12 +109673,12 @@ health = "/api/health"
|
|
|
109489
109673
|
return { toml, warnings, envVars, staticBuild };
|
|
109490
109674
|
}
|
|
109491
109675
|
function parseNetlifyToml(cwd) {
|
|
109492
|
-
const raw = readFileSync8(
|
|
109676
|
+
const raw = readFileSync8(join15(cwd, "netlify.toml"), "utf-8");
|
|
109493
109677
|
const warnings = [];
|
|
109494
109678
|
const envVars = [];
|
|
109495
109679
|
const buildCommand = raw.match(/command\s*=\s*"([^"]+)"/)?.[1] ?? "bun run build";
|
|
109496
109680
|
const publishDir = raw.match(/publish\s*=\s*"([^"]+)"/)?.[1] ?? "dist";
|
|
109497
|
-
const hasPackageJson =
|
|
109681
|
+
const hasPackageJson = existsSync11(join15(cwd, "package.json"));
|
|
109498
109682
|
const looksLikeStaticOutput = publishDir === "dist" || publishDir === "build" || publishDir === "public";
|
|
109499
109683
|
let toml = `[app]
|
|
109500
109684
|
name = "imported-app"
|
|
@@ -109565,11 +109749,11 @@ async function importProject(ctx, input = {}) {
|
|
|
109565
109749
|
hint: "Supported providers: vercel, netlify"
|
|
109566
109750
|
});
|
|
109567
109751
|
}
|
|
109568
|
-
const tomlPath =
|
|
109569
|
-
if (
|
|
109752
|
+
const tomlPath = join15(ctx.cwd, "percher.toml");
|
|
109753
|
+
if (existsSync11(tomlPath)) {
|
|
109570
109754
|
result.warnings.unshift("percher.toml already exists — overwriting with imported config");
|
|
109571
109755
|
}
|
|
109572
|
-
|
|
109756
|
+
writeFileSync7(tomlPath, result.toml);
|
|
109573
109757
|
const scaffoldedFiles = [];
|
|
109574
109758
|
if (result.staticBuild) {
|
|
109575
109759
|
const targets = [
|
|
@@ -109583,12 +109767,12 @@ async function importProject(ctx, input = {}) {
|
|
|
109583
109767
|
}
|
|
109584
109768
|
];
|
|
109585
109769
|
for (const { name, content } of targets) {
|
|
109586
|
-
const target =
|
|
109587
|
-
if (
|
|
109770
|
+
const target = join15(ctx.cwd, name);
|
|
109771
|
+
if (existsSync11(target)) {
|
|
109588
109772
|
result.warnings.push(`${name} already exists — left untouched. The imported config expects a multi-stage static build; merge by hand if needed.`);
|
|
109589
109773
|
continue;
|
|
109590
109774
|
}
|
|
109591
|
-
|
|
109775
|
+
writeFileSync7(target, content, "utf-8");
|
|
109592
109776
|
scaffoldedFiles.push(name);
|
|
109593
109777
|
}
|
|
109594
109778
|
}
|
|
@@ -109601,14 +109785,14 @@ async function importProject(ctx, input = {}) {
|
|
|
109601
109785
|
};
|
|
109602
109786
|
}
|
|
109603
109787
|
// ../core/dist/commands/init.js
|
|
109604
|
-
import { existsSync as
|
|
109605
|
-
import { basename as
|
|
109788
|
+
import { existsSync as existsSync13, writeFileSync as writeFileSync8 } from "node:fs";
|
|
109789
|
+
import { basename as basename3, join as join17 } from "node:path";
|
|
109606
109790
|
|
|
109607
109791
|
// ../core/dist/detect.js
|
|
109608
|
-
import { existsSync as
|
|
109609
|
-
import { join as
|
|
109792
|
+
import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
|
|
109793
|
+
import { join as join16 } from "node:path";
|
|
109610
109794
|
function exists(dir, ...names) {
|
|
109611
|
-
return names.some((n) =>
|
|
109795
|
+
return names.some((n) => existsSync12(join16(dir, n)));
|
|
109612
109796
|
}
|
|
109613
109797
|
function readJson(path) {
|
|
109614
109798
|
try {
|
|
@@ -109637,8 +109821,8 @@ function detectDataMode(pkg, cwd) {
|
|
|
109637
109821
|
return { mode: "none" };
|
|
109638
109822
|
}
|
|
109639
109823
|
async function detectFramework(cwd) {
|
|
109640
|
-
const pkgPath =
|
|
109641
|
-
const pkg =
|
|
109824
|
+
const pkgPath = join16(cwd, "package.json");
|
|
109825
|
+
const pkg = existsSync12(pkgPath) ? readJson(pkgPath) : null;
|
|
109642
109826
|
if (exists(cwd, "Dockerfile")) {
|
|
109643
109827
|
return {
|
|
109644
109828
|
runtime: "docker",
|
|
@@ -109740,7 +109924,7 @@ async function detectFramework(cwd) {
|
|
|
109740
109924
|
}
|
|
109741
109925
|
const hasPython = exists(cwd, "requirements.txt", "pyproject.toml");
|
|
109742
109926
|
if (hasPython) {
|
|
109743
|
-
if (
|
|
109927
|
+
if (existsSync12(join16(cwd, "manage.py"))) {
|
|
109744
109928
|
return {
|
|
109745
109929
|
runtime: "python",
|
|
109746
109930
|
framework: "django",
|
|
@@ -109748,7 +109932,7 @@ async function detectFramework(cwd) {
|
|
|
109748
109932
|
data: detectDataMode(pkg, cwd)
|
|
109749
109933
|
};
|
|
109750
109934
|
}
|
|
109751
|
-
const mainPy =
|
|
109935
|
+
const mainPy = existsSync12(join16(cwd, "main.py")) ? readFileSync9(join16(cwd, "main.py"), "utf8") : "";
|
|
109752
109936
|
if (/FastAPI\s*\(/.test(mainPy) || /from\s+fastapi/.test(mainPy)) {
|
|
109753
109937
|
return {
|
|
109754
109938
|
runtime: "python",
|
|
@@ -109757,7 +109941,7 @@ async function detectFramework(cwd) {
|
|
|
109757
109941
|
data: detectDataMode(pkg, cwd)
|
|
109758
109942
|
};
|
|
109759
109943
|
}
|
|
109760
|
-
const appPy =
|
|
109944
|
+
const appPy = existsSync12(join16(cwd, "app.py")) ? readFileSync9(join16(cwd, "app.py"), "utf8") : "";
|
|
109761
109945
|
if (/Flask\s*\(/.test(appPy) || /from\s+flask/.test(appPy)) {
|
|
109762
109946
|
return {
|
|
109763
109947
|
runtime: "python",
|
|
@@ -109772,7 +109956,7 @@ async function detectFramework(cwd) {
|
|
|
109772
109956
|
data: detectDataMode(pkg, cwd)
|
|
109773
109957
|
};
|
|
109774
109958
|
}
|
|
109775
|
-
if (
|
|
109959
|
+
if (existsSync12(join16(cwd, "index.html"))) {
|
|
109776
109960
|
return { runtime: "static" };
|
|
109777
109961
|
}
|
|
109778
109962
|
return null;
|
|
@@ -109822,8 +110006,8 @@ function scanEnvVars(_cwd) {
|
|
|
109822
110006
|
return {};
|
|
109823
110007
|
}
|
|
109824
110008
|
async function init(ctx, input = {}) {
|
|
109825
|
-
const path =
|
|
109826
|
-
const exists2 =
|
|
110009
|
+
const path = join17(ctx.cwd, "percher.toml");
|
|
110010
|
+
const exists2 = existsSync13(path);
|
|
109827
110011
|
if (exists2 && !input.force) {
|
|
109828
110012
|
throw new PercherCoreError("percher.toml already exists", {
|
|
109829
110013
|
code: "init.exists",
|
|
@@ -109836,7 +110020,7 @@ async function init(ctx, input = {}) {
|
|
|
109836
110020
|
if (input.name) {
|
|
109837
110021
|
name = input.name;
|
|
109838
110022
|
} else {
|
|
109839
|
-
const suggestion = generateName(
|
|
110023
|
+
const suggestion = generateName(basename3(ctx.cwd));
|
|
109840
110024
|
const interactive = input.interactive ?? detectInteractive();
|
|
109841
110025
|
if (isSuspiciousAutoName(suggestion) && interactive) {
|
|
109842
110026
|
const answer = (await ctx.prompt(`Suggested app name: '${suggestion}'. Press Enter to accept, or type a different name: `, { default: suggestion })).trim();
|
|
@@ -109870,7 +110054,7 @@ async function init(ctx, input = {}) {
|
|
|
109870
110054
|
if (Object.keys(envVars).length > 0) {
|
|
109871
110055
|
config2.env = envVars;
|
|
109872
110056
|
}
|
|
109873
|
-
|
|
110057
|
+
writeFileSync8(path, serialize(config2), "utf8");
|
|
109874
110058
|
const scaffoldedFiles = [];
|
|
109875
110059
|
if (detected?.staticBuild) {
|
|
109876
110060
|
const targets = [
|
|
@@ -109886,10 +110070,10 @@ async function init(ctx, input = {}) {
|
|
|
109886
110070
|
}
|
|
109887
110071
|
];
|
|
109888
110072
|
for (const { name: name2, content } of targets) {
|
|
109889
|
-
const target =
|
|
109890
|
-
if (
|
|
110073
|
+
const target = join17(ctx.cwd, name2);
|
|
110074
|
+
if (existsSync13(target) && !input.force)
|
|
109891
110075
|
continue;
|
|
109892
|
-
|
|
110076
|
+
writeFileSync8(target, content, "utf8");
|
|
109893
110077
|
scaffoldedFiles.push(name2);
|
|
109894
110078
|
}
|
|
109895
110079
|
}
|
|
@@ -109973,7 +110157,7 @@ async function login(ctx, input = {}) {
|
|
|
109973
110157
|
return validateAndPersist(ctx, input.apiUrl, result.token);
|
|
109974
110158
|
}
|
|
109975
110159
|
if (code.interval > 0) {
|
|
109976
|
-
await new Promise((
|
|
110160
|
+
await new Promise((resolve7) => setTimeout(resolve7, code.interval * 1000));
|
|
109977
110161
|
}
|
|
109978
110162
|
}
|
|
109979
110163
|
throw new PercherCoreError("Login timed out. Re-run `percher login`.", {
|
|
@@ -110890,16 +111074,277 @@ function collectWarnings2(collections, rlsPolicies, unsupported) {
|
|
|
110890
111074
|
}
|
|
110891
111075
|
// ../core/dist/commands/migrate-supabase-rewrite.js
|
|
110892
111076
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
110893
|
-
import { dirname as
|
|
111077
|
+
import { dirname as dirname6, join as join20, relative as relative6, resolve as resolve9, sep as sep5 } from "node:path";
|
|
110894
111078
|
|
|
110895
|
-
// ../core/dist/commands/migrate-supabase-
|
|
110896
|
-
var
|
|
110897
|
-
|
|
110898
|
-
|
|
111079
|
+
// ../core/dist/commands/migrate-supabase-recipes.js
|
|
111080
|
+
var AUTH_RECIPES = {
|
|
111081
|
+
"auth.getSession": {
|
|
111082
|
+
title: "getSession → pb.authStore",
|
|
111083
|
+
recipe: "PocketBase keeps the session in `pb.authStore` (local, synchronous — no await). Replace `const { data: { session } } = await supabase.auth.getSession()` with `pb.authStore.isValid` (logged in?), `pb.authStore.record` (the user record), and `pb.authStore.token` (the JWT)."
|
|
111084
|
+
},
|
|
111085
|
+
"auth.getClaims": {
|
|
111086
|
+
title: "getClaims → pb.authStore.record",
|
|
111087
|
+
recipe: "PocketBase has no separate claims endpoint. The authenticated user's fields live on `pb.authStore.record`; use `pb.authStore.isValid` for the logged-in check. Read them directly — no await, no token decode."
|
|
111088
|
+
},
|
|
111089
|
+
"auth.getUser": {
|
|
111090
|
+
title: "getUser → pb.authStore.record",
|
|
111091
|
+
recipe: "`pb.authStore.record` is the current user record (or null), read synchronously. Supabase's `getUser()` returns `Promise<{ data: { user } }>`, so drop the await and the `.data.user` unwrap."
|
|
111092
|
+
},
|
|
111093
|
+
"auth.signInWithOtp": {
|
|
111094
|
+
title: "signInWithOtp → requestOTP + authWithOTP",
|
|
111095
|
+
recipe: "PocketBase email-OTP is two steps: `const req = await pb.collection('users').requestOTP(email)` sends the code, then on a second screen `await pb.collection('users').authWithOTP(req.otpId, code)` verifies it. Supabase's single magic-link `signInWithOtp` maps to the first step — you'll add a code-entry screen for the second."
|
|
111096
|
+
},
|
|
111097
|
+
"auth.verifyOtp": {
|
|
111098
|
+
title: "verifyOtp → authWithOTP",
|
|
111099
|
+
recipe: "Pairs with requestOTP: `await pb.collection('users').authWithOTP(otpId, code)` (otpId comes from the requestOTP response, not from the email link). Supabase's `token_hash` / `type` model doesn't carry over — keep the otpId from step one in component state."
|
|
111100
|
+
},
|
|
111101
|
+
"auth.resetPasswordForEmail": {
|
|
111102
|
+
title: "resetPasswordForEmail → requestPasswordReset",
|
|
111103
|
+
recipe: "`await pb.collection('users').requestPasswordReset(email)` sends the reset email. The confirm step lives on your reset page: `await pb.collection('users').confirmPasswordReset(token, newPassword, newPasswordConfirm)` (token comes from the email link)."
|
|
111104
|
+
},
|
|
111105
|
+
"auth.updateUser": {
|
|
111106
|
+
title: "updateUser → collection('users').update",
|
|
111107
|
+
recipe: "PocketBase updates by record id: `await pb.collection('users').update(pb.authStore.record.id, { ... })`. There's no implicit current-user update — pass the id explicitly. Email/password changes use the dedicated `requestEmailChange` / `confirmEmailChange` flows."
|
|
111108
|
+
},
|
|
111109
|
+
"auth.refreshSession": {
|
|
111110
|
+
title: "refreshSession → authRefresh",
|
|
111111
|
+
recipe: "`await pb.collection('users').authRefresh()` re-validates the stored token and refreshes `pb.authStore`. There's no refresh-token rotation to manage — PocketBase reissues the JWT in place."
|
|
111112
|
+
},
|
|
111113
|
+
"auth.onAuthStateChange": {
|
|
111114
|
+
title: "onAuthStateChange → pb.authStore.onChange",
|
|
111115
|
+
recipe: "`const unsubscribe = pb.authStore.onChange((token, record) => { ... })`. The callback receives `(token, record)`, NOT Supabase's `(event, session)` — there's no event-type string, so branch on `pb.authStore.isValid` inside the callback. It returns an unsubscribe function; call it on teardown."
|
|
111116
|
+
}
|
|
111117
|
+
};
|
|
111118
|
+
function recipeFor(pattern) {
|
|
111119
|
+
return AUTH_RECIPES[pattern] ?? null;
|
|
111120
|
+
}
|
|
111121
|
+
var GENERAL_AUTH_RECIPES = [
|
|
111122
|
+
{
|
|
111123
|
+
title: "Route guards → pb.authStore.isValid",
|
|
111124
|
+
recipe: "Gate protected routes on `pb.authStore.isValid` instead of inspecting a session object, e.g. `if (!pb.authStore.isValid) redirect('/login')`. `pb.authStore` is restored from storage on load, so the check works on the first render."
|
|
111125
|
+
}
|
|
111126
|
+
];
|
|
111127
|
+
function renderRecipesSection(patterns2) {
|
|
111128
|
+
const seen = new Set;
|
|
111129
|
+
const recipes = [];
|
|
111130
|
+
for (const pattern of patterns2) {
|
|
111131
|
+
const recipe = recipeFor(pattern);
|
|
111132
|
+
if (recipe && !seen.has(recipe.title)) {
|
|
111133
|
+
seen.add(recipe.title);
|
|
111134
|
+
recipes.push(recipe);
|
|
111135
|
+
}
|
|
111136
|
+
}
|
|
111137
|
+
if (recipes.length === 0)
|
|
111138
|
+
return [];
|
|
111139
|
+
const lines = [];
|
|
111140
|
+
lines.push("## Recipes — Supabase auth → PocketBase");
|
|
111141
|
+
lines.push("");
|
|
111142
|
+
lines.push("Concrete PocketBase equivalents for the auth calls above. These are NOT auto-applied — the Supabase call is left in place so the app keeps working until you migrate it deliberately. See https://pocketbase.io/docs/authentication/.");
|
|
111143
|
+
lines.push("");
|
|
111144
|
+
for (const recipe of [...recipes, ...GENERAL_AUTH_RECIPES]) {
|
|
111145
|
+
lines.push(`### ${recipe.title}`);
|
|
111146
|
+
lines.push("");
|
|
111147
|
+
lines.push(recipe.recipe);
|
|
111148
|
+
lines.push("");
|
|
111149
|
+
}
|
|
111150
|
+
return lines;
|
|
111151
|
+
}
|
|
110899
111152
|
|
|
110900
|
-
// ../core/dist/commands/migrate-supabase-
|
|
111153
|
+
// ../core/dist/commands/migrate-supabase-scaffold.js
|
|
110901
111154
|
var import_jscodeshift = __toESM(require_core3(), 1);
|
|
111155
|
+
import { posix } from "node:path";
|
|
110902
111156
|
var tsx = import_jscodeshift.default.withParser("tsx");
|
|
111157
|
+
var CLIENT_FACTORIES = new Set(["createClient", "createBrowserClient", "createServerClient"]);
|
|
111158
|
+
function scaffoldPocketBaseClient(input) {
|
|
111159
|
+
const pbName = input.pbIdentifier ?? "pb";
|
|
111160
|
+
const codeFiles = input.files.filter((f) => f.kind === "code");
|
|
111161
|
+
const flags = [];
|
|
111162
|
+
for (const file2 of codeFiles) {
|
|
111163
|
+
if (isSupabaseClientModule(file2.source)) {
|
|
111164
|
+
flags.push({
|
|
111165
|
+
file: file2.relativePath,
|
|
111166
|
+
kind: "manual_review",
|
|
111167
|
+
pattern: "supabase.client_module",
|
|
111168
|
+
note: "This module sets up the Supabase client. It's kept while any Supabase call remains; once everything is migrated to PocketBase, delete it and the imports that reference it."
|
|
111169
|
+
});
|
|
111170
|
+
}
|
|
111171
|
+
}
|
|
111172
|
+
const existing = codeFiles.find((f) => exportsBinding(f.rewritten, pbName));
|
|
111173
|
+
let targetRelNoExt;
|
|
111174
|
+
let clientModule = null;
|
|
111175
|
+
let skippedReason;
|
|
111176
|
+
if (existing) {
|
|
111177
|
+
targetRelNoExt = stripExt(existing.relativePath);
|
|
111178
|
+
skippedReason = "pb_client_exists";
|
|
111179
|
+
} else {
|
|
111180
|
+
const ext = pickExtension(codeFiles);
|
|
111181
|
+
const baseNoExt = pickModuleBase(codeFiles);
|
|
111182
|
+
const targetRel = `${baseNoExt}.${ext}`;
|
|
111183
|
+
if (input.files.some((f) => f.relativePath === targetRel)) {
|
|
111184
|
+
flags.push({
|
|
111185
|
+
file: targetRel,
|
|
111186
|
+
kind: "manual_review",
|
|
111187
|
+
pattern: "scaffold.path_taken",
|
|
111188
|
+
note: `Couldn't auto-create a PocketBase client — \`${targetRel}\` already exists. Create one that exports \`${pbName}\` and import it in the rewritten files.`
|
|
111189
|
+
});
|
|
111190
|
+
return {
|
|
111191
|
+
clientModule: null,
|
|
111192
|
+
importInsertions: new Map,
|
|
111193
|
+
flags,
|
|
111194
|
+
skippedReason: "target_path_taken"
|
|
111195
|
+
};
|
|
111196
|
+
}
|
|
111197
|
+
targetRelNoExt = baseNoExt;
|
|
111198
|
+
clientModule = { relativePath: targetRel, content: renderClientModule(pbName, codeFiles) };
|
|
111199
|
+
}
|
|
111200
|
+
const importInsertions = new Map;
|
|
111201
|
+
const changed = new Set(input.changedRelPaths);
|
|
111202
|
+
for (const file2 of codeFiles) {
|
|
111203
|
+
if (!changed.has(file2.relativePath))
|
|
111204
|
+
continue;
|
|
111205
|
+
if (file2.relativePath === clientModule?.relativePath)
|
|
111206
|
+
continue;
|
|
111207
|
+
if (!referencesUnboundIdentifier(file2.rewritten, pbName))
|
|
111208
|
+
continue;
|
|
111209
|
+
const importPath = computeImportPath(file2.relativePath, targetRelNoExt);
|
|
111210
|
+
const next = insertNamedImport(file2.rewritten, pbName, importPath);
|
|
111211
|
+
if (next !== null)
|
|
111212
|
+
importInsertions.set(file2.relativePath, next);
|
|
111213
|
+
}
|
|
111214
|
+
return { clientModule, importInsertions, flags, ...skippedReason ? { skippedReason } : {} };
|
|
111215
|
+
}
|
|
111216
|
+
function renderClientModule(pbName, codeFiles) {
|
|
111217
|
+
const usesViteEnv = codeFiles.some((f) => f.source.includes("import.meta.env"));
|
|
111218
|
+
const accessor = usesViteEnv ? "import.meta.env.VITE_POCKETBASE_URL" : "process.env.POCKETBASE_URL";
|
|
111219
|
+
return [
|
|
111220
|
+
'import PocketBase from "pocketbase";',
|
|
111221
|
+
"",
|
|
111222
|
+
"// Percher injects the PocketBase URL at deploy time. This is a working",
|
|
111223
|
+
"// default — adjust the URL accessor to match your framework if needed.",
|
|
111224
|
+
`export const ${pbName} = new PocketBase(${accessor});`,
|
|
111225
|
+
""
|
|
111226
|
+
].join(`
|
|
111227
|
+
`);
|
|
111228
|
+
}
|
|
111229
|
+
function pickExtension(codeFiles) {
|
|
111230
|
+
return codeFiles.some((f) => f.relativePath.endsWith(".ts") || f.relativePath.endsWith(".tsx")) ? "ts" : "js";
|
|
111231
|
+
}
|
|
111232
|
+
function pickModuleBase(codeFiles) {
|
|
111233
|
+
const hasSrc = codeFiles.some((f) => f.relativePath.startsWith("src/"));
|
|
111234
|
+
return hasSrc ? "src/lib/pocketbase" : "lib/pocketbase";
|
|
111235
|
+
}
|
|
111236
|
+
function stripExt(relPath) {
|
|
111237
|
+
const dot = relPath.lastIndexOf(".");
|
|
111238
|
+
return dot > relPath.lastIndexOf("/") ? relPath.slice(0, dot) : relPath;
|
|
111239
|
+
}
|
|
111240
|
+
function computeImportPath(fromFileRel, targetRelNoExt) {
|
|
111241
|
+
let rel = posix.relative(posix.dirname(fromFileRel), targetRelNoExt);
|
|
111242
|
+
if (!rel.startsWith("."))
|
|
111243
|
+
rel = `./${rel}`;
|
|
111244
|
+
return rel;
|
|
111245
|
+
}
|
|
111246
|
+
function insertNamedImport(source, name, spec) {
|
|
111247
|
+
let root;
|
|
111248
|
+
try {
|
|
111249
|
+
root = tsx(source);
|
|
111250
|
+
} catch {
|
|
111251
|
+
return null;
|
|
111252
|
+
}
|
|
111253
|
+
const decl = import_jscodeshift.default.importDeclaration([import_jscodeshift.default.importSpecifier(import_jscodeshift.default.identifier(name))], import_jscodeshift.default.literal(spec));
|
|
111254
|
+
const program = root.get().node.program;
|
|
111255
|
+
program.body.unshift(decl);
|
|
111256
|
+
return root.toSource({ quote: "double" });
|
|
111257
|
+
}
|
|
111258
|
+
function referencesUnboundIdentifier(source, name) {
|
|
111259
|
+
let root;
|
|
111260
|
+
try {
|
|
111261
|
+
root = tsx(source);
|
|
111262
|
+
} catch {
|
|
111263
|
+
return false;
|
|
111264
|
+
}
|
|
111265
|
+
let declared = false;
|
|
111266
|
+
root.find(import_jscodeshift.default.ImportDeclaration).forEach((p) => {
|
|
111267
|
+
for (const spec of p.node.specifiers ?? []) {
|
|
111268
|
+
if (spec.local?.name === name)
|
|
111269
|
+
declared = true;
|
|
111270
|
+
}
|
|
111271
|
+
});
|
|
111272
|
+
root.find(import_jscodeshift.default.VariableDeclarator).forEach((p) => {
|
|
111273
|
+
if (p.node.id.type === "Identifier" && p.node.id.name === name) {
|
|
111274
|
+
declared = true;
|
|
111275
|
+
}
|
|
111276
|
+
});
|
|
111277
|
+
let used = false;
|
|
111278
|
+
root.find(import_jscodeshift.default.MemberExpression).forEach((p) => {
|
|
111279
|
+
const obj = p.node.object;
|
|
111280
|
+
if (obj.type === "Identifier" && obj.name === name)
|
|
111281
|
+
used = true;
|
|
111282
|
+
});
|
|
111283
|
+
return used && !declared;
|
|
111284
|
+
}
|
|
111285
|
+
function exportsBinding(source, name) {
|
|
111286
|
+
if (!source.includes(`export`) || !source.includes(name))
|
|
111287
|
+
return false;
|
|
111288
|
+
let root;
|
|
111289
|
+
try {
|
|
111290
|
+
root = tsx(source);
|
|
111291
|
+
} catch {
|
|
111292
|
+
return false;
|
|
111293
|
+
}
|
|
111294
|
+
let found = false;
|
|
111295
|
+
root.find(import_jscodeshift.default.ExportNamedDeclaration).forEach((p) => {
|
|
111296
|
+
const node = p.node;
|
|
111297
|
+
if (node.declaration?.type === "VariableDeclaration") {
|
|
111298
|
+
for (const d of node.declaration.declarations) {
|
|
111299
|
+
if (d.type === "VariableDeclarator" && d.id.type === "Identifier" && d.id.name === name) {
|
|
111300
|
+
found = true;
|
|
111301
|
+
}
|
|
111302
|
+
}
|
|
111303
|
+
}
|
|
111304
|
+
for (const spec of node.specifiers ?? []) {
|
|
111305
|
+
const exported = spec.exported;
|
|
111306
|
+
if (exported?.type === "Identifier" && exported.name === name) {
|
|
111307
|
+
found = true;
|
|
111308
|
+
}
|
|
111309
|
+
}
|
|
111310
|
+
});
|
|
111311
|
+
return found;
|
|
111312
|
+
}
|
|
111313
|
+
function isSupabaseClientModule(source) {
|
|
111314
|
+
if (!source.includes("@supabase/"))
|
|
111315
|
+
return false;
|
|
111316
|
+
let root;
|
|
111317
|
+
try {
|
|
111318
|
+
root = tsx(source);
|
|
111319
|
+
} catch {
|
|
111320
|
+
return false;
|
|
111321
|
+
}
|
|
111322
|
+
let importsSupabase = false;
|
|
111323
|
+
root.find(import_jscodeshift.default.ImportDeclaration).forEach((p) => {
|
|
111324
|
+
const src = p.node.source.value;
|
|
111325
|
+
if (typeof src === "string" && src.startsWith("@supabase/"))
|
|
111326
|
+
importsSupabase = true;
|
|
111327
|
+
});
|
|
111328
|
+
if (!importsSupabase)
|
|
111329
|
+
return false;
|
|
111330
|
+
let callsFactory = false;
|
|
111331
|
+
root.find(import_jscodeshift.default.CallExpression).forEach((p) => {
|
|
111332
|
+
const callee = p.node.callee;
|
|
111333
|
+
if (callee.type === "Identifier" && CLIENT_FACTORIES.has(callee.name)) {
|
|
111334
|
+
callsFactory = true;
|
|
111335
|
+
}
|
|
111336
|
+
});
|
|
111337
|
+
return callsFactory;
|
|
111338
|
+
}
|
|
111339
|
+
|
|
111340
|
+
// ../core/dist/commands/migrate-supabase-status.js
|
|
111341
|
+
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
111342
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
111343
|
+
import { join as join19, relative as relative5, resolve as resolve8 } from "node:path";
|
|
111344
|
+
|
|
111345
|
+
// ../core/dist/commands/migrate-supabase-sdk.js
|
|
111346
|
+
var import_jscodeshift2 = __toESM(require_core3(), 1);
|
|
111347
|
+
var tsx2 = import_jscodeshift2.default.withParser("tsx");
|
|
110903
111348
|
function rewriteSupabaseSdk(input) {
|
|
110904
111349
|
const pbName = input.pbIdentifier ?? "pb";
|
|
110905
111350
|
const supabaseNames = new Set(input.supabaseIdentifiers ?? ["supabase"]);
|
|
@@ -110908,7 +111353,7 @@ function rewriteSupabaseSdk(input) {
|
|
|
110908
111353
|
}
|
|
110909
111354
|
let root;
|
|
110910
111355
|
try {
|
|
110911
|
-
root =
|
|
111356
|
+
root = tsx2(input.source);
|
|
110912
111357
|
} catch (err) {
|
|
110913
111358
|
return {
|
|
110914
111359
|
rewritten: input.source,
|
|
@@ -110991,7 +111436,7 @@ function sourceMentionsSupabase(source, supabaseNames) {
|
|
|
110991
111436
|
return false;
|
|
110992
111437
|
}
|
|
110993
111438
|
function rewriteAuthCalls(root, supabaseNames, pbName, flags, state) {
|
|
110994
|
-
root.find(
|
|
111439
|
+
root.find(import_jscodeshift2.default.CallExpression).filter((path) => isSupabaseAuthCall(path, supabaseNames)).forEach((path) => {
|
|
110995
111440
|
const callee = path.node.callee;
|
|
110996
111441
|
const method = callee.property.name;
|
|
110997
111442
|
switch (method) {
|
|
@@ -111010,6 +111455,12 @@ function rewriteAuthCalls(root, supabaseNames, pbName, flags, state) {
|
|
|
111010
111455
|
case "onAuthStateChange":
|
|
111011
111456
|
replaceAuthOnChange(path, pbName, flags, state);
|
|
111012
111457
|
return;
|
|
111458
|
+
default: {
|
|
111459
|
+
const recipe = recipeFor(`auth.${method}`);
|
|
111460
|
+
const note = recipe ? `supabase.auth.${method}(...) isn't auto-translated (the PB equivalent diverges) — it still calls Supabase. ${recipe.recipe}` : `supabase.auth.${method}(...) isn't auto-translated — it still calls Supabase. Map it to PocketBase's auth API by hand (https://pocketbase.io/docs/authentication/).`;
|
|
111461
|
+
flags.push(makeFlag(path, "unsupported", `auth.${method}`, note));
|
|
111462
|
+
return;
|
|
111463
|
+
}
|
|
111013
111464
|
}
|
|
111014
111465
|
});
|
|
111015
111466
|
}
|
|
@@ -111019,7 +111470,7 @@ function replaceAuthOnChange(path, pbName, flags, state) {
|
|
|
111019
111470
|
flags.push(makeFlag(path, "manual_review", "auth.onAuthStateChange", "onAuthStateChange called with no args — manual review."));
|
|
111020
111471
|
return;
|
|
111021
111472
|
}
|
|
111022
|
-
const replacement =
|
|
111473
|
+
const replacement = import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.identifier(pbName), import_jscodeshift2.default.identifier("authStore")), import_jscodeshift2.default.identifier("onChange")), [callback]);
|
|
111023
111474
|
applyRewrite(path, replacement, "manual_review", "auth.onAuthStateChange", "onAuthStateChange → pb.authStore.onChange — the callback signature changes: Supabase passes `(event, session)`, PB passes `(token, model)`. Rewrite the callback body.", flags, state);
|
|
111024
111475
|
}
|
|
111025
111476
|
function isSupabaseAuthCall(path, supabaseNames) {
|
|
@@ -111053,7 +111504,7 @@ function replaceAuthSignIn(path, pbName, flags, state) {
|
|
|
111053
111504
|
flagEnvelopeManualReview(path, "auth.signInWithPassword", flags);
|
|
111054
111505
|
return;
|
|
111055
111506
|
}
|
|
111056
|
-
const replacement =
|
|
111507
|
+
const replacement = import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.identifier(pbName), import_jscodeshift2.default.identifier("collection")), [import_jscodeshift2.default.literal("users")]), import_jscodeshift2.default.identifier("authWithPassword")), [emailExpr, passwordExpr]);
|
|
111057
111508
|
applyRewrite(path, replacement, "rewritten", "auth.signInWithPassword", 'signInWithPassword → pb.collection("users").authWithPassword', flags, state);
|
|
111058
111509
|
}
|
|
111059
111510
|
function replaceAuthSignUp(path, pbName, flags, state) {
|
|
@@ -111072,11 +111523,11 @@ function replaceAuthSignUp(path, pbName, flags, state) {
|
|
|
111072
111523
|
flagEnvelopeManualReview(path, "auth.signUp", flags);
|
|
111073
111524
|
return;
|
|
111074
111525
|
}
|
|
111075
|
-
const replacement =
|
|
111076
|
-
|
|
111077
|
-
|
|
111078
|
-
|
|
111079
|
-
|
|
111526
|
+
const replacement = import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.identifier(pbName), import_jscodeshift2.default.identifier("collection")), [import_jscodeshift2.default.literal("users")]), import_jscodeshift2.default.identifier("create")), [
|
|
111527
|
+
import_jscodeshift2.default.objectExpression([
|
|
111528
|
+
import_jscodeshift2.default.property("init", import_jscodeshift2.default.identifier("email"), emailExpr),
|
|
111529
|
+
import_jscodeshift2.default.property("init", import_jscodeshift2.default.identifier("password"), passwordExpr),
|
|
111530
|
+
import_jscodeshift2.default.property("init", import_jscodeshift2.default.identifier("passwordConfirm"), passwordExpr)
|
|
111080
111531
|
])
|
|
111081
111532
|
]);
|
|
111082
111533
|
applyRewrite(path, replacement, "rewritten", "auth.signUp", 'signUp → pb.collection("users").create({...passwordConfirm})', flags, state);
|
|
@@ -111086,7 +111537,7 @@ function replaceAuthSignOut(path, pbName, flags, state) {
|
|
|
111086
111537
|
flagEnvelopeManualReview(path, "auth.signOut", flags);
|
|
111087
111538
|
return;
|
|
111088
111539
|
}
|
|
111089
|
-
const replacement =
|
|
111540
|
+
const replacement = import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.identifier(pbName), import_jscodeshift2.default.identifier("authStore")), import_jscodeshift2.default.identifier("clear")), []);
|
|
111090
111541
|
applyRewrite(path, replacement, "rewritten", "auth.signOut", "signOut → pb.authStore.clear()", flags, state);
|
|
111091
111542
|
}
|
|
111092
111543
|
function replaceAuthGetUser(path, pbName, flags, state) {
|
|
@@ -111094,11 +111545,11 @@ function replaceAuthGetUser(path, pbName, flags, state) {
|
|
|
111094
111545
|
flagEnvelopeManualReview(path, "auth.getUser", flags);
|
|
111095
111546
|
return;
|
|
111096
111547
|
}
|
|
111097
|
-
const replacement =
|
|
111548
|
+
const replacement = import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.identifier(pbName), import_jscodeshift2.default.identifier("authStore")), import_jscodeshift2.default.identifier("model"));
|
|
111098
111549
|
applyRewrite(path, replacement, "manual_review", "auth.getUser", "getUser → pb.authStore.model — note Supabase returned Promise<{ data: { user } }>, PB returns the record sync; remove awaits + .data.user access.", flags, state);
|
|
111099
111550
|
}
|
|
111100
111551
|
function rewriteFromCalls(root, supabaseNames, pbName, flags, state) {
|
|
111101
|
-
root.find(
|
|
111552
|
+
root.find(import_jscodeshift2.default.CallExpression).filter((path) => isSupabaseFromTerminal(path, supabaseNames)).forEach((path) => {
|
|
111102
111553
|
rewriteFromChain(path, supabaseNames, pbName, flags, state);
|
|
111103
111554
|
});
|
|
111104
111555
|
}
|
|
@@ -111204,7 +111655,7 @@ function rewriteSelect(path, pbName, table, steps, flags, state) {
|
|
|
111204
111655
|
let paginationPerPage = 0;
|
|
111205
111656
|
const fieldsValue = extractSelectFields(select);
|
|
111206
111657
|
if (fieldsValue !== null)
|
|
111207
|
-
opts.fields =
|
|
111658
|
+
opts.fields = import_jscodeshift2.default.literal(fieldsValue);
|
|
111208
111659
|
for (const step of tail) {
|
|
111209
111660
|
switch (step.method) {
|
|
111210
111661
|
case "eq": {
|
|
@@ -111228,7 +111679,7 @@ function rewriteSelect(path, pbName, table, steps, flags, state) {
|
|
|
111228
111679
|
reviewNotes.push(`.order() arguments not in the recognised shape — manual review.`);
|
|
111229
111680
|
continue;
|
|
111230
111681
|
}
|
|
111231
|
-
opts.sort =
|
|
111682
|
+
opts.sort = import_jscodeshift2.default.literal(opts.sort ? `${literalString(opts.sort)},${sortFrag}` : sortFrag);
|
|
111232
111683
|
break;
|
|
111233
111684
|
}
|
|
111234
111685
|
case "limit": {
|
|
@@ -111289,7 +111740,7 @@ function rewriteSelect(path, pbName, table, steps, flags, state) {
|
|
|
111289
111740
|
if (usePagination) {
|
|
111290
111741
|
methodName = "getList";
|
|
111291
111742
|
const trailingOpts = buildOptionsObject(opts);
|
|
111292
|
-
methodArgs = [
|
|
111743
|
+
methodArgs = [import_jscodeshift2.default.literal(paginationPage), import_jscodeshift2.default.literal(paginationPerPage)];
|
|
111293
111744
|
if (trailingOpts)
|
|
111294
111745
|
methodArgs.push(trailingOpts);
|
|
111295
111746
|
} else {
|
|
@@ -111297,7 +111748,7 @@ function rewriteSelect(path, pbName, table, steps, flags, state) {
|
|
|
111297
111748
|
const optsObj = buildOptionsObject(opts);
|
|
111298
111749
|
methodArgs = optsObj ? [optsObj] : [];
|
|
111299
111750
|
}
|
|
111300
|
-
const replacement =
|
|
111751
|
+
const replacement = import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.identifier(pbName), import_jscodeshift2.default.identifier("collection")), [import_jscodeshift2.default.literal(table)]), import_jscodeshift2.default.identifier(methodName)), methodArgs);
|
|
111301
111752
|
const kind = needsReview ? "manual_review" : "rewritten";
|
|
111302
111753
|
const baseNote = `from(${JSON.stringify(table)}).select(...) → pb.collection(...).${methodName}(...)`;
|
|
111303
111754
|
const note = needsReview ? `${baseNote} — ${reviewNotes.join(" · ")}` : baseNote;
|
|
@@ -111328,23 +111779,23 @@ function buildEqFilter(step) {
|
|
|
111328
111779
|
const v = valArg.value;
|
|
111329
111780
|
if (typeof v === "string") {
|
|
111330
111781
|
return {
|
|
111331
|
-
expression:
|
|
111782
|
+
expression: import_jscodeshift2.default.literal(`${column} = "${escapeFilterString(v)}"`),
|
|
111332
111783
|
column,
|
|
111333
111784
|
identifierValue: false
|
|
111334
111785
|
};
|
|
111335
111786
|
}
|
|
111336
111787
|
if (typeof v === "number" || typeof v === "boolean") {
|
|
111337
111788
|
return {
|
|
111338
|
-
expression:
|
|
111789
|
+
expression: import_jscodeshift2.default.literal(`${column} = ${v}`),
|
|
111339
111790
|
column,
|
|
111340
111791
|
identifierValue: false
|
|
111341
111792
|
};
|
|
111342
111793
|
}
|
|
111343
111794
|
return null;
|
|
111344
111795
|
}
|
|
111345
|
-
const template =
|
|
111346
|
-
|
|
111347
|
-
|
|
111796
|
+
const template = import_jscodeshift2.default.templateLiteral([
|
|
111797
|
+
import_jscodeshift2.default.templateElement({ raw: `${column} = "`, cooked: `${column} = "` }, false),
|
|
111798
|
+
import_jscodeshift2.default.templateElement({ raw: `"`, cooked: `"` }, true)
|
|
111348
111799
|
], [valArg]);
|
|
111349
111800
|
return {
|
|
111350
111801
|
expression: template,
|
|
@@ -111361,17 +111812,17 @@ function combineFilterStatic(current, next) {
|
|
|
111361
111812
|
const a = literalString(current);
|
|
111362
111813
|
const b = literalString(next);
|
|
111363
111814
|
if (a !== null && b !== null) {
|
|
111364
|
-
return
|
|
111815
|
+
return import_jscodeshift2.default.literal(`(${a}) && (${b})`);
|
|
111365
111816
|
}
|
|
111366
111817
|
return combineFilterDynamic(current, next);
|
|
111367
111818
|
}
|
|
111368
111819
|
function combineFilterDynamic(current, next) {
|
|
111369
111820
|
if (!current)
|
|
111370
111821
|
return next;
|
|
111371
|
-
return
|
|
111372
|
-
|
|
111373
|
-
|
|
111374
|
-
|
|
111822
|
+
return import_jscodeshift2.default.templateLiteral([
|
|
111823
|
+
import_jscodeshift2.default.templateElement({ raw: "(", cooked: "(" }, false),
|
|
111824
|
+
import_jscodeshift2.default.templateElement({ raw: ") && (", cooked: ") && (" }, false),
|
|
111825
|
+
import_jscodeshift2.default.templateElement({ raw: ")", cooked: ")" }, true)
|
|
111375
111826
|
], [current, next]);
|
|
111376
111827
|
}
|
|
111377
111828
|
function literalString(node) {
|
|
@@ -111425,17 +111876,17 @@ function extractNumber(node) {
|
|
|
111425
111876
|
function buildOptionsObject(opts) {
|
|
111426
111877
|
const props = [];
|
|
111427
111878
|
if (opts.fields !== undefined) {
|
|
111428
|
-
props.push(
|
|
111879
|
+
props.push(import_jscodeshift2.default.property("init", import_jscodeshift2.default.identifier("fields"), opts.fields));
|
|
111429
111880
|
}
|
|
111430
111881
|
if (opts.filter !== undefined) {
|
|
111431
|
-
props.push(
|
|
111882
|
+
props.push(import_jscodeshift2.default.property("init", import_jscodeshift2.default.identifier("filter"), opts.filter));
|
|
111432
111883
|
}
|
|
111433
111884
|
if (opts.sort !== undefined) {
|
|
111434
|
-
props.push(
|
|
111885
|
+
props.push(import_jscodeshift2.default.property("init", import_jscodeshift2.default.identifier("sort"), opts.sort));
|
|
111435
111886
|
}
|
|
111436
111887
|
if (props.length === 0)
|
|
111437
111888
|
return null;
|
|
111438
|
-
return
|
|
111889
|
+
return import_jscodeshift2.default.objectExpression(props);
|
|
111439
111890
|
}
|
|
111440
111891
|
function rewriteInsert(path, pbName, table, insert, flags, state) {
|
|
111441
111892
|
if (consumesDataErrorEnvelope(path)) {
|
|
@@ -111451,7 +111902,7 @@ function rewriteInsert(path, pbName, table, insert, flags, state) {
|
|
|
111451
111902
|
flags.push(makeFlag(path, "manual_review", "from.insert.array", `from(${JSON.stringify(table)}).insert([...]) — PB's create takes one record at a time; wrap in a loop.`));
|
|
111452
111903
|
return;
|
|
111453
111904
|
}
|
|
111454
|
-
const replacement =
|
|
111905
|
+
const replacement = import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.identifier(pbName), import_jscodeshift2.default.identifier("collection")), [import_jscodeshift2.default.literal(table)]), import_jscodeshift2.default.identifier("create")), [arg]);
|
|
111455
111906
|
applyRewrite(path, replacement, "rewritten", "from.insert", `from(${JSON.stringify(table)}).insert({...}) → pb.collection(...).create({...})`, flags, state);
|
|
111456
111907
|
}
|
|
111457
111908
|
function rewriteUpdate(path, pbName, table, steps, flags, state) {
|
|
@@ -111480,7 +111931,7 @@ function rewriteUpdate(path, pbName, table, steps, flags, state) {
|
|
|
111480
111931
|
flags.push(makeFlag(path, "manual_review", "from.update", "update() called with no args — manual review."));
|
|
111481
111932
|
return;
|
|
111482
111933
|
}
|
|
111483
|
-
const replacement =
|
|
111934
|
+
const replacement = import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.identifier(pbName), import_jscodeshift2.default.identifier("collection")), [import_jscodeshift2.default.literal(table)]), import_jscodeshift2.default.identifier("update")), [eqVal, updateArg]);
|
|
111484
111935
|
applyRewrite(path, replacement, "rewritten", "from.update", `from(${JSON.stringify(table)}).update({...}).eq("id", v) → pb.collection(...).update(v, {...})`, flags, state);
|
|
111485
111936
|
}
|
|
111486
111937
|
function rewriteDelete(path, pbName, table, steps, flags, state) {
|
|
@@ -111503,11 +111954,11 @@ function rewriteDelete(path, pbName, table, steps, flags, state) {
|
|
|
111503
111954
|
flags.push(makeFlag(path, "manual_review", "from.delete.eq_non_id", `from(${JSON.stringify(table)}).delete().eq() filters on a non-id column — PB's delete needs an id; chunk 2 will handle filter-based deletes.`));
|
|
111504
111955
|
return;
|
|
111505
111956
|
}
|
|
111506
|
-
const replacement =
|
|
111957
|
+
const replacement = import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.callExpression(import_jscodeshift2.default.memberExpression(import_jscodeshift2.default.identifier(pbName), import_jscodeshift2.default.identifier("collection")), [import_jscodeshift2.default.literal(table)]), import_jscodeshift2.default.identifier("delete")), [eqVal]);
|
|
111507
111958
|
applyRewrite(path, replacement, "rewritten", "from.delete", `from(${JSON.stringify(table)}).delete().eq("id", v) → pb.collection(...).delete(v)`, flags, state);
|
|
111508
111959
|
}
|
|
111509
111960
|
function flagUnsupportedPatterns(root, supabaseNames, flags) {
|
|
111510
|
-
root.find(
|
|
111961
|
+
root.find(import_jscodeshift2.default.CallExpression).forEach((path) => {
|
|
111511
111962
|
flagOneUnsupported(path, supabaseNames, flags);
|
|
111512
111963
|
});
|
|
111513
111964
|
}
|
|
@@ -111646,11 +112097,148 @@ function readFirstStringArg(call) {
|
|
|
111646
112097
|
}
|
|
111647
112098
|
return null;
|
|
111648
112099
|
}
|
|
112100
|
+
var EMPTY_SCAN = {
|
|
112101
|
+
importsSupabase: false,
|
|
112102
|
+
authCalls: 0,
|
|
112103
|
+
fromCalls: 0,
|
|
112104
|
+
storage: 0,
|
|
112105
|
+
rpc: 0,
|
|
112106
|
+
realtime: 0,
|
|
112107
|
+
edgeFunctions: 0,
|
|
112108
|
+
usesPb: false,
|
|
112109
|
+
danglingPb: false
|
|
112110
|
+
};
|
|
112111
|
+
function scanSupabaseUsage(input) {
|
|
112112
|
+
const supabaseNames = new Set(input.supabaseIdentifiers ?? ["supabase"]);
|
|
112113
|
+
const pbName = input.pbIdentifier ?? "pb";
|
|
112114
|
+
const mentionsSupabase = sourceMentionsSupabase(input.source, supabaseNames);
|
|
112115
|
+
const mentionsPb = input.source.includes(pbName);
|
|
112116
|
+
if (!mentionsSupabase && !mentionsPb)
|
|
112117
|
+
return { ...EMPTY_SCAN };
|
|
112118
|
+
let root;
|
|
112119
|
+
try {
|
|
112120
|
+
root = tsx2(input.source);
|
|
112121
|
+
} catch (err) {
|
|
112122
|
+
return { ...EMPTY_SCAN, parseError: err instanceof Error ? err.message : String(err) };
|
|
112123
|
+
}
|
|
112124
|
+
const scan = { ...EMPTY_SCAN };
|
|
112125
|
+
scan.importsSupabase = importsSupabasePackage(root);
|
|
112126
|
+
root.find(import_jscodeshift2.default.CallExpression).forEach((path) => {
|
|
112127
|
+
const chainRoot = findChainRoot(path.node);
|
|
112128
|
+
if (chainRoot?.type !== "Identifier")
|
|
112129
|
+
return;
|
|
112130
|
+
if (!supabaseNames.has(chainRoot.name))
|
|
112131
|
+
return;
|
|
112132
|
+
const parent = path.parent?.node;
|
|
112133
|
+
if (parent?.type === "MemberExpression" && parent.object === path.node) {
|
|
112134
|
+
return;
|
|
112135
|
+
}
|
|
112136
|
+
const steps = readChainSteps(path.node);
|
|
112137
|
+
const first = steps[0];
|
|
112138
|
+
if (!first)
|
|
112139
|
+
return;
|
|
112140
|
+
switch (first.method) {
|
|
112141
|
+
case "auth":
|
|
112142
|
+
scan.authCalls += 1;
|
|
112143
|
+
break;
|
|
112144
|
+
case "from":
|
|
112145
|
+
scan.fromCalls += 1;
|
|
112146
|
+
break;
|
|
112147
|
+
case "storage":
|
|
112148
|
+
scan.storage += 1;
|
|
112149
|
+
break;
|
|
112150
|
+
case "rpc":
|
|
112151
|
+
scan.rpc += 1;
|
|
112152
|
+
break;
|
|
112153
|
+
case "channel":
|
|
112154
|
+
scan.realtime += 1;
|
|
112155
|
+
break;
|
|
112156
|
+
case "functions":
|
|
112157
|
+
if (steps[1]?.method === "invoke")
|
|
112158
|
+
scan.edgeFunctions += 1;
|
|
112159
|
+
break;
|
|
112160
|
+
}
|
|
112161
|
+
});
|
|
112162
|
+
const pb = analyzePbBinding(root, pbName);
|
|
112163
|
+
scan.usesPb = pb.usesPb;
|
|
112164
|
+
scan.danglingPb = pb.usesPb && !pb.declared;
|
|
112165
|
+
return scan;
|
|
112166
|
+
}
|
|
112167
|
+
function importsSupabasePackage(root) {
|
|
112168
|
+
let found = false;
|
|
112169
|
+
root.find(import_jscodeshift2.default.ImportDeclaration).forEach((p) => {
|
|
112170
|
+
const src = p.node.source.value;
|
|
112171
|
+
if (typeof src === "string" && src.startsWith("@supabase/"))
|
|
112172
|
+
found = true;
|
|
112173
|
+
});
|
|
112174
|
+
if (found)
|
|
112175
|
+
return true;
|
|
112176
|
+
root.find(import_jscodeshift2.default.CallExpression).forEach((p) => {
|
|
112177
|
+
const callee = p.node.callee;
|
|
112178
|
+
const isRequire = callee.type === "Identifier" && callee.name === "require";
|
|
112179
|
+
const isDynImport = callee.type === "Import";
|
|
112180
|
+
if (!isRequire && !isDynImport)
|
|
112181
|
+
return;
|
|
112182
|
+
const arg = p.node.arguments[0];
|
|
112183
|
+
if ((arg?.type === "Literal" || arg?.type === "StringLiteral") && typeof arg.value === "string" && arg.value.startsWith("@supabase/")) {
|
|
112184
|
+
found = true;
|
|
112185
|
+
}
|
|
112186
|
+
});
|
|
112187
|
+
return found;
|
|
112188
|
+
}
|
|
112189
|
+
function analyzePbBinding(root, pbName) {
|
|
112190
|
+
let declared = false;
|
|
112191
|
+
root.find(import_jscodeshift2.default.ImportDeclaration).forEach((p) => {
|
|
112192
|
+
for (const spec of p.node.specifiers ?? []) {
|
|
112193
|
+
if (spec.local?.name === pbName)
|
|
112194
|
+
declared = true;
|
|
112195
|
+
}
|
|
112196
|
+
});
|
|
112197
|
+
root.find(import_jscodeshift2.default.VariableDeclarator).forEach((p) => {
|
|
112198
|
+
const id = p.node.id;
|
|
112199
|
+
if (id.type === "Identifier" && id.name === pbName)
|
|
112200
|
+
declared = true;
|
|
112201
|
+
if (id.type === "ObjectPattern" && objectPatternBindsName(id, pbName)) {
|
|
112202
|
+
declared = true;
|
|
112203
|
+
}
|
|
112204
|
+
});
|
|
112205
|
+
const checkParams = (params) => {
|
|
112206
|
+
for (const param of params) {
|
|
112207
|
+
if (param.type === "Identifier" && param.name === pbName) {
|
|
112208
|
+
declared = true;
|
|
112209
|
+
}
|
|
112210
|
+
}
|
|
112211
|
+
};
|
|
112212
|
+
root.find(import_jscodeshift2.default.FunctionDeclaration).forEach((p) => {
|
|
112213
|
+
checkParams(p.node.params);
|
|
112214
|
+
});
|
|
112215
|
+
root.find(import_jscodeshift2.default.FunctionExpression).forEach((p) => {
|
|
112216
|
+
checkParams(p.node.params);
|
|
112217
|
+
});
|
|
112218
|
+
root.find(import_jscodeshift2.default.ArrowFunctionExpression).forEach((p) => {
|
|
112219
|
+
checkParams(p.node.params);
|
|
112220
|
+
});
|
|
112221
|
+
let usedAsObject = false;
|
|
112222
|
+
root.find(import_jscodeshift2.default.MemberExpression).forEach((p) => {
|
|
112223
|
+
const obj = p.node.object;
|
|
112224
|
+
if (obj.type === "Identifier" && obj.name === pbName)
|
|
112225
|
+
usedAsObject = true;
|
|
112226
|
+
});
|
|
112227
|
+
return { usesPb: usedAsObject, declared };
|
|
112228
|
+
}
|
|
112229
|
+
function objectPatternBindsName(pattern, name) {
|
|
112230
|
+
for (const prop of pattern.properties) {
|
|
112231
|
+
if ((prop.type === "Property" || prop.type === "ObjectProperty") && "value" in prop && prop.value.type === "Identifier" && prop.value.name === name) {
|
|
112232
|
+
return true;
|
|
112233
|
+
}
|
|
112234
|
+
}
|
|
112235
|
+
return false;
|
|
112236
|
+
}
|
|
111649
112237
|
function findObjectProp(obj, name) {
|
|
111650
112238
|
for (const prop of obj.properties) {
|
|
111651
112239
|
if ((prop.type === "Property" || prop.type === "ObjectProperty") && "key" in prop && prop.key.type === "Identifier" && prop.key.name === name) {
|
|
111652
112240
|
if (prop.shorthand === true) {
|
|
111653
|
-
return
|
|
112241
|
+
return import_jscodeshift2.default.identifier(name);
|
|
111654
112242
|
}
|
|
111655
112243
|
if ("value" in prop) {
|
|
111656
112244
|
const val = prop.value;
|
|
@@ -111687,6 +112275,9 @@ function applyRewrite(path, replacement, kind, pattern, note, flags, state) {
|
|
|
111687
112275
|
}
|
|
111688
112276
|
|
|
111689
112277
|
// ../core/dist/commands/migrate-supabase-walker.js
|
|
112278
|
+
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
112279
|
+
import { mkdir as mkdir2, readdir, readFile as readFile3, stat, writeFile as writeFile2 } from "node:fs/promises";
|
|
112280
|
+
import { dirname as dirname5, isAbsolute as isAbsolute3, join as join18, relative as relative4, resolve as resolve7, sep as sep4 } from "node:path";
|
|
111690
112281
|
var REWRITABLE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
111691
112282
|
var DEFAULT_EXCLUDES = [
|
|
111692
112283
|
"node_modules",
|
|
@@ -111707,15 +112298,16 @@ var DEFAULT_EXCLUDES = [
|
|
|
111707
112298
|
"pb_migrations"
|
|
111708
112299
|
];
|
|
111709
112300
|
async function walkSupabaseProject(input) {
|
|
111710
|
-
const rootAbs =
|
|
112301
|
+
const rootAbs = resolve7(input.rootDir);
|
|
111711
112302
|
const ig = import_ignore3.default().add(DEFAULT_EXCLUDES);
|
|
111712
112303
|
if (input.extraExcludes && input.extraExcludes.length > 0) {
|
|
111713
112304
|
ig.add(input.extraExcludes);
|
|
111714
112305
|
}
|
|
111715
112306
|
const files = [];
|
|
111716
112307
|
const skipped = [];
|
|
112308
|
+
const pendingConfig = [];
|
|
111717
112309
|
for await (const absPath of walkTree(rootAbs, rootAbs, ig)) {
|
|
111718
|
-
const rel =
|
|
112310
|
+
const rel = relative4(rootAbs, absPath).split(sep4).join("/");
|
|
111719
112311
|
const kind = classifyFile2(rel);
|
|
111720
112312
|
if (kind === null)
|
|
111721
112313
|
continue;
|
|
@@ -111759,11 +112351,38 @@ async function walkSupabaseProject(input) {
|
|
|
111759
112351
|
});
|
|
111760
112352
|
continue;
|
|
111761
112353
|
}
|
|
111762
|
-
|
|
112354
|
+
pendingConfig.push({ relativePath: rel, kind, source });
|
|
112355
|
+
}
|
|
112356
|
+
let supabaseUsageRemaining = 0;
|
|
112357
|
+
for (const file2 of files) {
|
|
112358
|
+
if (file2.kind !== "code")
|
|
112359
|
+
continue;
|
|
112360
|
+
const scan = scanSupabaseUsage({
|
|
112361
|
+
source: file2.rewritten,
|
|
112362
|
+
supabaseIdentifiers: input.supabaseIdentifiers
|
|
112363
|
+
});
|
|
112364
|
+
supabaseUsageRemaining += scan.authCalls + scan.storage + scan.rpc + scan.realtime + scan.edgeFunctions;
|
|
112365
|
+
if (scan.importsSupabase)
|
|
112366
|
+
supabaseUsageRemaining += 1;
|
|
112367
|
+
}
|
|
112368
|
+
const migrationComplete = supabaseUsageRemaining === 0;
|
|
112369
|
+
for (const cfg of pendingConfig) {
|
|
112370
|
+
if (!migrationComplete) {
|
|
112371
|
+
files.push({
|
|
112372
|
+
relativePath: cfg.relativePath,
|
|
112373
|
+
kind: cfg.kind,
|
|
112374
|
+
source: cfg.source,
|
|
112375
|
+
rewritten: cfg.source,
|
|
112376
|
+
changed: false,
|
|
112377
|
+
flags: []
|
|
112378
|
+
});
|
|
112379
|
+
continue;
|
|
112380
|
+
}
|
|
112381
|
+
const configResult = cfg.kind === "package_json" ? rewritePackageJson(cfg.source) : rewriteEnvFile(cfg.source);
|
|
111763
112382
|
files.push({
|
|
111764
|
-
relativePath:
|
|
111765
|
-
kind,
|
|
111766
|
-
source,
|
|
112383
|
+
relativePath: cfg.relativePath,
|
|
112384
|
+
kind: cfg.kind,
|
|
112385
|
+
source: cfg.source,
|
|
111767
112386
|
rewritten: configResult.rewritten,
|
|
111768
112387
|
changed: configResult.changed,
|
|
111769
112388
|
flags: configResult.flags
|
|
@@ -111796,7 +112415,9 @@ async function walkSupabaseProject(input) {
|
|
|
111796
112415
|
changedFiles,
|
|
111797
112416
|
flagCount,
|
|
111798
112417
|
packageJsonChanged,
|
|
111799
|
-
envFilesChanged
|
|
112418
|
+
envFilesChanged,
|
|
112419
|
+
migrationComplete,
|
|
112420
|
+
supabaseUsageRemaining
|
|
111800
112421
|
}
|
|
111801
112422
|
};
|
|
111802
112423
|
}
|
|
@@ -111808,8 +112429,8 @@ async function* walkTree(dir, rootAbs, ig) {
|
|
|
111808
112429
|
return;
|
|
111809
112430
|
}
|
|
111810
112431
|
for (const name of entries) {
|
|
111811
|
-
const abs =
|
|
111812
|
-
const rel =
|
|
112432
|
+
const abs = join18(dir, name);
|
|
112433
|
+
const rel = relative4(rootAbs, abs).split(sep4).join("/");
|
|
111813
112434
|
if (rel.length > 0 && ig.ignores(rel))
|
|
111814
112435
|
continue;
|
|
111815
112436
|
let st;
|
|
@@ -111958,38 +112579,420 @@ function extractPublicPrefix(key) {
|
|
|
111958
112579
|
return "";
|
|
111959
112580
|
}
|
|
111960
112581
|
async function writeWalkResult(input) {
|
|
111961
|
-
const targetAbs =
|
|
112582
|
+
const targetAbs = resolve7(input.targetDir);
|
|
111962
112583
|
const changedOnly = input.changedOnly !== false;
|
|
111963
112584
|
const written = [];
|
|
111964
112585
|
for (const file2 of input.result.files) {
|
|
111965
112586
|
if (changedOnly && !file2.changed)
|
|
111966
112587
|
continue;
|
|
111967
|
-
const abs =
|
|
111968
|
-
const rel =
|
|
111969
|
-
const isParentTraversal = rel === ".." || rel.startsWith(`..${
|
|
111970
|
-
if (rel.length === 0 || isParentTraversal ||
|
|
112588
|
+
const abs = resolve7(targetAbs, file2.relativePath);
|
|
112589
|
+
const rel = relative4(targetAbs, abs);
|
|
112590
|
+
const isParentTraversal = rel === ".." || rel.startsWith(`..${sep4}`) || rel.startsWith("../");
|
|
112591
|
+
if (rel.length === 0 || isParentTraversal || isAbsolute3(rel)) {
|
|
111971
112592
|
throw new Error(`writeWalkResult refused path-traversing file "${file2.relativePath}" → "${abs}" (would escape targetDir "${targetAbs}").`);
|
|
111972
112593
|
}
|
|
111973
|
-
await mkdir2(
|
|
112594
|
+
await mkdir2(dirname5(abs), { recursive: true });
|
|
111974
112595
|
await writeFile2(abs, file2.rewritten, "utf8");
|
|
111975
112596
|
written.push(file2.relativePath);
|
|
111976
112597
|
}
|
|
111977
112598
|
return { written };
|
|
111978
112599
|
}
|
|
111979
112600
|
|
|
112601
|
+
// ../core/dist/commands/migrate-supabase-status.js
|
|
112602
|
+
var migrationStatusInputSchema = exports_external.object({
|
|
112603
|
+
rootDir: exports_external.string().optional().describe("Project root to scan. Relative paths resolve against ctx.cwd. Defaults to ctx.cwd."),
|
|
112604
|
+
build: exports_external.boolean().optional().describe("Also run the project's build as a final gate. Off by default — a half-migrated project legitimately fails to build, so the noise is opt-in."),
|
|
112605
|
+
pbIdentifier: exports_external.string().optional().describe("PocketBase client identifier the rewrite used (defaults to `pb`). Pass the same value here that `rewrite_client` used, or the undefined-reference check can't see a custom identifier (e.g. `db`)."),
|
|
112606
|
+
supabaseIdentifiers: exports_external.array(exports_external.string()).optional().describe("Supabase client variable names to recognise (beyond `supabase`).")
|
|
112607
|
+
});
|
|
112608
|
+
function analyzeMigration(files, opts = {}) {
|
|
112609
|
+
const pbName = opts.pbIdentifier ?? "pb";
|
|
112610
|
+
const supabaseImportFiles = [];
|
|
112611
|
+
const danglingPbFiles = [];
|
|
112612
|
+
let authCalls = 0;
|
|
112613
|
+
let storage = 0;
|
|
112614
|
+
let rpc = 0;
|
|
112615
|
+
let realtime = 0;
|
|
112616
|
+
let edgeFunctions = 0;
|
|
112617
|
+
let anyPbUsage = false;
|
|
112618
|
+
let pocketbaseDepDeclared = false;
|
|
112619
|
+
let supabaseDepDeclared = false;
|
|
112620
|
+
let pocketbaseUrlEnv = false;
|
|
112621
|
+
let supabaseEnvPresent = false;
|
|
112622
|
+
for (const file2 of files) {
|
|
112623
|
+
if (file2.kind === "code") {
|
|
112624
|
+
const scan = scanSupabaseUsage({
|
|
112625
|
+
source: file2.source,
|
|
112626
|
+
supabaseIdentifiers: opts.supabaseIdentifiers,
|
|
112627
|
+
pbIdentifier: pbName
|
|
112628
|
+
});
|
|
112629
|
+
if (scan.importsSupabase)
|
|
112630
|
+
supabaseImportFiles.push(file2.relativePath);
|
|
112631
|
+
if (scan.danglingPb)
|
|
112632
|
+
danglingPbFiles.push(file2.relativePath);
|
|
112633
|
+
if (scan.usesPb)
|
|
112634
|
+
anyPbUsage = true;
|
|
112635
|
+
authCalls += scan.authCalls;
|
|
112636
|
+
storage += scan.storage;
|
|
112637
|
+
rpc += scan.rpc;
|
|
112638
|
+
realtime += scan.realtime;
|
|
112639
|
+
edgeFunctions += scan.edgeFunctions;
|
|
112640
|
+
continue;
|
|
112641
|
+
}
|
|
112642
|
+
if (file2.kind === "package_json") {
|
|
112643
|
+
const deps = readDeps(file2.source);
|
|
112644
|
+
if ("pocketbase" in deps)
|
|
112645
|
+
pocketbaseDepDeclared = true;
|
|
112646
|
+
if ("@supabase/supabase-js" in deps || "@supabase/ssr" in deps)
|
|
112647
|
+
supabaseDepDeclared = true;
|
|
112648
|
+
continue;
|
|
112649
|
+
}
|
|
112650
|
+
if (/^\s*[A-Z][A-Z0-9_]*POCKETBASE_URL\s*=/m.test(file2.source))
|
|
112651
|
+
pocketbaseUrlEnv = true;
|
|
112652
|
+
if (/^\s*[A-Z][A-Z0-9_]*SUPABASE[A-Z0-9_]*\s*=/m.test(file2.source))
|
|
112653
|
+
supabaseEnvPresent = true;
|
|
112654
|
+
}
|
|
112655
|
+
const remaining = supabaseImportFiles.length + authCalls + storage + rpc + realtime + edgeFunctions;
|
|
112656
|
+
const migrationComplete = remaining === 0;
|
|
112657
|
+
const checks3 = [];
|
|
112658
|
+
checks3.push({
|
|
112659
|
+
id: "supabaseImportsRemaining",
|
|
112660
|
+
label: "Supabase imports removed",
|
|
112661
|
+
status: supabaseImportFiles.length === 0 ? "pass" : "warn",
|
|
112662
|
+
count: supabaseImportFiles.length,
|
|
112663
|
+
detail: supabaseImportFiles.length === 0 ? "No files import @supabase/*." : `${supabaseImportFiles.length} file(s) still import @supabase/* — migrate them, or keep them if this is intentionally hybrid.`,
|
|
112664
|
+
...supabaseImportFiles.length > 0 ? { files: supabaseImportFiles } : {}
|
|
112665
|
+
});
|
|
112666
|
+
checks3.push({
|
|
112667
|
+
id: "undefinedPbReferences",
|
|
112668
|
+
label: "PocketBase client wired",
|
|
112669
|
+
status: danglingPbFiles.length === 0 ? "pass" : "fail",
|
|
112670
|
+
count: danglingPbFiles.length,
|
|
112671
|
+
detail: danglingPbFiles.length === 0 ? `Every \`${pbName}\` reference resolves to an imported client.` : `${danglingPbFiles.length} file(s) use \`${pbName}\` with no import in scope — the app won't run. Scaffold + import a client: percher migrate-from-supabase --rewrite-client --scaffold-client.`,
|
|
112672
|
+
...danglingPbFiles.length > 0 ? { files: danglingPbFiles } : {}
|
|
112673
|
+
});
|
|
112674
|
+
checks3.push(usageCheck("authCallsRemaining", "Auth calls migrated", authCalls, "supabase.auth.* call(s) still to map — see the auth recipes in REWRITE_NOTES.md."));
|
|
112675
|
+
checks3.push(usageCheck("storageUsage", "Storage migrated", storage, "supabase.storage.* call(s) remain — PocketBase models files as record fields; rewrite by hand."));
|
|
112676
|
+
checks3.push(usageCheck("rpcUsage", "RPC migrated", rpc, "supabase.rpc(...) call(s) remain — move the logic into app code or a PB hook."));
|
|
112677
|
+
checks3.push(usageCheck("realtimeUsage", "Realtime migrated", realtime, "supabase.channel(...) call(s) remain — PB realtime uses pb.collection(c).subscribe(); the event shape differs."));
|
|
112678
|
+
checks3.push(usageCheck("edgeFunctionUsage", "Edge functions migrated", edgeFunctions, "supabase.functions.invoke(...) call(s) remain — host the function elsewhere and fetch it."));
|
|
112679
|
+
checks3.push({
|
|
112680
|
+
id: "pocketbaseDepDeclared",
|
|
112681
|
+
label: "pocketbase dependency declared",
|
|
112682
|
+
status: pocketbaseDepDeclared ? "pass" : anyPbUsage ? "warn" : "n/a",
|
|
112683
|
+
count: 0,
|
|
112684
|
+
detail: pocketbaseDepDeclared ? "package.json depends on pocketbase." : anyPbUsage ? "Your code uses `pb` but package.json has no `pocketbase` dependency — add it." : "No PocketBase client in use yet."
|
|
112685
|
+
});
|
|
112686
|
+
checks3.push(cleanupCheck({ migrationComplete, supabaseDepDeclared, remaining, anyPbUsage }));
|
|
112687
|
+
checks3.push({
|
|
112688
|
+
id: "envWired",
|
|
112689
|
+
label: "POCKETBASE_URL in env",
|
|
112690
|
+
status: pocketbaseUrlEnv ? "pass" : anyPbUsage ? "warn" : "n/a",
|
|
112691
|
+
count: 0,
|
|
112692
|
+
detail: pocketbaseUrlEnv ? "POCKETBASE_URL is set for local dev." : anyPbUsage ? "No POCKETBASE_URL in your env files. Percher injects it automatically in production; add it to .env for local dev." : "No PocketBase env needed yet."
|
|
112693
|
+
});
|
|
112694
|
+
const rls = opts.rlsManualCount ?? null;
|
|
112695
|
+
checks3.push({
|
|
112696
|
+
id: "rlsRulesToWrite",
|
|
112697
|
+
label: "RLS → PB API rules",
|
|
112698
|
+
status: rls === null ? "n/a" : rls === 0 ? "pass" : "warn",
|
|
112699
|
+
count: rls ?? 0,
|
|
112700
|
+
detail: rls === null ? "No migration-preview/MIGRATION_NOTES.md — run migrate-from-supabase to generate the schema + RLS report." : rls === 0 ? "No RLS policies need manual translation." : `${rls} RLS policy/policies still need PB API rules — see migration-preview/MIGRATION_NOTES.md.`
|
|
112701
|
+
});
|
|
112702
|
+
let supabaseEnvNote = "";
|
|
112703
|
+
if (!migrationComplete && !supabaseEnvPresent && supabaseDepDeclared) {
|
|
112704
|
+
supabaseEnvNote = " Note: Supabase calls remain but no SUPABASE_* env was found — make sure those keys are still set.";
|
|
112705
|
+
}
|
|
112706
|
+
if (supabaseEnvNote) {
|
|
112707
|
+
const envCheck = checks3.find((c) => c.id === "envWired");
|
|
112708
|
+
if (envCheck)
|
|
112709
|
+
envCheck.detail += supabaseEnvNote;
|
|
112710
|
+
}
|
|
112711
|
+
const state = deriveState(checks3, migrationComplete, anyPbUsage, remaining);
|
|
112712
|
+
return { checks: checks3, migrationComplete, state };
|
|
112713
|
+
}
|
|
112714
|
+
function usageCheck(id, label, count, remainingDetail) {
|
|
112715
|
+
return {
|
|
112716
|
+
id,
|
|
112717
|
+
label,
|
|
112718
|
+
status: count === 0 ? "pass" : "warn",
|
|
112719
|
+
count,
|
|
112720
|
+
detail: count === 0 ? "None remaining." : `${count} ${remainingDetail}`
|
|
112721
|
+
};
|
|
112722
|
+
}
|
|
112723
|
+
function cleanupCheck(args) {
|
|
112724
|
+
const base = { id: "supabaseCleanup", label: "Supabase removed", count: args.remaining };
|
|
112725
|
+
if (args.migrationComplete) {
|
|
112726
|
+
if (args.supabaseDepDeclared) {
|
|
112727
|
+
return {
|
|
112728
|
+
...base,
|
|
112729
|
+
status: "warn",
|
|
112730
|
+
detail: "Migration looks complete — you can now drop @supabase/supabase-js and the Supabase env keys."
|
|
112731
|
+
};
|
|
112732
|
+
}
|
|
112733
|
+
return { ...base, status: "pass", detail: "Supabase fully removed." };
|
|
112734
|
+
}
|
|
112735
|
+
if (!args.supabaseDepDeclared && args.remaining > 0) {
|
|
112736
|
+
return {
|
|
112737
|
+
...base,
|
|
112738
|
+
status: "fail",
|
|
112739
|
+
detail: `@supabase/supabase-js was dropped but ${args.remaining} Supabase reference(s) still need it — restore the dependency or finish migrating them.`
|
|
112740
|
+
};
|
|
112741
|
+
}
|
|
112742
|
+
return {
|
|
112743
|
+
...base,
|
|
112744
|
+
status: "warn",
|
|
112745
|
+
detail: `Hybrid: ${args.remaining} Supabase reference(s) remain (storage/rpc/realtime/edge/un-mapped auth or @supabase imports). Keep @supabase/supabase-js + Supabase env until they're migrated.`
|
|
112746
|
+
};
|
|
112747
|
+
}
|
|
112748
|
+
function deriveState(checks3, migrationComplete, anyPbUsage, remaining) {
|
|
112749
|
+
if (checks3.some((c) => c.status === "fail"))
|
|
112750
|
+
return "broken";
|
|
112751
|
+
if (migrationComplete)
|
|
112752
|
+
return "complete";
|
|
112753
|
+
if (anyPbUsage)
|
|
112754
|
+
return "hybrid";
|
|
112755
|
+
return remaining > 0 ? "not_started" : "complete";
|
|
112756
|
+
}
|
|
112757
|
+
function readDeps(source) {
|
|
112758
|
+
let pkg;
|
|
112759
|
+
try {
|
|
112760
|
+
pkg = JSON.parse(source);
|
|
112761
|
+
} catch {
|
|
112762
|
+
return {};
|
|
112763
|
+
}
|
|
112764
|
+
const out = {};
|
|
112765
|
+
for (const section of [
|
|
112766
|
+
"dependencies",
|
|
112767
|
+
"devDependencies",
|
|
112768
|
+
"peerDependencies",
|
|
112769
|
+
"optionalDependencies"
|
|
112770
|
+
]) {
|
|
112771
|
+
const deps = pkg[section];
|
|
112772
|
+
if (deps && typeof deps === "object" && !Array.isArray(deps)) {
|
|
112773
|
+
Object.assign(out, deps);
|
|
112774
|
+
}
|
|
112775
|
+
}
|
|
112776
|
+
return out;
|
|
112777
|
+
}
|
|
112778
|
+
var STATUS_GLYPH = {
|
|
112779
|
+
pass: "✓",
|
|
112780
|
+
fail: "✗",
|
|
112781
|
+
warn: "⚠",
|
|
112782
|
+
"n/a": "•"
|
|
112783
|
+
};
|
|
112784
|
+
function renderMigrationChecklist(checks3) {
|
|
112785
|
+
const lines = [];
|
|
112786
|
+
for (const check2 of checks3) {
|
|
112787
|
+
const glyph = STATUS_GLYPH[check2.status];
|
|
112788
|
+
const countSuffix = check2.count > 0 ? ` (${check2.count})` : "";
|
|
112789
|
+
lines.push(`${glyph} ${check2.label}${countSuffix} — ${check2.detail}`);
|
|
112790
|
+
if (check2.files && check2.files.length > 0) {
|
|
112791
|
+
for (const f of check2.files.slice(0, 10))
|
|
112792
|
+
lines.push(` - ${f}`);
|
|
112793
|
+
if (check2.files.length > 10)
|
|
112794
|
+
lines.push(` …and ${check2.files.length - 10} more`);
|
|
112795
|
+
}
|
|
112796
|
+
}
|
|
112797
|
+
return lines.join(`
|
|
112798
|
+
`);
|
|
112799
|
+
}
|
|
112800
|
+
var STATE_SUMMARY = {
|
|
112801
|
+
broken: "Migration is in a broken state — fix the ✗ items before deploying.",
|
|
112802
|
+
hybrid: "Hybrid migration — some calls are on PocketBase, some still on Supabase (both SDKs needed).",
|
|
112803
|
+
not_started: "Supabase is still in use — nothing migrated to PocketBase yet.",
|
|
112804
|
+
complete: "Migration looks complete — no Supabase usage remains."
|
|
112805
|
+
};
|
|
112806
|
+
async function migrationStatus(ctx, input) {
|
|
112807
|
+
const rootAbs = input.rootDir ? resolve8(ctx.cwd, input.rootDir) : resolve8(ctx.cwd);
|
|
112808
|
+
ctx.status(`Scanning ${relative5(ctx.cwd, rootAbs) || "."} for migration status...`);
|
|
112809
|
+
let files;
|
|
112810
|
+
try {
|
|
112811
|
+
const walk2 = await walkSupabaseProject({ rootDir: rootAbs });
|
|
112812
|
+
files = walk2.files.map((f) => ({
|
|
112813
|
+
relativePath: f.relativePath,
|
|
112814
|
+
kind: f.kind,
|
|
112815
|
+
source: f.source
|
|
112816
|
+
}));
|
|
112817
|
+
} catch (err) {
|
|
112818
|
+
return failure2(rootAbs, err);
|
|
112819
|
+
}
|
|
112820
|
+
const rlsManualCount = await readManualRlsCount(rootAbs);
|
|
112821
|
+
const analysis = analyzeMigration(files, {
|
|
112822
|
+
rlsManualCount,
|
|
112823
|
+
pbIdentifier: input.pbIdentifier,
|
|
112824
|
+
supabaseIdentifiers: input.supabaseIdentifiers
|
|
112825
|
+
});
|
|
112826
|
+
let build;
|
|
112827
|
+
if (input.build === true) {
|
|
112828
|
+
build = await runProjectBuild(rootAbs);
|
|
112829
|
+
}
|
|
112830
|
+
const checklist = renderMigrationChecklist(analysis.checks);
|
|
112831
|
+
const failing = analysis.checks.filter((c) => c.status === "fail");
|
|
112832
|
+
const warning = analysis.checks.filter((c) => c.status === "warn");
|
|
112833
|
+
const buildFailed = build?.ran === true && !build.passed;
|
|
112834
|
+
const allGreen = failing.length === 0 && warning.length === 0 && !buildFailed;
|
|
112835
|
+
const recovery = allGreen ? recoveryNone() : recoveryAsk({
|
|
112836
|
+
prompt: buildPrompt(analysis.state, failing, warning, build),
|
|
112837
|
+
reasonCode: "unknown"
|
|
112838
|
+
});
|
|
112839
|
+
const summary = `${STATE_SUMMARY[analysis.state]}${build ? ` Build: ${build.ran ? build.passed ? "passed" : "FAILED" : "skipped"}.` : ""}`;
|
|
112840
|
+
return {
|
|
112841
|
+
status: "ok",
|
|
112842
|
+
rootDir: rootAbs,
|
|
112843
|
+
state: analysis.state,
|
|
112844
|
+
migrationComplete: analysis.migrationComplete,
|
|
112845
|
+
checks: analysis.checks,
|
|
112846
|
+
...build ? { build } : {},
|
|
112847
|
+
recovery,
|
|
112848
|
+
summary,
|
|
112849
|
+
checklist
|
|
112850
|
+
};
|
|
112851
|
+
}
|
|
112852
|
+
function buildPrompt(state, failing, warning, build) {
|
|
112853
|
+
const bits = [];
|
|
112854
|
+
if (failing.length > 0) {
|
|
112855
|
+
bits.push(`fix first: ${failing.map((c) => `${c.label} — ${c.detail}`).join("; ")}`);
|
|
112856
|
+
}
|
|
112857
|
+
if (warning.length > 0) {
|
|
112858
|
+
bits.push(`still to do: ${warning.map((c) => `${c.label} (${c.count || "n/a"})`).join(", ")}`);
|
|
112859
|
+
}
|
|
112860
|
+
if (build?.ran && !build.passed) {
|
|
112861
|
+
bits.push(`the build failed: ${build.detail}`);
|
|
112862
|
+
}
|
|
112863
|
+
const lead = state === "broken" ? "The migration is in a broken state." : "The migration isn't finished.";
|
|
112864
|
+
return `${lead} ${bits.join(". ")}. Work through migration-preview/REWRITE_NOTES.md, then re-run --status.`;
|
|
112865
|
+
}
|
|
112866
|
+
async function readManualRlsCount(rootAbs) {
|
|
112867
|
+
for (const dir of ["migration-preview", "."]) {
|
|
112868
|
+
try {
|
|
112869
|
+
const notes = await readFile4(join19(rootAbs, dir, "MIGRATION_NOTES.md"), "utf8");
|
|
112870
|
+
const m = notes.match(/\*\*RLS policies:\*\*\s*\d+\s*\((\d+)\s*need manual review\)/);
|
|
112871
|
+
if (m?.[1] !== undefined)
|
|
112872
|
+
return Number.parseInt(m[1], 10);
|
|
112873
|
+
return 0;
|
|
112874
|
+
} catch {}
|
|
112875
|
+
}
|
|
112876
|
+
return null;
|
|
112877
|
+
}
|
|
112878
|
+
async function runProjectBuild(rootAbs) {
|
|
112879
|
+
let hasBuildScript = false;
|
|
112880
|
+
try {
|
|
112881
|
+
const pkg = JSON.parse(await readFile4(join19(rootAbs, "package.json"), "utf8"));
|
|
112882
|
+
hasBuildScript = typeof pkg.scripts?.build === "string";
|
|
112883
|
+
} catch {
|
|
112884
|
+
return { ran: false, passed: false, detail: "No readable package.json — nothing to build." };
|
|
112885
|
+
}
|
|
112886
|
+
if (!hasBuildScript) {
|
|
112887
|
+
return { ran: false, passed: false, detail: "No `build` script in package.json." };
|
|
112888
|
+
}
|
|
112889
|
+
const pm = await detectPackageManager(rootAbs);
|
|
112890
|
+
const result = await spawnCapture(pm, ["run", "build"], rootAbs, 300000);
|
|
112891
|
+
if (result.timedOut) {
|
|
112892
|
+
return { ran: true, passed: false, detail: `\`${pm} run build\` timed out after 5 min.` };
|
|
112893
|
+
}
|
|
112894
|
+
if (result.spawnError) {
|
|
112895
|
+
return {
|
|
112896
|
+
ran: false,
|
|
112897
|
+
passed: false,
|
|
112898
|
+
detail: `Couldn't run \`${pm} run build\` (${result.spawnError}). Is ${pm} installed?`
|
|
112899
|
+
};
|
|
112900
|
+
}
|
|
112901
|
+
const passed = result.code === 0;
|
|
112902
|
+
const tail = lastLines(result.output, 12);
|
|
112903
|
+
return {
|
|
112904
|
+
ran: true,
|
|
112905
|
+
passed,
|
|
112906
|
+
detail: passed ? `\`${pm} run build\` succeeded.` : `\`${pm} run build\` exited ${result.code}.${tail ? `
|
|
112907
|
+
${tail}` : ""}`
|
|
112908
|
+
};
|
|
112909
|
+
}
|
|
112910
|
+
async function detectPackageManager(rootAbs) {
|
|
112911
|
+
const has = async (name) => {
|
|
112912
|
+
try {
|
|
112913
|
+
await readFile4(join19(rootAbs, name), "utf8");
|
|
112914
|
+
return true;
|
|
112915
|
+
} catch {
|
|
112916
|
+
return false;
|
|
112917
|
+
}
|
|
112918
|
+
};
|
|
112919
|
+
if (await has("bun.lock") || await has("bun.lockb"))
|
|
112920
|
+
return "bun";
|
|
112921
|
+
if (await has("pnpm-lock.yaml"))
|
|
112922
|
+
return "pnpm";
|
|
112923
|
+
if (await has("yarn.lock"))
|
|
112924
|
+
return "yarn";
|
|
112925
|
+
return "npm";
|
|
112926
|
+
}
|
|
112927
|
+
function spawnCapture(cmd, args, cwd, timeoutMs) {
|
|
112928
|
+
return new Promise((resolve9) => {
|
|
112929
|
+
const child = import_cross_spawn.default(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
112930
|
+
let output = "";
|
|
112931
|
+
const onData = (chunk) => {
|
|
112932
|
+
output += chunk.toString();
|
|
112933
|
+
if (output.length > 64000)
|
|
112934
|
+
output = output.slice(-64000);
|
|
112935
|
+
};
|
|
112936
|
+
child.stdout?.on("data", onData);
|
|
112937
|
+
child.stderr?.on("data", onData);
|
|
112938
|
+
let timedOut = false;
|
|
112939
|
+
const timer = setTimeout(() => {
|
|
112940
|
+
timedOut = true;
|
|
112941
|
+
child.kill("SIGTERM");
|
|
112942
|
+
}, timeoutMs);
|
|
112943
|
+
child.on("error", (err) => {
|
|
112944
|
+
clearTimeout(timer);
|
|
112945
|
+
resolve9({ code: 1, output, timedOut, spawnError: err.message });
|
|
112946
|
+
});
|
|
112947
|
+
child.on("close", (code) => {
|
|
112948
|
+
clearTimeout(timer);
|
|
112949
|
+
resolve9({ code: code ?? 1, output, timedOut });
|
|
112950
|
+
});
|
|
112951
|
+
});
|
|
112952
|
+
}
|
|
112953
|
+
function lastLines(text, n) {
|
|
112954
|
+
const lines = text.split(/\r?\n/).filter((l) => l.trim().length > 0);
|
|
112955
|
+
return lines.slice(-n).join(`
|
|
112956
|
+
`);
|
|
112957
|
+
}
|
|
112958
|
+
function failure2(rootAbs, err) {
|
|
112959
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
112960
|
+
return {
|
|
112961
|
+
status: "failed",
|
|
112962
|
+
rootDir: rootAbs,
|
|
112963
|
+
state: "broken",
|
|
112964
|
+
migrationComplete: false,
|
|
112965
|
+
checks: [],
|
|
112966
|
+
recovery: recoveryAsk({
|
|
112967
|
+
prompt: `Couldn't scan the project for migration status (${message}). Check the path exists and is readable, then re-run.`,
|
|
112968
|
+
reasonCode: "unknown",
|
|
112969
|
+
retryable: true
|
|
112970
|
+
}),
|
|
112971
|
+
summary: `Migration status scan failed: ${message}`,
|
|
112972
|
+
checklist: "",
|
|
112973
|
+
error: {
|
|
112974
|
+
code: "status_failed",
|
|
112975
|
+
title: "Migration status scan failed",
|
|
112976
|
+
explanation: message,
|
|
112977
|
+
suggestion: "Check the project path exists and is readable, then re-run."
|
|
112978
|
+
}
|
|
112979
|
+
};
|
|
112980
|
+
}
|
|
112981
|
+
|
|
111980
112982
|
// ../core/dist/commands/migrate-supabase-rewrite.js
|
|
111981
112983
|
var rewriteSupabaseClientInputSchema = exports_external.object({
|
|
111982
112984
|
rootDir: exports_external.string().optional().describe("Project root to rewrite. Relative paths resolve against ctx.cwd. Defaults to ctx.cwd."),
|
|
111983
112985
|
outputDir: exports_external.string().optional().describe("Where preview-mode writes the rewritten tree. Ignored when `apply` is true. Defaults to `<root>/migration-preview/rewritten`."),
|
|
111984
112986
|
apply: exports_external.boolean().optional().describe("When true, overwrite changed files in place (originals backed up to `migration-preview/backup/` first). Default false = preview only."),
|
|
111985
112987
|
pbIdentifier: exports_external.string().optional().describe("PocketBase client variable name to emit. Defaults to `pb`."),
|
|
111986
|
-
supabaseIdentifiers: exports_external.array(exports_external.string()).optional().describe("Extra Supabase client variable names to recognise (beyond `supabase`).")
|
|
112988
|
+
supabaseIdentifiers: exports_external.array(exports_external.string()).optional().describe("Extra Supabase client variable names to recognise (beyond `supabase`)."),
|
|
112989
|
+
scaffoldClient: exports_external.boolean().optional().describe("Generate a PocketBase client module (src/lib/pocketbase.<ext>) and insert `import { pb }` into rewritten files. Default true when there are rewrites; pass false to opt out. Skips silently if a pb client already exists.")
|
|
111987
112990
|
});
|
|
111988
112991
|
async function rewriteSupabaseClient(ctx, input) {
|
|
111989
|
-
const rootAbs = input.rootDir ?
|
|
112992
|
+
const rootAbs = input.rootDir ? resolve9(ctx.cwd, input.rootDir) : resolve9(ctx.cwd);
|
|
111990
112993
|
const apply = input.apply === true;
|
|
111991
112994
|
const mode = apply ? "apply" : "preview";
|
|
111992
|
-
ctx.status(`Scanning ${
|
|
112995
|
+
ctx.status(`Scanning ${relative6(ctx.cwd, rootAbs) || "."} for Supabase SDK calls...`);
|
|
111993
112996
|
let walk2;
|
|
111994
112997
|
try {
|
|
111995
112998
|
walk2 = await walkSupabaseProject({
|
|
@@ -111998,7 +113001,7 @@ async function rewriteSupabaseClient(ctx, input) {
|
|
|
111998
113001
|
supabaseIdentifiers: input.supabaseIdentifiers
|
|
111999
113002
|
});
|
|
112000
113003
|
} catch (err) {
|
|
112001
|
-
return
|
|
113004
|
+
return failure3(rootAbs, mode, err, `Couldn't scan ${relative6(ctx.cwd, rootAbs) || "."}: check the path exists and is readable, then re-run.`);
|
|
112002
113005
|
}
|
|
112003
113006
|
const changed = walk2.files.filter((f) => f.changed);
|
|
112004
113007
|
const flags = collectManualFlags(walk2);
|
|
@@ -112015,15 +113018,32 @@ async function rewriteSupabaseClient(ctx, input) {
|
|
|
112015
113018
|
flagsByPattern: {},
|
|
112016
113019
|
packageJsonChanged: false,
|
|
112017
113020
|
envFilesChanged: 0,
|
|
113021
|
+
clientModule: null,
|
|
112018
113022
|
skipped: [],
|
|
112019
113023
|
recovery: recoveryNone(),
|
|
112020
113024
|
summary: "No Supabase SDK calls found to rewrite. If you intend to keep Supabase as your backend, " + 'set `[data] mode = "supabase"` in percher.toml instead.'
|
|
112021
113025
|
};
|
|
112022
113026
|
}
|
|
112023
|
-
const
|
|
112024
|
-
const
|
|
112025
|
-
const
|
|
113027
|
+
const hadRewrites = changed.length > 0;
|
|
113028
|
+
const scaffoldEnabled = input.scaffoldClient !== false && hadRewrites;
|
|
113029
|
+
const scaffold = scaffoldEnabled ? scaffoldPocketBaseClient({
|
|
113030
|
+
files: walk2.files,
|
|
113031
|
+
changedRelPaths: changed.map((f) => f.relativePath),
|
|
113032
|
+
pbIdentifier: input.pbIdentifier
|
|
113033
|
+
}) : null;
|
|
113034
|
+
if (scaffold) {
|
|
113035
|
+
for (const [rel, content] of scaffold.importInsertions) {
|
|
113036
|
+
const file2 = walk2.files.find((f) => f.relativePath === rel);
|
|
113037
|
+
if (file2)
|
|
113038
|
+
file2.rewritten = content;
|
|
113039
|
+
}
|
|
113040
|
+
flags.push(...scaffold.flags);
|
|
113041
|
+
}
|
|
113042
|
+
const reportNeeded = hadRewrites || flags.length > 0 || walk2.skipped.length > 0;
|
|
113043
|
+
const backupDir = apply && changed.length > 0 ? join20(rootAbs, "migration-preview", "backup") : null;
|
|
113044
|
+
const rewriteTarget = apply ? rootAbs : input.outputDir ? resolve9(ctx.cwd, input.outputDir) : join20(rootAbs, "migration-preview", "rewritten");
|
|
112026
113045
|
const filesWritten = [];
|
|
113046
|
+
let clientModuleWritten = null;
|
|
112027
113047
|
try {
|
|
112028
113048
|
if (changed.length > 0) {
|
|
112029
113049
|
if (apply && backupDir) {
|
|
@@ -112041,23 +113061,47 @@ async function rewriteSupabaseClient(ctx, input) {
|
|
|
112041
113061
|
changedOnly: true
|
|
112042
113062
|
});
|
|
112043
113063
|
for (const rel of out.written) {
|
|
112044
|
-
filesWritten.push(
|
|
113064
|
+
filesWritten.push(relative6(ctx.cwd, join20(rewriteTarget, rel)));
|
|
113065
|
+
}
|
|
113066
|
+
if (scaffold?.clientModule) {
|
|
113067
|
+
const moduleAbs = join20(rewriteTarget, scaffold.clientModule.relativePath);
|
|
113068
|
+
await mkdir3(dirname6(moduleAbs), { recursive: true });
|
|
113069
|
+
await writeFile3(moduleAbs, scaffold.clientModule.content, "utf8");
|
|
113070
|
+
clientModuleWritten = relative6(ctx.cwd, moduleAbs).split(sep5).join("/");
|
|
113071
|
+
filesWritten.push(clientModuleWritten);
|
|
112045
113072
|
}
|
|
112046
113073
|
}
|
|
112047
113074
|
if (reportNeeded) {
|
|
112048
|
-
const reportAbs =
|
|
112049
|
-
await mkdir3(
|
|
112050
|
-
|
|
112051
|
-
|
|
113075
|
+
const reportAbs = join20(rootAbs, "migration-preview", "REWRITE_NOTES.md");
|
|
113076
|
+
await mkdir3(dirname6(reportAbs), { recursive: true });
|
|
113077
|
+
const analysis = analyzeMigration(walk2.files.map((f) => ({
|
|
113078
|
+
relativePath: f.relativePath,
|
|
113079
|
+
kind: f.kind,
|
|
113080
|
+
source: f.rewritten
|
|
113081
|
+
})), { supabaseIdentifiers: input.supabaseIdentifiers, pbIdentifier: input.pbIdentifier });
|
|
113082
|
+
await writeFile3(reportAbs, renderReport({
|
|
113083
|
+
flags,
|
|
113084
|
+
skipped: walk2.skipped,
|
|
113085
|
+
hadRewrites,
|
|
113086
|
+
migrationComplete: walk2.summary.migrationComplete,
|
|
113087
|
+
supabaseUsageRemaining: walk2.summary.supabaseUsageRemaining,
|
|
113088
|
+
checklist: renderMigrationChecklist(analysis.checks),
|
|
113089
|
+
scaffoldedClient: scaffold?.clientModule?.relativePath ?? null,
|
|
113090
|
+
scaffoldSkippedExisting: scaffold?.skippedReason === "pb_client_exists"
|
|
113091
|
+
}), "utf8");
|
|
113092
|
+
filesWritten.push(relative6(ctx.cwd, reportAbs));
|
|
112052
113093
|
}
|
|
112053
113094
|
} catch (err) {
|
|
112054
|
-
return
|
|
113095
|
+
return failure3(rootAbs, mode, err, apply ? "The in-place rewrite failed partway. Your originals are safe — restore from `migration-preview/backup/` and re-run." : "Couldn't write the rewritten preview. Check the output directory is writeable and re-run.");
|
|
112055
113096
|
}
|
|
112056
113097
|
const flagsByPattern = {};
|
|
112057
113098
|
for (const flag of flags) {
|
|
112058
113099
|
flagsByPattern[flag.pattern] = (flagsByPattern[flag.pattern] ?? 0) + 1;
|
|
112059
113100
|
}
|
|
112060
|
-
const recovery = reportNeeded ? recoveryAsk({
|
|
113101
|
+
const recovery = reportNeeded ? recoveryAsk({
|
|
113102
|
+
prompt: buildPrompt2(flags, walk2.skipped.length, hadRewrites, clientModuleWritten),
|
|
113103
|
+
reasonCode: "unknown"
|
|
113104
|
+
}) : recoveryNone();
|
|
112061
113105
|
return {
|
|
112062
113106
|
status: "ok",
|
|
112063
113107
|
mode,
|
|
@@ -112070,11 +113114,21 @@ async function rewriteSupabaseClient(ctx, input) {
|
|
|
112070
113114
|
flagsByPattern,
|
|
112071
113115
|
packageJsonChanged: walk2.summary.packageJsonChanged,
|
|
112072
113116
|
envFilesChanged: walk2.summary.envFilesChanged,
|
|
113117
|
+
clientModule: clientModuleWritten,
|
|
112073
113118
|
skipped: walk2.skipped,
|
|
112074
113119
|
recovery,
|
|
112075
|
-
summary: renderSummary2({
|
|
113120
|
+
summary: renderSummary2({
|
|
113121
|
+
mode,
|
|
113122
|
+
changed: changed.length,
|
|
113123
|
+
walk: walk2,
|
|
113124
|
+
flagCount: flags.length,
|
|
113125
|
+
clientModule: clientModuleWritten
|
|
113126
|
+
})
|
|
112076
113127
|
};
|
|
112077
113128
|
}
|
|
113129
|
+
function isHybrid(walk2) {
|
|
113130
|
+
return !walk2.summary.migrationComplete && walk2.summary.supabaseUsageRemaining > 0;
|
|
113131
|
+
}
|
|
112078
113132
|
function collectManualFlags(walk2) {
|
|
112079
113133
|
const out = [];
|
|
112080
113134
|
for (const file2 of walk2.files) {
|
|
@@ -112093,10 +113147,15 @@ function collectManualFlags(walk2) {
|
|
|
112093
113147
|
}
|
|
112094
113148
|
return out;
|
|
112095
113149
|
}
|
|
112096
|
-
function
|
|
113150
|
+
function buildPrompt2(flags, skippedCount, hadRewrites, clientModule) {
|
|
112097
113151
|
const rewritten = flags.filter((f) => f.kind === "manual_review").length;
|
|
112098
113152
|
const untouched = flags.filter((f) => f.kind === "unsupported").length;
|
|
112099
113153
|
const bits = [];
|
|
113154
|
+
if (clientModule) {
|
|
113155
|
+
bits.push(`review the scaffolded PocketBase client at \`${clientModule}\``);
|
|
113156
|
+
} else if (hadRewrites) {
|
|
113157
|
+
bits.push("create the `pb` PocketBase client the rewritten code now uses (it isn't created for you)");
|
|
113158
|
+
}
|
|
112100
113159
|
if (rewritten > 0) {
|
|
112101
113160
|
bits.push(`${rewritten} rewritten to PocketBase but with semantics that differ from Supabase`);
|
|
112102
113161
|
}
|
|
@@ -112106,7 +113165,7 @@ function buildPrompt(flags, skippedCount) {
|
|
|
112106
113165
|
if (skippedCount > 0) {
|
|
112107
113166
|
bits.push(`${skippedCount} file${skippedCount === 1 ? "" : "s"} couldn't be parsed`);
|
|
112108
113167
|
}
|
|
112109
|
-
return `
|
|
113168
|
+
return `Before deploying, work through migration-preview/REWRITE_NOTES.md: ${bits.join("; ")}.`;
|
|
112110
113169
|
}
|
|
112111
113170
|
function renderSummary2(args) {
|
|
112112
113171
|
const parts = [];
|
|
@@ -112116,12 +113175,18 @@ function renderSummary2(args) {
|
|
|
112116
113175
|
} else {
|
|
112117
113176
|
parts.push("No files needed automatic rewriting.");
|
|
112118
113177
|
}
|
|
113178
|
+
if (args.clientModule) {
|
|
113179
|
+
parts.push(`Scaffolded a PocketBase client at \`${args.clientModule}\` and imported it.`);
|
|
113180
|
+
}
|
|
112119
113181
|
if (args.walk.summary.packageJsonChanged) {
|
|
112120
113182
|
parts.push("`package.json` swapped `@supabase/supabase-js` → `pocketbase`.");
|
|
112121
113183
|
}
|
|
112122
113184
|
if (args.walk.summary.envFilesChanged > 0) {
|
|
112123
113185
|
parts.push(`${args.walk.summary.envFilesChanged} .env file${args.walk.summary.envFilesChanged === 1 ? "" : "s"} stubbed with PocketBase keys.`);
|
|
112124
113186
|
}
|
|
113187
|
+
if (isHybrid(args.walk)) {
|
|
113188
|
+
parts.push(`Hybrid migration — ${args.walk.summary.supabaseUsageRemaining} Supabase reference${args.walk.summary.supabaseUsageRemaining === 1 ? "" : "s"} still need${args.walk.summary.supabaseUsageRemaining === 1 ? "s" : ""} \`@supabase/supabase-js\`, so the dependency + Supabase env were kept. Drop them once the rest is migrated.`);
|
|
113189
|
+
}
|
|
112125
113190
|
if (args.flagCount > 0) {
|
|
112126
113191
|
parts.push(`${args.flagCount} pattern${args.flagCount === 1 ? "" : "s"} need manual review — see \`migration-preview/REWRITE_NOTES.md\`.`);
|
|
112127
113192
|
}
|
|
@@ -112134,8 +113199,51 @@ function renderReport(args) {
|
|
|
112134
113199
|
const lines = [];
|
|
112135
113200
|
lines.push("# Supabase → PocketBase — review notes");
|
|
112136
113201
|
lines.push("");
|
|
112137
|
-
lines.push("The automated rewrite
|
|
113202
|
+
lines.push("The automated rewrite converted the high-confidence auth and CRUD call sites. It does NOT create your PocketBase client, and the items below still need a human. There are no inline markers — work from this list.");
|
|
112138
113203
|
lines.push("");
|
|
113204
|
+
if (args.checklist) {
|
|
113205
|
+
lines.push("## Status checklist");
|
|
113206
|
+
lines.push("");
|
|
113207
|
+
lines.push("Same scoreboard as `percher migrate-from-supabase --status`:");
|
|
113208
|
+
lines.push("");
|
|
113209
|
+
lines.push("```");
|
|
113210
|
+
lines.push(args.checklist);
|
|
113211
|
+
lines.push("```");
|
|
113212
|
+
lines.push("");
|
|
113213
|
+
}
|
|
113214
|
+
if (!args.migrationComplete && args.supabaseUsageRemaining > 0) {
|
|
113215
|
+
lines.push("## Hybrid state — Supabase kept on purpose");
|
|
113216
|
+
lines.push("");
|
|
113217
|
+
lines.push(`${args.supabaseUsageRemaining} Supabase reference${args.supabaseUsageRemaining === 1 ? "" : "s"} (storage / realtime / rpc / edge functions / un-mapped auth, or files still importing \`@supabase/*\`) ${args.supabaseUsageRemaining === 1 ? "was" : "were"} left in place because ${args.supabaseUsageRemaining === 1 ? "it has" : "they have"} no clean PocketBase equivalent. While they remain, your app needs **both** SDKs:`);
|
|
113218
|
+
lines.push("");
|
|
113219
|
+
lines.push("- `package.json` still depends on `@supabase/supabase-js` (and `pocketbase` once you add it) — **this is correct**, don't remove the Supabase dep yet.");
|
|
113220
|
+
lines.push("- your Supabase env vars (`SUPABASE_*` / `VITE_SUPABASE_*` / …) were **kept** — they're still needed by the calls below.");
|
|
113221
|
+
lines.push("");
|
|
113222
|
+
lines.push("Once you've migrated every item in this report, drop `@supabase/supabase-js` and the Supabase env keys. Run `percher migrate-from-supabase --status` to check what's left.");
|
|
113223
|
+
lines.push("");
|
|
113224
|
+
}
|
|
113225
|
+
if (args.scaffoldedClient) {
|
|
113226
|
+
lines.push("## PocketBase client (scaffolded for you)");
|
|
113227
|
+
lines.push("");
|
|
113228
|
+
lines.push(`A PocketBase client was generated at \`${args.scaffoldedClient}\` and \`import { pb } from "…"\` was inserted into the rewritten files. Review the URL accessor — it's a working default, adjust it to match your framework if needed.`);
|
|
113229
|
+
lines.push("");
|
|
113230
|
+
} else if (args.hadRewrites) {
|
|
113231
|
+
lines.push("## Wire the PocketBase client (required first)");
|
|
113232
|
+
lines.push("");
|
|
113233
|
+
lines.push(args.scaffoldSkippedExisting ? "The rewritten call sites use a `pb` client. Your project already exports one, so no module was generated — make sure each rewritten file imports `pb` from it." : "The rewritten call sites now use a `pb` client this tool did not create — until you add it, they reference an undefined `pb` and the app won't run.");
|
|
113234
|
+
lines.push("");
|
|
113235
|
+
lines.push("1. Replace your Supabase client setup with a PocketBase one, exported under the same name the rewrites use (`pb`):");
|
|
113236
|
+
lines.push("");
|
|
113237
|
+
lines.push("```js");
|
|
113238
|
+
lines.push('import PocketBase from "pocketbase";');
|
|
113239
|
+
lines.push("// Percher injects POCKETBASE_URL / VITE_POCKETBASE_URL at deploy time.");
|
|
113240
|
+
lines.push("export const pb = new PocketBase(import.meta.env.VITE_POCKETBASE_URL ?? process.env.POCKETBASE_URL);");
|
|
113241
|
+
lines.push("```");
|
|
113242
|
+
lines.push("");
|
|
113243
|
+
lines.push("2. Import `pb` in the rewritten files from wherever you export it.");
|
|
113244
|
+
lines.push("3. Remove the leftover `@supabase/*` imports (the `createClient(...)` setup, `@supabase/ssr` helpers, etc.) once nothing else needs them.");
|
|
113245
|
+
lines.push("");
|
|
113246
|
+
}
|
|
112139
113247
|
const rewritten = args.flags.filter((f) => f.kind === "manual_review");
|
|
112140
113248
|
const untouched = args.flags.filter((f) => f.kind === "unsupported");
|
|
112141
113249
|
if (rewritten.length > 0) {
|
|
@@ -112152,6 +113260,9 @@ function renderReport(args) {
|
|
|
112152
113260
|
lines.push("");
|
|
112153
113261
|
appendFlagsByFile(lines, untouched);
|
|
112154
113262
|
}
|
|
113263
|
+
const recipeLines = renderRecipesSection(args.flags.map((f) => f.pattern));
|
|
113264
|
+
for (const line of recipeLines)
|
|
113265
|
+
lines.push(line);
|
|
112155
113266
|
if (args.skipped.length > 0) {
|
|
112156
113267
|
lines.push("## Files that couldn't be parsed");
|
|
112157
113268
|
lines.push("");
|
|
@@ -112182,7 +113293,7 @@ function appendFlagsByFile(lines, flags) {
|
|
|
112182
113293
|
lines.push("");
|
|
112183
113294
|
}
|
|
112184
113295
|
}
|
|
112185
|
-
function
|
|
113296
|
+
function failure3(rootAbs, mode, err, suggestion) {
|
|
112186
113297
|
const message = err instanceof Error ? err.message : String(err);
|
|
112187
113298
|
return {
|
|
112188
113299
|
status: "failed",
|
|
@@ -112196,6 +113307,7 @@ function failure2(rootAbs, mode, err, suggestion) {
|
|
|
112196
113307
|
flagsByPattern: {},
|
|
112197
113308
|
packageJsonChanged: false,
|
|
112198
113309
|
envFilesChanged: 0,
|
|
113310
|
+
clientModule: null,
|
|
112199
113311
|
skipped: [],
|
|
112200
113312
|
recovery: recoveryAsk({
|
|
112201
113313
|
prompt: `${suggestion} (${message})`,
|
|
@@ -112213,7 +113325,7 @@ function failure2(rootAbs, mode, err, suggestion) {
|
|
|
112213
113325
|
}
|
|
112214
113326
|
// ../core/dist/commands/migrate-supabase-schema.js
|
|
112215
113327
|
import { mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
|
|
112216
|
-
import { isAbsolute as
|
|
113328
|
+
import { isAbsolute as isAbsolute4, join as join21, relative as relative7, resolve as resolve10 } from "node:path";
|
|
112217
113329
|
|
|
112218
113330
|
// ../core/dist/commands/migrate-supabase-scripts.js
|
|
112219
113331
|
function generateDataImportScripts(preview) {
|
|
@@ -112661,7 +113773,7 @@ var migrateSupabaseSchemaInputSchema = exports_external.object({
|
|
|
112661
113773
|
});
|
|
112662
113774
|
async function migrateSupabaseSchema(ctx, input) {
|
|
112663
113775
|
const outputDirAbs = resolveOutputDir(ctx.cwd, input.outputDir);
|
|
112664
|
-
const outputDirRel =
|
|
113776
|
+
const outputDirRel = relative7(ctx.cwd, outputDirAbs) || ".";
|
|
112665
113777
|
ctx.status(`Inspecting Supabase project ${input.projectRef}...`);
|
|
112666
113778
|
const inspection = await inspectSupabase(ctx, {
|
|
112667
113779
|
projectRef: input.projectRef,
|
|
@@ -112725,28 +113837,28 @@ async function migrateSupabaseSchema(ctx, input) {
|
|
|
112725
113837
|
}
|
|
112726
113838
|
function resolveOutputDir(cwd, requested) {
|
|
112727
113839
|
const raw = requested ?? "./migration-preview";
|
|
112728
|
-
return
|
|
113840
|
+
return isAbsolute4(raw) ? raw : resolve10(cwd, raw);
|
|
112729
113841
|
}
|
|
112730
113842
|
async function writePreviewFiles(ctx, outputDir, preview) {
|
|
112731
113843
|
await mkdir4(outputDir, { recursive: true });
|
|
112732
113844
|
const schemaJson = renderSchemaJson(preview);
|
|
112733
113845
|
const notesMd = renderMigrationNotes(preview);
|
|
112734
113846
|
const scripts = generateDataImportScripts(preview);
|
|
112735
|
-
const schemaPath =
|
|
112736
|
-
const notesPath =
|
|
112737
|
-
const migratePath =
|
|
112738
|
-
const storagePath =
|
|
113847
|
+
const schemaPath = join21(outputDir, "pb_schema.json");
|
|
113848
|
+
const notesPath = join21(outputDir, "MIGRATION_NOTES.md");
|
|
113849
|
+
const migratePath = join21(outputDir, "pb_migrate.js");
|
|
113850
|
+
const storagePath = join21(outputDir, "pb_migrate_storage.js");
|
|
112739
113851
|
await writeFile4(schemaPath, schemaJson, "utf8");
|
|
112740
113852
|
await writeFile4(notesPath, notesMd, "utf8");
|
|
112741
113853
|
await writeFile4(migratePath, scripts.pbMigrate, "utf8");
|
|
112742
113854
|
const written = [
|
|
112743
|
-
|
|
112744
|
-
|
|
112745
|
-
|
|
113855
|
+
relative7(ctx.cwd, schemaPath),
|
|
113856
|
+
relative7(ctx.cwd, notesPath),
|
|
113857
|
+
relative7(ctx.cwd, migratePath)
|
|
112746
113858
|
];
|
|
112747
113859
|
if (scripts.pbMigrateStorage !== null) {
|
|
112748
113860
|
await writeFile4(storagePath, scripts.pbMigrateStorage, "utf8");
|
|
112749
|
-
written.push(
|
|
113861
|
+
written.push(relative7(ctx.cwd, storagePath));
|
|
112750
113862
|
}
|
|
112751
113863
|
return written;
|
|
112752
113864
|
}
|
|
@@ -112961,8 +114073,8 @@ async function previewBranchShow(ctx, input = {}) {
|
|
|
112961
114073
|
};
|
|
112962
114074
|
}
|
|
112963
114075
|
// ../core/dist/commands/publish.js
|
|
112964
|
-
import { existsSync as
|
|
112965
|
-
import { join as
|
|
114076
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
114077
|
+
import { join as join24 } from "node:path";
|
|
112966
114078
|
|
|
112967
114079
|
// ../shared/dist/pow.js
|
|
112968
114080
|
import { createHash as createHash3 } from "node:crypto";
|
|
@@ -113339,7 +114451,7 @@ async function runDeployWithRetry(opts) {
|
|
|
113339
114451
|
|
|
113340
114452
|
// ../core/dist/commands/env-scan.js
|
|
113341
114453
|
import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
|
|
113342
|
-
import { join as
|
|
114454
|
+
import { join as join22 } from "node:path";
|
|
113343
114455
|
var SOURCE_EXTS = new Set([
|
|
113344
114456
|
".ts",
|
|
113345
114457
|
".tsx",
|
|
@@ -113376,7 +114488,7 @@ function scanForMissingBuildEnvRefs(cwd, existingKeys) {
|
|
|
113376
114488
|
continue;
|
|
113377
114489
|
let content;
|
|
113378
114490
|
try {
|
|
113379
|
-
content = readFileSync10(
|
|
114491
|
+
content = readFileSync10(join22(cwd, rel), "utf8");
|
|
113380
114492
|
} catch {
|
|
113381
114493
|
continue;
|
|
113382
114494
|
}
|
|
@@ -113408,7 +114520,7 @@ function* walkDir(dir, base) {
|
|
|
113408
114520
|
for (const name of entries) {
|
|
113409
114521
|
if (SKIP_DIRS.has(name))
|
|
113410
114522
|
continue;
|
|
113411
|
-
const full =
|
|
114523
|
+
const full = join22(dir, name);
|
|
113412
114524
|
let st;
|
|
113413
114525
|
try {
|
|
113414
114526
|
st = statSync3(full);
|
|
@@ -113768,19 +114880,19 @@ function titleFromCode(code) {
|
|
|
113768
114880
|
}
|
|
113769
114881
|
|
|
113770
114882
|
// ../core/dist/commands/publish-node.js
|
|
113771
|
-
import { existsSync as
|
|
113772
|
-
import { join as
|
|
114883
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11 } from "node:fs";
|
|
114884
|
+
import { join as join23 } from "node:path";
|
|
113773
114885
|
function resolveNodeVersion(cwd) {
|
|
113774
|
-
const nvmrc =
|
|
113775
|
-
if (
|
|
114886
|
+
const nvmrc = join23(cwd, ".nvmrc");
|
|
114887
|
+
if (existsSync14(nvmrc)) {
|
|
113776
114888
|
try {
|
|
113777
114889
|
const v = readFileSync11(nvmrc, "utf8").trim();
|
|
113778
114890
|
if (v)
|
|
113779
114891
|
return { value: v, source: ".nvmrc" };
|
|
113780
114892
|
} catch {}
|
|
113781
114893
|
}
|
|
113782
|
-
const pkgPath =
|
|
113783
|
-
if (!
|
|
114894
|
+
const pkgPath = join23(cwd, "package.json");
|
|
114895
|
+
if (!existsSync14(pkgPath))
|
|
113784
114896
|
return null;
|
|
113785
114897
|
try {
|
|
113786
114898
|
const pkg = JSON.parse(readFileSync11(pkgPath, "utf8"));
|
|
@@ -113805,7 +114917,7 @@ var publishInputSchema = exports_external.object({
|
|
|
113805
114917
|
var SUSPICIOUS_BYTES = 50 * 1024 * 1024;
|
|
113806
114918
|
var SUSPICIOUS_FILES = 1e4;
|
|
113807
114919
|
function tomlPathFor2(cwd) {
|
|
113808
|
-
return
|
|
114920
|
+
return join24(cwd, "percher.toml");
|
|
113809
114921
|
}
|
|
113810
114922
|
async function buildReplacedResult2(opts) {
|
|
113811
114923
|
const { ctx, app, deployment, tarball, cwd } = opts;
|
|
@@ -114470,8 +115582,8 @@ async function handleAnonymousPublish(ctx, config2, input, tarball) {
|
|
|
114470
115582
|
};
|
|
114471
115583
|
}
|
|
114472
115584
|
async function loadOrGenerate(ctx) {
|
|
114473
|
-
const tomlPath =
|
|
114474
|
-
if (!
|
|
115585
|
+
const tomlPath = join24(ctx.cwd, "percher.toml");
|
|
115586
|
+
if (!existsSync15(tomlPath)) {
|
|
114475
115587
|
ctx.status("No percher.toml found — detecting framework...");
|
|
114476
115588
|
await init(ctx);
|
|
114477
115589
|
}
|
|
@@ -114520,8 +115632,8 @@ function emitPreflight(ctx, config2, tarball) {
|
|
|
114520
115632
|
}
|
|
114521
115633
|
}
|
|
114522
115634
|
// ../core/dist/commands/push.js
|
|
114523
|
-
import { existsSync as
|
|
114524
|
-
import { join as
|
|
115635
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
115636
|
+
import { join as join25 } from "node:path";
|
|
114525
115637
|
var pushInputSchema = exports_external.object({
|
|
114526
115638
|
dryRun: exports_external.boolean().optional(),
|
|
114527
115639
|
force: exports_external.boolean().optional(),
|
|
@@ -114532,8 +115644,8 @@ var SUSPICIOUS_BYTES2 = 50 * 1024 * 1024;
|
|
|
114532
115644
|
var SUSPICIOUS_FILES2 = 1e4;
|
|
114533
115645
|
var PLACEHOLDER_PREFIXES = ["add-your-", "your-key-here"];
|
|
114534
115646
|
async function loadOrGenerate2(ctx) {
|
|
114535
|
-
const tomlPath =
|
|
114536
|
-
if (!
|
|
115647
|
+
const tomlPath = join25(ctx.cwd, "percher.toml");
|
|
115648
|
+
if (!existsSync16(tomlPath)) {
|
|
114537
115649
|
ctx.status("No percher.toml found — detecting framework...");
|
|
114538
115650
|
const result = await init(ctx);
|
|
114539
115651
|
const answer = await ctx.prompt(`Generated percher.toml for ${result.detected?.framework ?? result.detected?.runtime ?? "node"}. Continue? [Y/n]`, { default: "y" });
|
|
@@ -114644,7 +115756,7 @@ async function push(ctx, input = {}, internals = {}) {
|
|
|
114644
115756
|
fileCount: tarball.fileCount,
|
|
114645
115757
|
recovery: RECOVERY_NONE,
|
|
114646
115758
|
summary: `Dry run for ${config2.app.name}: ${tarball.fileCount} files, ${(tarball.bytes / 1024).toFixed(1)} KB — no deploy performed.`,
|
|
114647
|
-
configPath:
|
|
115759
|
+
configPath: join25(ctx.cwd, "percher.toml"),
|
|
114648
115760
|
bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
|
|
114649
115761
|
};
|
|
114650
115762
|
}
|
|
@@ -114827,7 +115939,7 @@ ${deployment.errorMessage}` : "";
|
|
|
114827
115939
|
fileCount: tarball.fileCount,
|
|
114828
115940
|
recovery: RECOVERY_NONE,
|
|
114829
115941
|
summary,
|
|
114830
|
-
configPath:
|
|
115942
|
+
configPath: join25(ctx.cwd, "percher.toml"),
|
|
114831
115943
|
bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
|
|
114832
115944
|
};
|
|
114833
115945
|
}
|
|
@@ -115156,8 +116268,8 @@ function failureResult(error48) {
|
|
|
115156
116268
|
};
|
|
115157
116269
|
}
|
|
115158
116270
|
// ../core/dist/commands/rename.js
|
|
115159
|
-
import { existsSync as
|
|
115160
|
-
import { join as
|
|
116271
|
+
import { existsSync as existsSync17, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
|
|
116272
|
+
import { join as join26 } from "node:path";
|
|
115161
116273
|
var renameInputSchema = exports_external.object({
|
|
115162
116274
|
app: exports_external.string().optional(),
|
|
115163
116275
|
name: exports_external.string().min(3).max(40)
|
|
@@ -115177,8 +116289,8 @@ async function rename2(ctx, input) {
|
|
|
115177
116289
|
};
|
|
115178
116290
|
}
|
|
115179
116291
|
function updateLocalTomlName(cwd, oldName, newName) {
|
|
115180
|
-
const p =
|
|
115181
|
-
if (!
|
|
116292
|
+
const p = join26(cwd, "percher.toml");
|
|
116293
|
+
if (!existsSync17(p))
|
|
115182
116294
|
return false;
|
|
115183
116295
|
try {
|
|
115184
116296
|
const src = readFileSync12(p, "utf8");
|
|
@@ -115187,25 +116299,25 @@ function updateLocalTomlName(cwd, oldName, newName) {
|
|
|
115187
116299
|
const next = src.replace(new RegExp(`(name\\s*=\\s*")${oldName}(")`), `$1${newName}$2`);
|
|
115188
116300
|
if (next === src || parse5(next).app.name !== newName)
|
|
115189
116301
|
return false;
|
|
115190
|
-
|
|
116302
|
+
writeFileSync9(p, next);
|
|
115191
116303
|
return true;
|
|
115192
116304
|
} catch {
|
|
115193
116305
|
return false;
|
|
115194
116306
|
}
|
|
115195
116307
|
}
|
|
115196
116308
|
// ../core/dist/commands/reproduce.js
|
|
115197
|
-
import { mkdtempSync, writeFileSync as
|
|
116309
|
+
import { mkdtempSync, writeFileSync as writeFileSync10 } from "node:fs";
|
|
115198
116310
|
import { tmpdir } from "node:os";
|
|
115199
|
-
import { join as
|
|
115200
|
-
var
|
|
116311
|
+
import { join as join27 } from "node:path";
|
|
116312
|
+
var import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
|
|
115201
116313
|
function runProcessExit(cmd, args, opts = {}) {
|
|
115202
|
-
return new Promise((
|
|
115203
|
-
const child =
|
|
116314
|
+
return new Promise((resolve11, reject) => {
|
|
116315
|
+
const child = import_cross_spawn2.default(cmd, args, {
|
|
115204
116316
|
cwd: opts.cwd,
|
|
115205
116317
|
stdio: opts.inherit ? "inherit" : "ignore"
|
|
115206
116318
|
});
|
|
115207
116319
|
child.on("error", reject);
|
|
115208
|
-
child.on("close", (code) =>
|
|
116320
|
+
child.on("close", (code) => resolve11(code ?? 1));
|
|
115209
116321
|
});
|
|
115210
116322
|
}
|
|
115211
116323
|
var reproduceInputSchema = exports_external.object({
|
|
@@ -115291,9 +116403,9 @@ async function reproduce(ctx, input) {
|
|
|
115291
116403
|
const envMap = await ctx.client.env.list(app.id);
|
|
115292
116404
|
currentAppEnvKeys = Object.keys(envMap).sort();
|
|
115293
116405
|
} catch {}
|
|
115294
|
-
const tmpDir = mkdtempSync(
|
|
115295
|
-
const tarballPath =
|
|
115296
|
-
|
|
116406
|
+
const tmpDir = mkdtempSync(join27(tmpdir(), `percher-reproduce-${input.deployId}-`));
|
|
116407
|
+
const tarballPath = join27(tmpDir, "source.tar.gz");
|
|
116408
|
+
writeFileSync10(tarballPath, bytes);
|
|
115297
116409
|
let extracted = false;
|
|
115298
116410
|
try {
|
|
115299
116411
|
extracted = await runProcessExit("tar", ["-xzf", tarballPath, "-C", tmpDir]) === 0;
|
|
@@ -115730,7 +116842,6 @@ var PLAN_CATALOG = {
|
|
|
115730
116842
|
priceEur: 0,
|
|
115731
116843
|
limits: {
|
|
115732
116844
|
apps: 3,
|
|
115733
|
-
deploysPerMonth: 50,
|
|
115734
116845
|
deploysPerHour: 12,
|
|
115735
116846
|
memory: "256mb",
|
|
115736
116847
|
cpu: 0.25,
|
|
@@ -115762,7 +116873,6 @@ var PLAN_CATALOG = {
|
|
|
115762
116873
|
priceEur: 3,
|
|
115763
116874
|
limits: {
|
|
115764
116875
|
apps: 10,
|
|
115765
|
-
deploysPerMonth: 200,
|
|
115766
116876
|
deploysPerHour: 30,
|
|
115767
116877
|
memory: "512mb",
|
|
115768
116878
|
cpu: 0.25,
|
|
@@ -115794,7 +116904,6 @@ var PLAN_CATALOG = {
|
|
|
115794
116904
|
priceEur: 12,
|
|
115795
116905
|
limits: {
|
|
115796
116906
|
apps: 20,
|
|
115797
|
-
deploysPerMonth: 500,
|
|
115798
116907
|
deploysPerHour: 60,
|
|
115799
116908
|
memory: "1gb",
|
|
115800
116909
|
cpu: 0.5,
|
|
@@ -115826,7 +116935,6 @@ var PLAN_CATALOG = {
|
|
|
115826
116935
|
priceEur: 29,
|
|
115827
116936
|
limits: {
|
|
115828
116937
|
apps: 40,
|
|
115829
|
-
deploysPerMonth: "unlimited",
|
|
115830
116938
|
deploysPerHour: 120,
|
|
115831
116939
|
memory: "1gb",
|
|
115832
116940
|
cpu: 1,
|
|
@@ -115859,7 +116967,6 @@ var PLAN_CATALOG = {
|
|
|
115859
116967
|
hidden: true,
|
|
115860
116968
|
limits: {
|
|
115861
116969
|
apps: 1,
|
|
115862
|
-
deploysPerMonth: 20,
|
|
115863
116970
|
deploysPerHour: 6,
|
|
115864
116971
|
memory: "128mb",
|
|
115865
116972
|
cpu: 0.25,
|
|
@@ -116551,6 +117658,36 @@ function registerAppsCommands(cli, ctx) {
|
|
|
116551
117658
|
await writeLine(ctx, `${import_picocolors4.default.green("✓")} wrote ${file2}`);
|
|
116552
117659
|
}
|
|
116553
117660
|
});
|
|
117661
|
+
cli.command("appstore-kit", "Write app-store starter files (PWA manifest, TWA/Capacitor, asset links)").option("--name <name>", "App name (defaults to percher.toml / directory)").option("--url <url>", "App URL (defaults to https://<name>.percher.run)").option("--package <pkg>", "Android package name for assetlinks.json").option("--fingerprint <sha256>", "Signing-cert SHA-256 for assetlinks.json").option("--team-id <id>", "Apple Team ID for apple-app-site-association").option("--bundle-id <id>", "Apple bundle ID for apple-app-site-association").option("--out <dir>", "Output directory (defaults to the current directory)").option("--force", "Overwrite files that already exist").action(async (options) => {
|
|
117662
|
+
const result = await appstoreKit(ctx, {
|
|
117663
|
+
name: options.name,
|
|
117664
|
+
url: options.url,
|
|
117665
|
+
packageName: options.package,
|
|
117666
|
+
fingerprint: options.fingerprint,
|
|
117667
|
+
teamId: options.teamId,
|
|
117668
|
+
bundleId: options.bundleId,
|
|
117669
|
+
outDir: options.out,
|
|
117670
|
+
force: options.force
|
|
117671
|
+
});
|
|
117672
|
+
for (const file2 of result.written) {
|
|
117673
|
+
await writeLine(ctx, `${import_picocolors4.default.green("✓")} wrote ${file2}`);
|
|
117674
|
+
}
|
|
117675
|
+
for (const file2 of result.skipped) {
|
|
117676
|
+
await writeLine(ctx, `${import_picocolors4.default.dim("•")} skipped ${file2} (exists — pass --force to overwrite)`);
|
|
117677
|
+
}
|
|
117678
|
+
await writeLine(ctx, "");
|
|
117679
|
+
await writeLine(ctx, `${import_picocolors4.default.bold("Make it an installable PWA:")} link the manifest from your HTML`);
|
|
117680
|
+
await writeLine(ctx, ` <link rel="manifest" href="/manifest.json">`);
|
|
117681
|
+
await writeLine(ctx, "and register the service worker from your app entry:");
|
|
117682
|
+
await writeLine(ctx, result.swRegistration);
|
|
117683
|
+
await writeLine(ctx, "");
|
|
117684
|
+
await writeLine(ctx, `${import_picocolors4.default.bold("Wrap for Google Play (TWA):")}`);
|
|
117685
|
+
await writeLine(ctx, result.bubblewrapCommand);
|
|
117686
|
+
await writeLine(ctx, "");
|
|
117687
|
+
await writeLine(ctx, `The two ${import_picocolors4.default.dim(".well-known")} files are trust assertions for your origin — add real values`);
|
|
117688
|
+
await writeLine(ctx, `after you sign the apps, then serve them yourself or let Percher serve them from the`);
|
|
117689
|
+
await writeLine(ctx, "App store kit at https://percher.app. Full guide: /docs/app-stores");
|
|
117690
|
+
});
|
|
116554
117691
|
cli.command("publish", "Publish this project to Percher (recommended deploy command)").option("--force", "Skip size warnings").option("--preview", "Deploy as preview (does not replace the live version)").option("-m, --message <msg>", "Deploy note (visible in deploy history)").option("--dry-run", "Show what would be deployed (file count, bytes) without uploading").option("--no-cache", "Skip image-cache lookup and force a fresh build (use when you suspect cached image is stale)").option("--anonymous", "Publish without an account — a 72h sandbox you can claim later (where enabled)").action(async (options) => {
|
|
116555
117692
|
const { detectCiBranchMessage: detectCiBranchMessage2 } = await Promise.resolve().then(() => exports_ci_env);
|
|
116556
117693
|
let messageOverride = options.message;
|
|
@@ -116632,8 +117769,8 @@ function registerAppsCommands(cli, ctx) {
|
|
|
116632
117769
|
deployId,
|
|
116633
117770
|
timeoutSeconds: Math.min(Math.ceil(remainingMs / 1000), 30)
|
|
116634
117771
|
}, { signal: callController.signal }),
|
|
116635
|
-
new Promise((
|
|
116636
|
-
raceTimer = setTimeout(() =>
|
|
117772
|
+
new Promise((resolve11) => {
|
|
117773
|
+
raceTimer = setTimeout(() => resolve11(null), remainingMs);
|
|
116637
117774
|
})
|
|
116638
117775
|
]);
|
|
116639
117776
|
} finally {
|
|
@@ -117172,7 +118309,7 @@ function registerEnvCommands(cli, ctx) {
|
|
|
117172
118309
|
if (action === "set") {
|
|
117173
118310
|
const { resolveEnvSetInputs: resolveEnvSetInputs2, EnvSetInputError: EnvSetInputError2 } = await Promise.resolve().then(() => (init_env_set_input(), exports_env_set_input));
|
|
117174
118311
|
const { promptHidden: promptHidden2 } = await Promise.resolve().then(() => (init_prompt_hidden(), exports_prompt_hidden));
|
|
117175
|
-
const { readFile:
|
|
118312
|
+
const { readFile: readFile5 } = await import("node:fs/promises");
|
|
117176
118313
|
try {
|
|
117177
118314
|
const values = await resolveEnvSetInputs2({
|
|
117178
118315
|
args,
|
|
@@ -117184,7 +118321,7 @@ function registerEnvCommands(cli, ctx) {
|
|
|
117184
118321
|
chunks.push(c);
|
|
117185
118322
|
return Buffer.concat(chunks).toString("utf8");
|
|
117186
118323
|
},
|
|
117187
|
-
readFile: async (p) =>
|
|
118324
|
+
readFile: async (p) => readFile5(p, "utf8"),
|
|
117188
118325
|
promptHidden: promptHidden2
|
|
117189
118326
|
});
|
|
117190
118327
|
await envSet(ctx, { app: options.app, values });
|
|
@@ -117298,7 +118435,24 @@ function registerGithubCommands(cli, ctx) {
|
|
|
117298
118435
|
// src/commands/migrate.ts
|
|
117299
118436
|
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
117300
118437
|
function registerMigrateCommands(cli, ctx) {
|
|
117301
|
-
cli.command("migrate-from-supabase", "Migrate a Supabase project to PocketBase: schema + data-import script, optionally rewrite SDK calls").option("--project <ref>", "Supabase project reference (the 20-char id from the project URL)").option("--token <token>", "Supabase personal access token (sbp_...). Read from SUPABASE_ACCESS_TOKEN if omitted.").option("--inspect-only", "Only print the schema that would migrate — read-only, no file writes").option("--output-dir <dir>", "Where to write the preview files (default: ./migration-preview/)").option("--rewrite-client", "Also convert your Supabase SDK calls to PocketBase across the project").option("--apply", "With --rewrite-client: overwrite files in place (originals backed up first). Default: preview only.").option("--root <dir>", "Project root to rewrite with --rewrite-client (default: current directory)").option("--json", "Output the structured result as JSON").action(async (options) => {
|
|
118438
|
+
cli.command("migrate-from-supabase", "Migrate a Supabase project to PocketBase: schema + data-import script, optionally rewrite SDK calls").option("--project <ref>", "Supabase project reference (the 20-char id from the project URL)").option("--token <token>", "Supabase personal access token (sbp_...). Read from SUPABASE_ACCESS_TOKEN if omitted.").option("--inspect-only", "Only print the schema that would migrate — read-only, no file writes").option("--output-dir <dir>", "Where to write the preview files (default: ./migration-preview/)").option("--rewrite-client", "Also convert your Supabase SDK calls to PocketBase across the project").option("--apply", "With --rewrite-client: overwrite files in place (originals backed up first). Default: preview only.").option("--root <dir>", "Project root to rewrite with --rewrite-client (default: current directory)").option("--no-scaffold-client", "With --rewrite-client: don't generate a PocketBase client module / insert pb imports (default: scaffold one)").option("--status", "Show a migration scoreboard for the local project — what's still on Supabase vs PocketBase. Local scan, no Supabase token needed.").option("--build", "With --status: also run the project build as a final gate").option("--pb-identifier <name>", "With --status: the PocketBase client identifier to check for (default: pb). Match what the rewrite used.").option("--json", "Output the structured result as JSON").action(async (options) => {
|
|
118439
|
+
if (options.status) {
|
|
118440
|
+
const result2 = await migrationStatus(ctx, {
|
|
118441
|
+
rootDir: options.root,
|
|
118442
|
+
build: options.build === true,
|
|
118443
|
+
pbIdentifier: options.pbIdentifier
|
|
118444
|
+
});
|
|
118445
|
+
if (options.json) {
|
|
118446
|
+
await writeLine(ctx, JSON.stringify(result2, null, 2));
|
|
118447
|
+
if (result2.status === "failed")
|
|
118448
|
+
throw new SilentExitError(1);
|
|
118449
|
+
return;
|
|
118450
|
+
}
|
|
118451
|
+
await renderStatusHuman(ctx, result2);
|
|
118452
|
+
if (result2.status === "failed")
|
|
118453
|
+
throw new SilentExitError(1);
|
|
118454
|
+
return;
|
|
118455
|
+
}
|
|
117302
118456
|
const projectRef = options.project;
|
|
117303
118457
|
const token = options.token ?? ctx.env.SUPABASE_ACCESS_TOKEN;
|
|
117304
118458
|
if (options.apply && !options.rewriteClient) {
|
|
@@ -117335,7 +118489,8 @@ function registerMigrateCommands(cli, ctx) {
|
|
|
117335
118489
|
if (options.rewriteClient && result.status === "ok") {
|
|
117336
118490
|
rewrite = await rewriteSupabaseClient(ctx, {
|
|
117337
118491
|
rootDir: options.root,
|
|
117338
|
-
apply: options.apply === true
|
|
118492
|
+
apply: options.apply === true,
|
|
118493
|
+
scaffoldClient: options.scaffoldClient !== false
|
|
117339
118494
|
});
|
|
117340
118495
|
}
|
|
117341
118496
|
if (options.json) {
|
|
@@ -117489,6 +118644,37 @@ ${result.skipped.length} file(s) couldn't be parsed and were skipped — listed
|
|
|
117489
118644
|
await writeLine(ctx, import_picocolors11.default.dim(result.changedCount > 0 ? "Preview only — diff ./migration-preview/rewritten/ against your project, then re-run with --rewrite-client --apply to write in place." : "Preview only — no files needed automatic rewriting; work through the manual review above."));
|
|
117490
118645
|
}
|
|
117491
118646
|
}
|
|
118647
|
+
async function renderStatusHuman(ctx, result) {
|
|
118648
|
+
if (result.status === "failed") {
|
|
118649
|
+
const err = result.error;
|
|
118650
|
+
await writeLine(ctx, `${import_picocolors11.default.red("✗")} ${err?.title ?? "Migration status scan failed"}`);
|
|
118651
|
+
if (err?.explanation)
|
|
118652
|
+
await writeLine(ctx, ` ${err.explanation}`);
|
|
118653
|
+
if (err?.suggestion)
|
|
118654
|
+
await writeLine(ctx, import_picocolors11.default.dim(` ${err.suggestion}`));
|
|
118655
|
+
return;
|
|
118656
|
+
}
|
|
118657
|
+
await writeLine(ctx, import_picocolors11.default.bold("Migration status"));
|
|
118658
|
+
await writeLine(ctx, "");
|
|
118659
|
+
for (const check2 of result.checks) {
|
|
118660
|
+
const mark = check2.status === "pass" ? import_picocolors11.default.green("✓") : check2.status === "fail" ? import_picocolors11.default.red("✗") : check2.status === "warn" ? import_picocolors11.default.yellow("⚠") : import_picocolors11.default.dim("•");
|
|
118661
|
+
const count = check2.count > 0 ? import_picocolors11.default.dim(` (${check2.count})`) : "";
|
|
118662
|
+
await writeLine(ctx, ` ${mark} ${check2.label}${count} ${import_picocolors11.default.dim(`— ${check2.detail}`)}`);
|
|
118663
|
+
for (const file2 of (check2.files ?? []).slice(0, 10)) {
|
|
118664
|
+
await writeLine(ctx, import_picocolors11.default.dim(` - ${file2}`));
|
|
118665
|
+
}
|
|
118666
|
+
if ((check2.files?.length ?? 0) > 10) {
|
|
118667
|
+
await writeLine(ctx, import_picocolors11.default.dim(` …and ${(check2.files?.length ?? 0) - 10} more`));
|
|
118668
|
+
}
|
|
118669
|
+
}
|
|
118670
|
+
if (result.build) {
|
|
118671
|
+
await writeLine(ctx, "");
|
|
118672
|
+
const mark = !result.build.ran ? import_picocolors11.default.dim("•") : result.build.passed ? import_picocolors11.default.green("✓") : import_picocolors11.default.red("✗");
|
|
118673
|
+
await writeLine(ctx, ` ${mark} Build ${import_picocolors11.default.dim(`— ${result.build.detail}`)}`);
|
|
118674
|
+
}
|
|
118675
|
+
await writeLine(ctx, "");
|
|
118676
|
+
await writeLine(ctx, import_picocolors11.default.dim(result.summary));
|
|
118677
|
+
}
|
|
117492
118678
|
|
|
117493
118679
|
// src/commands/sharing.ts
|
|
117494
118680
|
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
@@ -117828,7 +119014,7 @@ async function renderError(stderr, error48) {
|
|
|
117828
119014
|
// package.json
|
|
117829
119015
|
var package_default = {
|
|
117830
119016
|
name: "percher",
|
|
117831
|
-
version: "0.5.
|
|
119017
|
+
version: "0.5.9",
|
|
117832
119018
|
description: "CLI for the Percher hosting platform — publish apps with one command",
|
|
117833
119019
|
type: "module",
|
|
117834
119020
|
bin: {
|
|
@@ -117909,18 +119095,18 @@ async function showTelemetryNotice() {
|
|
|
117909
119095
|
if (isDisabled())
|
|
117910
119096
|
return;
|
|
117911
119097
|
const { homedir: homedir2 } = await import("node:os");
|
|
117912
|
-
const { existsSync:
|
|
117913
|
-
const { join:
|
|
117914
|
-
const configDir =
|
|
117915
|
-
const markerFile =
|
|
117916
|
-
if (
|
|
119098
|
+
const { existsSync: existsSync18, mkdirSync: mkdirSync7, writeFileSync: writeFileSync11 } = await import("node:fs");
|
|
119099
|
+
const { join: join28 } = await import("node:path");
|
|
119100
|
+
const configDir = join28(homedir2(), ".percher");
|
|
119101
|
+
const markerFile = join28(configDir, ".telemetry-notice-shown");
|
|
119102
|
+
if (existsSync18(markerFile))
|
|
117917
119103
|
return;
|
|
117918
119104
|
console.log("Percher sends non-account-linked usage stats (command, result, error type, OS, Bun version).");
|
|
117919
119105
|
console.log(`Disable with PERCHER_NO_TELEMETRY=1
|
|
117920
119106
|
`);
|
|
117921
119107
|
try {
|
|
117922
|
-
|
|
117923
|
-
|
|
119108
|
+
mkdirSync7(configDir, { recursive: true });
|
|
119109
|
+
writeFileSync11(markerFile, new Date().toISOString());
|
|
117924
119110
|
} catch {}
|
|
117925
119111
|
}
|
|
117926
119112
|
|