percher 0.5.8 → 0.5.10
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 +506 -263
- package/dist/package.json +2 -2
- 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/templates/astro/Dockerfile +35 -34
- package/dist/templates/astro/src/pages/index.astro +1 -1
- package/dist/templates/eleventy/Dockerfile +35 -34
- package/dist/templates/hugo/Dockerfile +33 -32
- package/dist/templates/laravel/Dockerfile +5 -1
- package/dist/templates/nextjs/next.config.mjs +8 -0
- package/dist/templates/nextjs/package.json +6 -0
- package/dist/templates/preact/Dockerfile +35 -34
- package/dist/templates/python/nixpacks.toml +8 -0
- package/dist/templates/python/percher.toml +1 -0
- package/dist/templates/rust/Dockerfile +5 -1
- package/dist/templates/solid/Dockerfile +35 -34
- package/dist/templates/vite-react/Dockerfile +35 -34
- package/dist/templates/vite-vue/Dockerfile +35 -34
- package/package.json +2 -2
- package/dist/templates/nextjs/next.config.ts +0 -5
- package/dist/templates/node/index.ts +0 -12
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);
|
|
@@ -85326,12 +85326,12 @@ var require_isexe = __commonJS((exports, module) => {
|
|
|
85326
85326
|
if (typeof Promise !== "function") {
|
|
85327
85327
|
throw new TypeError("callback not provided");
|
|
85328
85328
|
}
|
|
85329
|
-
return new Promise(function(
|
|
85329
|
+
return new Promise(function(resolve7, reject) {
|
|
85330
85330
|
isexe(path, options || {}, function(er, is) {
|
|
85331
85331
|
if (er) {
|
|
85332
85332
|
reject(er);
|
|
85333
85333
|
} else {
|
|
85334
|
-
|
|
85334
|
+
resolve7(is);
|
|
85335
85335
|
}
|
|
85336
85336
|
});
|
|
85337
85337
|
});
|
|
@@ -85393,27 +85393,27 @@ var require_which = __commonJS((exports, module) => {
|
|
|
85393
85393
|
opt = {};
|
|
85394
85394
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
85395
85395
|
const found = [];
|
|
85396
|
-
const step = (i) => new Promise((
|
|
85396
|
+
const step = (i) => new Promise((resolve7, reject) => {
|
|
85397
85397
|
if (i === pathEnv.length)
|
|
85398
|
-
return opt.all && found.length ?
|
|
85398
|
+
return opt.all && found.length ? resolve7(found) : reject(getNotFoundError(cmd));
|
|
85399
85399
|
const ppRaw = pathEnv[i];
|
|
85400
85400
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
85401
85401
|
const pCmd = path.join(pathPart, cmd);
|
|
85402
85402
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
85403
|
-
|
|
85403
|
+
resolve7(subStep(p, i, 0));
|
|
85404
85404
|
});
|
|
85405
|
-
const subStep = (p, i, ii) => new Promise((
|
|
85405
|
+
const subStep = (p, i, ii) => new Promise((resolve7, reject) => {
|
|
85406
85406
|
if (ii === pathExt.length)
|
|
85407
|
-
return
|
|
85407
|
+
return resolve7(step(i + 1));
|
|
85408
85408
|
const ext = pathExt[ii];
|
|
85409
85409
|
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
85410
85410
|
if (!er && is) {
|
|
85411
85411
|
if (opt.all)
|
|
85412
85412
|
found.push(p + ext);
|
|
85413
85413
|
else
|
|
85414
|
-
return
|
|
85414
|
+
return resolve7(p + ext);
|
|
85415
85415
|
}
|
|
85416
|
-
return
|
|
85416
|
+
return resolve7(subStep(p, i, ii + 1));
|
|
85417
85417
|
});
|
|
85418
85418
|
});
|
|
85419
85419
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -89840,10 +89840,10 @@ var require_browser = __commonJS((exports) => {
|
|
|
89840
89840
|
text = canvas;
|
|
89841
89841
|
canvas = undefined;
|
|
89842
89842
|
}
|
|
89843
|
-
return new Promise(function(
|
|
89843
|
+
return new Promise(function(resolve11, reject) {
|
|
89844
89844
|
try {
|
|
89845
89845
|
const data2 = QRCode.create(text, opts);
|
|
89846
|
-
|
|
89846
|
+
resolve11(renderFunc(data2, canvas, opts));
|
|
89847
89847
|
} catch (e) {
|
|
89848
89848
|
reject(e);
|
|
89849
89849
|
}
|
|
@@ -89922,11 +89922,11 @@ var require_server = __commonJS((exports) => {
|
|
|
89922
89922
|
}
|
|
89923
89923
|
function render(renderFunc, text, params) {
|
|
89924
89924
|
if (!params.cb) {
|
|
89925
|
-
return new Promise(function(
|
|
89925
|
+
return new Promise(function(resolve11, reject) {
|
|
89926
89926
|
try {
|
|
89927
89927
|
const data2 = QRCode.create(text, params.opts);
|
|
89928
89928
|
return renderFunc(data2, params.opts, function(err, data3) {
|
|
89929
|
-
return err ? reject(err) :
|
|
89929
|
+
return err ? reject(err) : resolve11(data3);
|
|
89930
89930
|
});
|
|
89931
89931
|
} catch (e) {
|
|
89932
89932
|
reject(e);
|
|
@@ -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") {
|
|
@@ -90873,10 +90873,6 @@ var CAC = class extends EventTarget {
|
|
|
90873
90873
|
};
|
|
90874
90874
|
var cac = (name = "") => new CAC(name);
|
|
90875
90875
|
|
|
90876
|
-
// ../core/dist/app-name.js
|
|
90877
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
90878
|
-
import { join } from "node:path";
|
|
90879
|
-
|
|
90880
90876
|
// ../toml/dist/errors.js
|
|
90881
90877
|
class PercherTomlError extends Error {
|
|
90882
90878
|
code;
|
|
@@ -104801,6 +104797,8 @@ function serialize(config2) {
|
|
|
104801
104797
|
return import_toml2.default.stringify(config2);
|
|
104802
104798
|
}
|
|
104803
104799
|
// ../core/dist/app-name.js
|
|
104800
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
104801
|
+
import { join } from "node:path";
|
|
104804
104802
|
function readPercherTomlAppName(cwd) {
|
|
104805
104803
|
const p = join(cwd, "percher.toml");
|
|
104806
104804
|
if (!existsSync(p))
|
|
@@ -105399,6 +105397,181 @@ var appResourcesInputSchema = exports_external.object({
|
|
|
105399
105397
|
var appTopologyInputSchema = exports_external.object({
|
|
105400
105398
|
app: exports_external.string().optional()
|
|
105401
105399
|
});
|
|
105400
|
+
// ../core/dist/commands/appstore-kit.js
|
|
105401
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
105402
|
+
import { basename, dirname as dirname3, isAbsolute, join as join5, relative, resolve as resolve3, sep } from "node:path";
|
|
105403
|
+
|
|
105404
|
+
// ../core/dist/appstore-artifacts.js
|
|
105405
|
+
var BRAND_GREEN = "#2d6a4f";
|
|
105406
|
+
var ICON_COLOUR_HEX = {
|
|
105407
|
+
green: BRAND_GREEN,
|
|
105408
|
+
terracotta: "#d0653a",
|
|
105409
|
+
blue: "#4a6fa4",
|
|
105410
|
+
purple: "#6e4dba",
|
|
105411
|
+
olive: "#b8923a"
|
|
105412
|
+
};
|
|
105413
|
+
function themeColorForToken(token) {
|
|
105414
|
+
if (token && token in ICON_COLOUR_HEX)
|
|
105415
|
+
return ICON_COLOUR_HEX[token] ?? BRAND_GREEN;
|
|
105416
|
+
return BRAND_GREEN;
|
|
105417
|
+
}
|
|
105418
|
+
function hostFromUrl(url2) {
|
|
105419
|
+
try {
|
|
105420
|
+
return new URL(url2).host;
|
|
105421
|
+
} catch {
|
|
105422
|
+
return url2.replace(/^https?:\/\//, "").replace(/\/.*$/, "");
|
|
105423
|
+
}
|
|
105424
|
+
}
|
|
105425
|
+
function shortName(name) {
|
|
105426
|
+
const cleaned = name.replace(/[^A-Za-z0-9]/g, "");
|
|
105427
|
+
return (cleaned || "App").slice(0, 12);
|
|
105428
|
+
}
|
|
105429
|
+
function manifestStarter({ name, themeColorHex }) {
|
|
105430
|
+
return JSON.stringify({
|
|
105431
|
+
name,
|
|
105432
|
+
short_name: shortName(name),
|
|
105433
|
+
start_url: "/",
|
|
105434
|
+
display: "standalone",
|
|
105435
|
+
background_color: "#ffffff",
|
|
105436
|
+
theme_color: themeColorHex
|
|
105437
|
+
}, null, 2);
|
|
105438
|
+
}
|
|
105439
|
+
function serviceWorkerStarter() {
|
|
105440
|
+
return `// sw.js — minimal offline shell. Drop in at your app root and serve from /sw.js.
|
|
105441
|
+
const CACHE = "app-shell-v1";
|
|
105442
|
+
const SHELL = ["/"];
|
|
105443
|
+
|
|
105444
|
+
self.addEventListener("install", (event) => {
|
|
105445
|
+
event.waitUntil(caches.open(CACHE).then((cache) => cache.addAll(SHELL)));
|
|
105446
|
+
self.skipWaiting();
|
|
105447
|
+
});
|
|
105448
|
+
|
|
105449
|
+
self.addEventListener("activate", (event) => {
|
|
105450
|
+
event.waitUntil(
|
|
105451
|
+
caches.keys().then((keys) =>
|
|
105452
|
+
Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k))),
|
|
105453
|
+
),
|
|
105454
|
+
);
|
|
105455
|
+
self.clients.claim();
|
|
105456
|
+
});
|
|
105457
|
+
|
|
105458
|
+
self.addEventListener("fetch", (event) => {
|
|
105459
|
+
if (event.request.method !== "GET") return;
|
|
105460
|
+
event.respondWith(
|
|
105461
|
+
caches.match(event.request).then((cached) => cached || fetch(event.request)),
|
|
105462
|
+
);
|
|
105463
|
+
});`;
|
|
105464
|
+
}
|
|
105465
|
+
function swRegistrationSnippet() {
|
|
105466
|
+
return `if ("serviceWorker" in navigator) {
|
|
105467
|
+
navigator.serviceWorker.register("/sw.js");
|
|
105468
|
+
}`;
|
|
105469
|
+
}
|
|
105470
|
+
function bubblewrapCommand({ url: url2 }) {
|
|
105471
|
+
const host = hostFromUrl(url2);
|
|
105472
|
+
return `# generate the Android project, pointed at your manifest
|
|
105473
|
+
npx @bubblewrap/cli init --manifest https://${host}/manifest.json
|
|
105474
|
+
npx @bubblewrap/cli build`;
|
|
105475
|
+
}
|
|
105476
|
+
function capacitorConfig({ name, url: url2 }) {
|
|
105477
|
+
const host = hostFromUrl(url2);
|
|
105478
|
+
return `import type { CapacitorConfig } from "@capacitor/cli";
|
|
105479
|
+
const config: CapacitorConfig = {
|
|
105480
|
+
appId: "app.percher.yourapp",
|
|
105481
|
+
appName: ${JSON.stringify(name)},
|
|
105482
|
+
webDir: "dist",
|
|
105483
|
+
server: { url: "https://${host}", cleartext: false },
|
|
105484
|
+
};
|
|
105485
|
+
export default config;`;
|
|
105486
|
+
}
|
|
105487
|
+
function assetlinksJson({ packageName, sha256Fingerprint }) {
|
|
105488
|
+
const pkg = packageName.trim() || "app.percher.yourapp";
|
|
105489
|
+
const fp = sha256Fingerprint.trim() || "<your signing cert SHA-256>";
|
|
105490
|
+
return `[{
|
|
105491
|
+
"relation": ["delegate_permission/common.handle_all_urls"],
|
|
105492
|
+
"target": {
|
|
105493
|
+
"namespace": "android_app",
|
|
105494
|
+
"package_name": ${JSON.stringify(pkg)},
|
|
105495
|
+
"sha256_cert_fingerprints": [${JSON.stringify(fp)}]
|
|
105496
|
+
}
|
|
105497
|
+
}]`;
|
|
105498
|
+
}
|
|
105499
|
+
function appleAppSiteAssociation({ teamId, bundleId }) {
|
|
105500
|
+
const team = teamId.trim() || "TEAMID";
|
|
105501
|
+
const bundle = bundleId.trim() || "app.percher.yourapp";
|
|
105502
|
+
return `{
|
|
105503
|
+
"applinks": {
|
|
105504
|
+
"apps": [],
|
|
105505
|
+
"details": [{ "appID": ${JSON.stringify(`${team}.${bundle}`)}, "paths": ["*"] }]
|
|
105506
|
+
}
|
|
105507
|
+
}`;
|
|
105508
|
+
}
|
|
105509
|
+
|
|
105510
|
+
// ../core/dist/commands/appstore-kit.js
|
|
105511
|
+
var appstoreKitInputSchema = exports_external.object({
|
|
105512
|
+
name: exports_external.string().optional(),
|
|
105513
|
+
url: exports_external.string().optional(),
|
|
105514
|
+
packageName: exports_external.string().optional(),
|
|
105515
|
+
fingerprint: exports_external.string().optional(),
|
|
105516
|
+
teamId: exports_external.string().optional(),
|
|
105517
|
+
bundleId: exports_external.string().optional(),
|
|
105518
|
+
force: exports_external.boolean().optional(),
|
|
105519
|
+
outDir: exports_external.string().optional()
|
|
105520
|
+
});
|
|
105521
|
+
async function appstoreKit(ctx, input = {}) {
|
|
105522
|
+
const name = (input.name ?? readPercherTomlAppName(ctx.cwd) ?? basename(ctx.cwd) ?? "app").trim() || "app";
|
|
105523
|
+
const url2 = input.url?.trim() || `https://${name}.percher.run`;
|
|
105524
|
+
const themeHex = themeColorForToken(null);
|
|
105525
|
+
const base = resolve3(ctx.cwd, input.outDir ?? ".");
|
|
105526
|
+
const baseRel = relative(ctx.cwd, base);
|
|
105527
|
+
if (baseRel === ".." || baseRel.startsWith(`..${sep}`) || isAbsolute(baseRel)) {
|
|
105528
|
+
throw new PercherCoreError("Output directory must stay inside the project", {
|
|
105529
|
+
code: "appstore-kit.bad-out-dir",
|
|
105530
|
+
hint: "Pass a path inside the current project (e.g. --out public), not an absolute or parent path."
|
|
105531
|
+
});
|
|
105532
|
+
}
|
|
105533
|
+
const files = [
|
|
105534
|
+
{ rel: "manifest.json", content: manifestStarter({ name, themeColorHex: themeHex }) },
|
|
105535
|
+
{ rel: "sw.js", content: serviceWorkerStarter() },
|
|
105536
|
+
{ rel: "capacitor.config.ts", content: capacitorConfig({ name, url: url2 }) },
|
|
105537
|
+
{
|
|
105538
|
+
rel: ".well-known/assetlinks.json",
|
|
105539
|
+
content: assetlinksJson({
|
|
105540
|
+
packageName: input.packageName ?? "",
|
|
105541
|
+
sha256Fingerprint: input.fingerprint ?? ""
|
|
105542
|
+
})
|
|
105543
|
+
},
|
|
105544
|
+
{
|
|
105545
|
+
rel: ".well-known/apple-app-site-association",
|
|
105546
|
+
content: appleAppSiteAssociation({
|
|
105547
|
+
teamId: input.teamId ?? "",
|
|
105548
|
+
bundleId: input.bundleId ?? ""
|
|
105549
|
+
})
|
|
105550
|
+
}
|
|
105551
|
+
];
|
|
105552
|
+
const written = [];
|
|
105553
|
+
const skipped = [];
|
|
105554
|
+
for (const f of files) {
|
|
105555
|
+
const abs = join5(base, ...f.rel.split("/"));
|
|
105556
|
+
const display = relative(ctx.cwd, abs).split(sep).join("/");
|
|
105557
|
+
if (existsSync3(abs) && !input.force) {
|
|
105558
|
+
skipped.push(display);
|
|
105559
|
+
continue;
|
|
105560
|
+
}
|
|
105561
|
+
mkdirSync3(dirname3(abs), { recursive: true });
|
|
105562
|
+
writeFileSync3(abs, `${f.content}
|
|
105563
|
+
`, "utf8");
|
|
105564
|
+
written.push(display);
|
|
105565
|
+
}
|
|
105566
|
+
return {
|
|
105567
|
+
appName: name,
|
|
105568
|
+
appUrl: url2,
|
|
105569
|
+
written,
|
|
105570
|
+
skipped,
|
|
105571
|
+
bubblewrapCommand: bubblewrapCommand({ url: url2 }),
|
|
105572
|
+
swRegistration: swRegistrationSnippet()
|
|
105573
|
+
};
|
|
105574
|
+
}
|
|
105402
105575
|
// ../core/dist/commands/billing.js
|
|
105403
105576
|
var billingUpgradeInputSchema = exports_external.object({
|
|
105404
105577
|
plan: exports_external.enum(["starter", "maker", "pro"])
|
|
@@ -105422,22 +105595,22 @@ async function cacheReset(ctx, input = {}) {
|
|
|
105422
105595
|
var capabilitiesInputSchema = exports_external.object({});
|
|
105423
105596
|
// ../client/dist/abortable-sleep.js
|
|
105424
105597
|
function abortableSleep(ms, signal) {
|
|
105425
|
-
return new Promise((
|
|
105598
|
+
return new Promise((resolve4) => {
|
|
105426
105599
|
if (!signal) {
|
|
105427
|
-
setTimeout(
|
|
105600
|
+
setTimeout(resolve4, ms);
|
|
105428
105601
|
return;
|
|
105429
105602
|
}
|
|
105430
105603
|
if (signal.aborted) {
|
|
105431
|
-
|
|
105604
|
+
resolve4();
|
|
105432
105605
|
return;
|
|
105433
105606
|
}
|
|
105434
105607
|
const onAbort = () => {
|
|
105435
105608
|
clearTimeout(t);
|
|
105436
|
-
|
|
105609
|
+
resolve4();
|
|
105437
105610
|
};
|
|
105438
105611
|
const t = setTimeout(() => {
|
|
105439
105612
|
signal.removeEventListener("abort", onAbort);
|
|
105440
|
-
|
|
105613
|
+
resolve4();
|
|
105441
105614
|
}, ms);
|
|
105442
105615
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
105443
105616
|
});
|
|
@@ -105456,9 +105629,9 @@ function isAutoForwardedBuildKey(name) {
|
|
|
105456
105629
|
return AUTO_FORWARD_PREFIXES.some((p) => name.startsWith(p));
|
|
105457
105630
|
}
|
|
105458
105631
|
// ../client/dist/config.js
|
|
105459
|
-
import { existsSync as
|
|
105632
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
105460
105633
|
import { homedir } from "node:os";
|
|
105461
|
-
import { dirname as
|
|
105634
|
+
import { dirname as dirname4, join as join6 } from "node:path";
|
|
105462
105635
|
var DEFAULT_API_URL = "https://api.percher.run";
|
|
105463
105636
|
function home() {
|
|
105464
105637
|
return process.env.HOME ?? process.env.USERPROFILE ?? homedir();
|
|
@@ -105466,12 +105639,12 @@ function home() {
|
|
|
105466
105639
|
function configPath() {
|
|
105467
105640
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
105468
105641
|
if (xdg)
|
|
105469
|
-
return
|
|
105470
|
-
return
|
|
105642
|
+
return join6(xdg, "percher", "config.json");
|
|
105643
|
+
return join6(home(), ".percher", "config.json");
|
|
105471
105644
|
}
|
|
105472
105645
|
function readFile2() {
|
|
105473
105646
|
const p = configPath();
|
|
105474
|
-
if (!
|
|
105647
|
+
if (!existsSync4(p))
|
|
105475
105648
|
return {};
|
|
105476
105649
|
try {
|
|
105477
105650
|
const parsed = JSON.parse(readFileSync4(p, "utf8"));
|
|
@@ -105499,11 +105672,11 @@ function readAnonClaims() {
|
|
|
105499
105672
|
}
|
|
105500
105673
|
function saveConfig(partial2) {
|
|
105501
105674
|
const p = configPath();
|
|
105502
|
-
|
|
105675
|
+
mkdirSync4(dirname4(p), { recursive: true });
|
|
105503
105676
|
const current = readFile2();
|
|
105504
105677
|
const merged = { ...current, ...partial2 };
|
|
105505
105678
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
105506
|
-
|
|
105679
|
+
writeFileSync4(tmp, JSON.stringify(merged, null, 2), "utf8");
|
|
105507
105680
|
renameSync(tmp, p);
|
|
105508
105681
|
}
|
|
105509
105682
|
function getAnonClaim(app) {
|
|
@@ -105907,6 +106080,15 @@ class AppsResource {
|
|
|
105907
106080
|
unsetPreviewBranch(appRef) {
|
|
105908
106081
|
return this.http.deleteJson(`/apps/${encodeURIComponent(appRef)}/preview-branch`);
|
|
105909
106082
|
}
|
|
106083
|
+
listWellKnown(appRef) {
|
|
106084
|
+
return this.http.get(`/apps/${encodeURIComponent(appRef)}/well-known`);
|
|
106085
|
+
}
|
|
106086
|
+
setWellKnown(appRef, kind, content) {
|
|
106087
|
+
return this.http.put(`/apps/${encodeURIComponent(appRef)}/well-known/${encodeURIComponent(kind)}`, { content });
|
|
106088
|
+
}
|
|
106089
|
+
clearWellKnown(appRef, kind) {
|
|
106090
|
+
return this.http.deleteJson(`/apps/${encodeURIComponent(appRef)}/well-known/${encodeURIComponent(kind)}`);
|
|
106091
|
+
}
|
|
105910
106092
|
setDescription(appRef, description) {
|
|
105911
106093
|
return this.http.patch(`/apps/${encodeURIComponent(appRef)}/description`, {
|
|
105912
106094
|
description
|
|
@@ -106582,17 +106764,17 @@ async function claim(ctx, input = {}) {
|
|
|
106582
106764
|
};
|
|
106583
106765
|
}
|
|
106584
106766
|
// ../core/dist/commands/create.js
|
|
106585
|
-
import { join as
|
|
106767
|
+
import { join as join8, resolve as resolve5 } from "node:path";
|
|
106586
106768
|
|
|
106587
106769
|
// ../core/dist/templates.js
|
|
106588
|
-
import { existsSync as
|
|
106589
|
-
import { basename, join as
|
|
106770
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readdirSync, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
106771
|
+
import { basename as basename2, join as join7, normalize, relative as relative2, resolve as resolve4 } from "node:path";
|
|
106590
106772
|
var __dirname = "C:\\dev\\Percher\\packages\\core\\dist";
|
|
106591
|
-
var TEMPLATES_DIR =
|
|
106773
|
+
var TEMPLATES_DIR = resolve4(import.meta.dirname ?? __dirname, "../templates");
|
|
106592
106774
|
var PLACEHOLDER = "__APP_NAME__";
|
|
106593
106775
|
function listTemplates() {
|
|
106594
106776
|
return readdirSync(TEMPLATES_DIR).filter((name) => {
|
|
106595
|
-
const full =
|
|
106777
|
+
const full = join7(TEMPLATES_DIR, name);
|
|
106596
106778
|
return statSync(full).isDirectory();
|
|
106597
106779
|
});
|
|
106598
106780
|
}
|
|
@@ -106602,36 +106784,36 @@ function scaffoldTemplate(input) {
|
|
|
106602
106784
|
if (!available.includes(template)) {
|
|
106603
106785
|
throw new Error(`Unknown template "${template}". Available: ${available.join(", ")}`);
|
|
106604
106786
|
}
|
|
106605
|
-
const absTarget =
|
|
106606
|
-
if (
|
|
106787
|
+
const absTarget = resolve4(targetDir);
|
|
106788
|
+
if (existsSync5(absTarget)) {
|
|
106607
106789
|
const entries = readdirSync(absTarget);
|
|
106608
106790
|
if (entries.length > 0 && !force) {
|
|
106609
106791
|
throw new Error(`Target directory "${absTarget}" is not empty. Use --force to overwrite.`);
|
|
106610
106792
|
}
|
|
106611
106793
|
}
|
|
106612
|
-
const srcDir =
|
|
106794
|
+
const srcDir = join7(TEMPLATES_DIR, template);
|
|
106613
106795
|
const files = [];
|
|
106614
106796
|
function copyDir(src, dest) {
|
|
106615
|
-
|
|
106797
|
+
mkdirSync5(dest, { recursive: true });
|
|
106616
106798
|
for (const entry of readdirSync(src)) {
|
|
106617
|
-
const srcPath =
|
|
106618
|
-
const destPath =
|
|
106619
|
-
const rel =
|
|
106620
|
-
if (rel.startsWith("..") ||
|
|
106799
|
+
const srcPath = join7(src, entry);
|
|
106800
|
+
const destPath = join7(dest, entry);
|
|
106801
|
+
const rel = relative2(absTarget, normalize(destPath));
|
|
106802
|
+
if (rel.startsWith("..") || resolve4(destPath) === resolve4(absTarget, "..", basename2(absTarget))) {
|
|
106621
106803
|
throw new Error(`Template contains path traversal: ${entry}`);
|
|
106622
106804
|
}
|
|
106623
106805
|
if (statSync(srcPath).isDirectory()) {
|
|
106624
106806
|
copyDir(srcPath, destPath);
|
|
106625
106807
|
} else {
|
|
106626
|
-
if (
|
|
106808
|
+
if (existsSync5(destPath) && !force) {
|
|
106627
106809
|
continue;
|
|
106628
106810
|
}
|
|
106629
106811
|
let content = readFileSync5(srcPath, "utf-8");
|
|
106630
106812
|
content = content.replaceAll(PLACEHOLDER, appName);
|
|
106631
106813
|
content = content.replace(/\r\n/g, `
|
|
106632
106814
|
`);
|
|
106633
|
-
|
|
106634
|
-
files.push(
|
|
106815
|
+
writeFileSync5(destPath, content, "utf-8");
|
|
106816
|
+
files.push(relative2(absTarget, destPath).replace(/\\/g, "/"));
|
|
106635
106817
|
}
|
|
106636
106818
|
}
|
|
106637
106819
|
}
|
|
@@ -106656,14 +106838,14 @@ async function create(ctx, input) {
|
|
|
106656
106838
|
}
|
|
106657
106839
|
let targetDir;
|
|
106658
106840
|
if (input.directory) {
|
|
106659
|
-
targetDir =
|
|
106660
|
-
if (!targetDir.startsWith(
|
|
106841
|
+
targetDir = resolve5(ctx.cwd, input.directory);
|
|
106842
|
+
if (!targetDir.startsWith(resolve5(ctx.cwd))) {
|
|
106661
106843
|
throw new PercherCoreError("Directory must be within the current workspace", {
|
|
106662
106844
|
code: "create.failed"
|
|
106663
106845
|
});
|
|
106664
106846
|
}
|
|
106665
106847
|
} else {
|
|
106666
|
-
targetDir =
|
|
106848
|
+
targetDir = join8(ctx.cwd, input.name);
|
|
106667
106849
|
}
|
|
106668
106850
|
try {
|
|
106669
106851
|
const result = scaffoldTemplate({
|
|
@@ -106759,7 +106941,7 @@ async function data(ctx, input = {}) {
|
|
|
106759
106941
|
};
|
|
106760
106942
|
}
|
|
106761
106943
|
// ../core/dist/commands/data-export.js
|
|
106762
|
-
import { resolve as
|
|
106944
|
+
import { resolve as resolve6 } from "node:path";
|
|
106763
106945
|
var dataExportInputSchema = exports_external.object({
|
|
106764
106946
|
app: exports_external.string().optional().describe("App name or id. Defaults to the app in percher.toml."),
|
|
106765
106947
|
out: exports_external.string().optional().describe("Output file path. Defaults to ./<app>-pb-<timestamp>.tar.gz in the current directory.")
|
|
@@ -106775,7 +106957,7 @@ async function dataExport(ctx, input) {
|
|
|
106775
106957
|
ctx.status?.(`Exporting ${appName} data...`);
|
|
106776
106958
|
const stamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
106777
106959
|
const fileName = input.out ?? `${appName}-pb-${stamp}.tar.gz`;
|
|
106778
|
-
const path =
|
|
106960
|
+
const path = resolve6(ctx.cwd, fileName);
|
|
106779
106961
|
const res = await ctx.client.apps.streamDataExport(appName);
|
|
106780
106962
|
const bytes = await writeResponseToFile(res, path);
|
|
106781
106963
|
return {
|
|
@@ -106871,14 +107053,14 @@ async function deploysInspect(ctx, input) {
|
|
|
106871
107053
|
return { deploy, buildLog };
|
|
106872
107054
|
}
|
|
106873
107055
|
// ../core/dist/commands/dev.js
|
|
106874
|
-
import { existsSync as
|
|
106875
|
-
import { join as
|
|
107056
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
107057
|
+
import { join as join11 } from "node:path";
|
|
106876
107058
|
|
|
106877
107059
|
// ../core/dist/tarball.js
|
|
106878
107060
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
106879
107061
|
import { createHash as createHash2 } from "node:crypto";
|
|
106880
|
-
import { existsSync as
|
|
106881
|
-
import { join as
|
|
107062
|
+
import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync2 } from "node:fs";
|
|
107063
|
+
import { join as join9, relative as relative3, sep as sep2 } from "node:path";
|
|
106882
107064
|
import { Readable } from "node:stream";
|
|
106883
107065
|
import { createGzip } from "node:zlib";
|
|
106884
107066
|
|
|
@@ -106904,8 +107086,8 @@ var DEFAULT_IGNORE = [
|
|
|
106904
107086
|
function* walk(dir, baseDir, ig) {
|
|
106905
107087
|
const entries = readdirSync2(dir);
|
|
106906
107088
|
for (const name of entries) {
|
|
106907
|
-
const full =
|
|
106908
|
-
const rel =
|
|
107089
|
+
const full = join9(dir, name);
|
|
107090
|
+
const rel = relative3(baseDir, full).split(sep2).join("/");
|
|
106909
107091
|
if (ig.ignores(rel))
|
|
106910
107092
|
continue;
|
|
106911
107093
|
const stats = statSync2(full);
|
|
@@ -106921,15 +107103,15 @@ function* walk(dir, baseDir, ig) {
|
|
|
106921
107103
|
async function createTarball(options) {
|
|
106922
107104
|
const ig = import_ignore.default();
|
|
106923
107105
|
ig.add(DEFAULT_IGNORE);
|
|
106924
|
-
const gitignorePath =
|
|
106925
|
-
if (
|
|
107106
|
+
const gitignorePath = join9(options.cwd, ".gitignore");
|
|
107107
|
+
if (existsSync6(gitignorePath)) {
|
|
106926
107108
|
ig.add(readFileSync6(gitignorePath, "utf8"));
|
|
106927
107109
|
}
|
|
106928
107110
|
if (options.extraIgnore)
|
|
106929
107111
|
ig.add(options.extraIgnore);
|
|
106930
107112
|
const fileBuffers = [];
|
|
106931
107113
|
for (const rel of walk(options.cwd, options.cwd, ig)) {
|
|
106932
|
-
const data2 = readFileSync6(
|
|
107114
|
+
const data2 = readFileSync6(join9(options.cwd, rel));
|
|
106933
107115
|
fileBuffers.push({ path: rel, size: data2.length, data: data2 });
|
|
106934
107116
|
}
|
|
106935
107117
|
fileBuffers.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
@@ -106948,8 +107130,8 @@ async function createTarball(options) {
|
|
|
106948
107130
|
const pack = $pack();
|
|
106949
107131
|
(async () => {
|
|
106950
107132
|
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) :
|
|
107133
|
+
await new Promise((resolve7, reject) => {
|
|
107134
|
+
pack.entry({ name: file2.path, size: file2.data.length }, file2.data, (err) => err ? reject(err) : resolve7());
|
|
106953
107135
|
});
|
|
106954
107136
|
}
|
|
106955
107137
|
pack.finalize();
|
|
@@ -106969,8 +107151,8 @@ async function createTarball(options) {
|
|
|
106969
107151
|
|
|
106970
107152
|
// ../core/dist/watcher.js
|
|
106971
107153
|
var import_ignore2 = __toESM(require_ignore(), 1);
|
|
106972
|
-
import { existsSync as
|
|
106973
|
-
import { join as
|
|
107154
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, watch } from "node:fs";
|
|
107155
|
+
import { join as join10, sep as sep3 } from "node:path";
|
|
106974
107156
|
var DEFAULT_IGNORE2 = [
|
|
106975
107157
|
"node_modules",
|
|
106976
107158
|
".git",
|
|
@@ -106990,8 +107172,8 @@ function createWatcher(options) {
|
|
|
106990
107172
|
const debounceMs = options.debounceMs ?? 500;
|
|
106991
107173
|
const ig = import_ignore2.default();
|
|
106992
107174
|
ig.add(DEFAULT_IGNORE2);
|
|
106993
|
-
const gitignorePath =
|
|
106994
|
-
if (
|
|
107175
|
+
const gitignorePath = join10(options.cwd, ".gitignore");
|
|
107176
|
+
if (existsSync7(gitignorePath)) {
|
|
106995
107177
|
ig.add(readFileSync7(gitignorePath, "utf8"));
|
|
106996
107178
|
}
|
|
106997
107179
|
if (options.extraIgnore)
|
|
@@ -107001,7 +107183,7 @@ function createWatcher(options) {
|
|
|
107001
107183
|
const fsWatcher = watch(options.cwd, { recursive: true }, (_event, filename) => {
|
|
107002
107184
|
if (!filename)
|
|
107003
107185
|
return;
|
|
107004
|
-
const rel = filename.split(
|
|
107186
|
+
const rel = filename.split(sep3).join("/");
|
|
107005
107187
|
if (ig.ignores(rel))
|
|
107006
107188
|
return;
|
|
107007
107189
|
pending.add(rel);
|
|
@@ -107030,8 +107212,8 @@ var devInputSchema = exports_external.object({
|
|
|
107030
107212
|
app: exports_external.string().optional()
|
|
107031
107213
|
});
|
|
107032
107214
|
async function loadConfig2(ctx, appOverride) {
|
|
107033
|
-
const tomlPath =
|
|
107034
|
-
if (!
|
|
107215
|
+
const tomlPath = join11(ctx.cwd, "percher.toml");
|
|
107216
|
+
if (!existsSync8(tomlPath)) {
|
|
107035
107217
|
throw new PercherCoreError("No percher.toml found. Run: percher init", {
|
|
107036
107218
|
code: "dev.no-app",
|
|
107037
107219
|
hint: "Create a percher.toml first with `percher init`."
|
|
@@ -107185,12 +107367,12 @@ async function dev(ctx, input, callbacks) {
|
|
|
107185
107367
|
}
|
|
107186
107368
|
});
|
|
107187
107369
|
try {
|
|
107188
|
-
await new Promise((
|
|
107370
|
+
await new Promise((resolve7) => {
|
|
107189
107371
|
if (callbacks.signal.aborted) {
|
|
107190
|
-
|
|
107372
|
+
resolve7();
|
|
107191
107373
|
return;
|
|
107192
107374
|
}
|
|
107193
|
-
callbacks.signal.addEventListener("abort", () =>
|
|
107375
|
+
callbacks.signal.addEventListener("abort", () => resolve7(), { once: true });
|
|
107194
107376
|
});
|
|
107195
107377
|
} finally {
|
|
107196
107378
|
logStream.ctrl?.abort();
|
|
@@ -107225,8 +107407,8 @@ async function diff(ctx, input = {}) {
|
|
|
107225
107407
|
});
|
|
107226
107408
|
}
|
|
107227
107409
|
// ../core/dist/commands/doctor.js
|
|
107228
|
-
import { existsSync as
|
|
107229
|
-
import { join as
|
|
107410
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
107411
|
+
import { join as join13 } from "node:path";
|
|
107230
107412
|
|
|
107231
107413
|
// ../core/dist/error-classifier.js
|
|
107232
107414
|
function extractEnvVarsFromLog(combined) {
|
|
@@ -107771,7 +107953,7 @@ function recoveryFromErrorClass(errorClass, failure = {}) {
|
|
|
107771
107953
|
}
|
|
107772
107954
|
|
|
107773
107955
|
// ../core/dist/commands/publish-failure.js
|
|
107774
|
-
import { join as
|
|
107956
|
+
import { join as join12 } from "node:path";
|
|
107775
107957
|
|
|
107776
107958
|
// ../core/dist/structured-error-codes.js
|
|
107777
107959
|
var MAPPINGS = {
|
|
@@ -107849,7 +108031,7 @@ function trimMessage(raw) {
|
|
|
107849
108031
|
|
|
107850
108032
|
// ../core/dist/commands/publish-failure.js
|
|
107851
108033
|
function tomlPathFor(cwd) {
|
|
107852
|
-
return
|
|
108034
|
+
return join12(cwd, "percher.toml");
|
|
107853
108035
|
}
|
|
107854
108036
|
async function buildFailureError(ctx, app, deployment, signal) {
|
|
107855
108037
|
let buildLogTail;
|
|
@@ -108192,8 +108374,8 @@ async function doctor(ctx, input = {}) {
|
|
|
108192
108374
|
});
|
|
108193
108375
|
return summarize(checks3, { appProvided: !!input.app });
|
|
108194
108376
|
}
|
|
108195
|
-
const tomlPath =
|
|
108196
|
-
const tomlExists =
|
|
108377
|
+
const tomlPath = join13(ctx.cwd, "percher.toml");
|
|
108378
|
+
const tomlExists = existsSync9(tomlPath);
|
|
108197
108379
|
let tomlValid = false;
|
|
108198
108380
|
if (!tomlExists) {
|
|
108199
108381
|
checks3.push({
|
|
@@ -108973,7 +109155,7 @@ async function envList(ctx, input = {}) {
|
|
|
108973
109155
|
import { randomUUID } from "node:crypto";
|
|
108974
109156
|
import { createWriteStream } from "node:fs";
|
|
108975
109157
|
import { rename, unlink } from "node:fs/promises";
|
|
108976
|
-
import { isAbsolute, resolve as resolvePath } from "node:path";
|
|
109158
|
+
import { isAbsolute as isAbsolute2, resolve as resolvePath } from "node:path";
|
|
108977
109159
|
var exportInputSchema = exports_external.object({
|
|
108978
109160
|
app: exports_external.string().optional(),
|
|
108979
109161
|
out: exports_external.string().optional(),
|
|
@@ -108997,7 +109179,7 @@ async function streamToFile(outPath, source) {
|
|
|
108997
109179
|
const tmpPath = `${outPath}.part-${randomUUID()}`;
|
|
108998
109180
|
const out = createWriteStream(tmpPath);
|
|
108999
109181
|
const reader = source.getReader();
|
|
109000
|
-
const closed = new Promise((
|
|
109182
|
+
const closed = new Promise((resolve7) => out.once("close", () => resolve7()));
|
|
109001
109183
|
let onWriteError;
|
|
109002
109184
|
const writeFailed = new Promise((_, reject) => {
|
|
109003
109185
|
onWriteError = reject;
|
|
@@ -109014,14 +109196,14 @@ async function streamToFile(outPath, source) {
|
|
|
109014
109196
|
bytes += value.byteLength;
|
|
109015
109197
|
if (!out.write(value)) {
|
|
109016
109198
|
await Promise.race([
|
|
109017
|
-
new Promise((
|
|
109199
|
+
new Promise((resolve7) => out.once("drain", resolve7)),
|
|
109018
109200
|
writeFailed
|
|
109019
109201
|
]);
|
|
109020
109202
|
}
|
|
109021
109203
|
}
|
|
109022
109204
|
}
|
|
109023
|
-
await new Promise((
|
|
109024
|
-
out.end((err) => err ? reject(err) :
|
|
109205
|
+
await new Promise((resolve7, reject) => {
|
|
109206
|
+
out.end((err) => err ? reject(err) : resolve7());
|
|
109025
109207
|
});
|
|
109026
109208
|
await closed;
|
|
109027
109209
|
} catch (err) {
|
|
@@ -109039,7 +109221,7 @@ async function streamToFile(outPath, source) {
|
|
|
109039
109221
|
return { bytes };
|
|
109040
109222
|
}
|
|
109041
109223
|
function resolveOutPath(ctxCwd, filename) {
|
|
109042
|
-
if (
|
|
109224
|
+
if (isAbsolute2(filename))
|
|
109043
109225
|
return filename;
|
|
109044
109226
|
return resolvePath(ctxCwd, filename);
|
|
109045
109227
|
}
|
|
@@ -109100,8 +109282,8 @@ var forgejoSetupWebhookInputSchema = exports_external.object({
|
|
|
109100
109282
|
app: exports_external.string().optional().describe("App name (overrides percher.toml)")
|
|
109101
109283
|
});
|
|
109102
109284
|
// ../core/dist/commands/generate.js
|
|
109103
|
-
import { existsSync as
|
|
109104
|
-
import { join as
|
|
109285
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
109286
|
+
import { join as join14 } from "node:path";
|
|
109105
109287
|
var generateInputSchema = exports_external.object({
|
|
109106
109288
|
cwd: exports_external.string().optional()
|
|
109107
109289
|
});
|
|
@@ -109187,8 +109369,8 @@ function generateTypeScript(config2) {
|
|
|
109187
109369
|
}
|
|
109188
109370
|
async function generate(ctx, input = {}) {
|
|
109189
109371
|
const cwd = input.cwd ?? ctx.cwd;
|
|
109190
|
-
const tomlPath =
|
|
109191
|
-
if (!
|
|
109372
|
+
const tomlPath = join14(cwd, "percher.toml");
|
|
109373
|
+
if (!existsSync10(tomlPath)) {
|
|
109192
109374
|
throw new PercherCoreError("No percher.toml found", {
|
|
109193
109375
|
code: "dev.no-app",
|
|
109194
109376
|
hint: "Run percher init first."
|
|
@@ -109197,14 +109379,14 @@ async function generate(ctx, input = {}) {
|
|
|
109197
109379
|
const config2 = await parseFile(tomlPath);
|
|
109198
109380
|
const files = [];
|
|
109199
109381
|
const envExample = generateEnvExample(config2);
|
|
109200
|
-
|
|
109382
|
+
writeFileSync6(join14(cwd, ".env.example"), envExample);
|
|
109201
109383
|
files.push(".env.example");
|
|
109202
109384
|
const tsTypes = generateTypeScript(config2);
|
|
109203
|
-
|
|
109385
|
+
writeFileSync6(join14(cwd, "percher.generated.d.ts"), tsTypes);
|
|
109204
109386
|
files.push("percher.generated.d.ts");
|
|
109205
109387
|
const agentInstructions = generateAgentInstructions(config2);
|
|
109206
|
-
|
|
109207
|
-
|
|
109388
|
+
mkdirSync6(join14(cwd, ".percher"), { recursive: true });
|
|
109389
|
+
writeFileSync6(join14(cwd, ".percher", "agent-instructions.md"), agentInstructions);
|
|
109208
109390
|
files.push(".percher/agent-instructions.md");
|
|
109209
109391
|
return { files };
|
|
109210
109392
|
}
|
|
@@ -109353,8 +109535,8 @@ async function githubSetupWebhook(ctx, input) {
|
|
|
109353
109535
|
};
|
|
109354
109536
|
}
|
|
109355
109537
|
// ../core/dist/commands/import-project.js
|
|
109356
|
-
import { existsSync as
|
|
109357
|
-
import { join as
|
|
109538
|
+
import { existsSync as existsSync11, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "node:fs";
|
|
109539
|
+
import { join as join15 } from "node:path";
|
|
109358
109540
|
|
|
109359
109541
|
// ../core/dist/static-docker.js
|
|
109360
109542
|
var STATIC_DOCKER_PORT = 8080;
|
|
@@ -109382,7 +109564,8 @@ FROM caddy:2-alpine AS caddy-source
|
|
|
109382
109564
|
FROM alpine:3.21
|
|
109383
109565
|
COPY --from=caddy-source /usr/bin/caddy /usr/bin/caddy
|
|
109384
109566
|
RUN apk add --no-cache libcap \\
|
|
109385
|
-
&& setcap -r /usr/bin/caddy \\
|
|
109567
|
+
&& (setcap -r /usr/bin/caddy 2>/dev/null || true) \\
|
|
109568
|
+
&& test -z "$(getcap /usr/bin/caddy)" \\
|
|
109386
109569
|
&& apk del libcap \\
|
|
109387
109570
|
&& rm -rf /var/cache/apk/*
|
|
109388
109571
|
COPY Caddyfile /etc/caddy/Caddyfile
|
|
@@ -109415,9 +109598,9 @@ var importInputSchema = exports_external.object({
|
|
|
109415
109598
|
app: exports_external.string().optional().describe("App name to import into")
|
|
109416
109599
|
});
|
|
109417
109600
|
function detectProvider(cwd) {
|
|
109418
|
-
if (
|
|
109601
|
+
if (existsSync11(join15(cwd, "vercel.json")))
|
|
109419
109602
|
return "vercel";
|
|
109420
|
-
if (
|
|
109603
|
+
if (existsSync11(join15(cwd, "netlify.toml")))
|
|
109421
109604
|
return "netlify";
|
|
109422
109605
|
return null;
|
|
109423
109606
|
}
|
|
@@ -109435,7 +109618,7 @@ function mapVercelFramework(framework) {
|
|
|
109435
109618
|
return map2[framework ?? ""] ?? { runtime: "node" };
|
|
109436
109619
|
}
|
|
109437
109620
|
function parseVercelJson(cwd) {
|
|
109438
|
-
const raw = readFileSync8(
|
|
109621
|
+
const raw = readFileSync8(join15(cwd, "vercel.json"), "utf-8");
|
|
109439
109622
|
const config2 = JSON.parse(raw);
|
|
109440
109623
|
const warnings = [];
|
|
109441
109624
|
const envVars = [];
|
|
@@ -109489,12 +109672,12 @@ health = "/api/health"
|
|
|
109489
109672
|
return { toml, warnings, envVars, staticBuild };
|
|
109490
109673
|
}
|
|
109491
109674
|
function parseNetlifyToml(cwd) {
|
|
109492
|
-
const raw = readFileSync8(
|
|
109675
|
+
const raw = readFileSync8(join15(cwd, "netlify.toml"), "utf-8");
|
|
109493
109676
|
const warnings = [];
|
|
109494
109677
|
const envVars = [];
|
|
109495
109678
|
const buildCommand = raw.match(/command\s*=\s*"([^"]+)"/)?.[1] ?? "bun run build";
|
|
109496
109679
|
const publishDir = raw.match(/publish\s*=\s*"([^"]+)"/)?.[1] ?? "dist";
|
|
109497
|
-
const hasPackageJson =
|
|
109680
|
+
const hasPackageJson = existsSync11(join15(cwd, "package.json"));
|
|
109498
109681
|
const looksLikeStaticOutput = publishDir === "dist" || publishDir === "build" || publishDir === "public";
|
|
109499
109682
|
let toml = `[app]
|
|
109500
109683
|
name = "imported-app"
|
|
@@ -109565,11 +109748,11 @@ async function importProject(ctx, input = {}) {
|
|
|
109565
109748
|
hint: "Supported providers: vercel, netlify"
|
|
109566
109749
|
});
|
|
109567
109750
|
}
|
|
109568
|
-
const tomlPath =
|
|
109569
|
-
if (
|
|
109751
|
+
const tomlPath = join15(ctx.cwd, "percher.toml");
|
|
109752
|
+
if (existsSync11(tomlPath)) {
|
|
109570
109753
|
result.warnings.unshift("percher.toml already exists — overwriting with imported config");
|
|
109571
109754
|
}
|
|
109572
|
-
|
|
109755
|
+
writeFileSync7(tomlPath, result.toml);
|
|
109573
109756
|
const scaffoldedFiles = [];
|
|
109574
109757
|
if (result.staticBuild) {
|
|
109575
109758
|
const targets = [
|
|
@@ -109583,12 +109766,12 @@ async function importProject(ctx, input = {}) {
|
|
|
109583
109766
|
}
|
|
109584
109767
|
];
|
|
109585
109768
|
for (const { name, content } of targets) {
|
|
109586
|
-
const target =
|
|
109587
|
-
if (
|
|
109769
|
+
const target = join15(ctx.cwd, name);
|
|
109770
|
+
if (existsSync11(target)) {
|
|
109588
109771
|
result.warnings.push(`${name} already exists — left untouched. The imported config expects a multi-stage static build; merge by hand if needed.`);
|
|
109589
109772
|
continue;
|
|
109590
109773
|
}
|
|
109591
|
-
|
|
109774
|
+
writeFileSync7(target, content, "utf-8");
|
|
109592
109775
|
scaffoldedFiles.push(name);
|
|
109593
109776
|
}
|
|
109594
109777
|
}
|
|
@@ -109601,14 +109784,14 @@ async function importProject(ctx, input = {}) {
|
|
|
109601
109784
|
};
|
|
109602
109785
|
}
|
|
109603
109786
|
// ../core/dist/commands/init.js
|
|
109604
|
-
import { existsSync as
|
|
109605
|
-
import { basename as
|
|
109787
|
+
import { existsSync as existsSync13, writeFileSync as writeFileSync8 } from "node:fs";
|
|
109788
|
+
import { basename as basename3, join as join17 } from "node:path";
|
|
109606
109789
|
|
|
109607
109790
|
// ../core/dist/detect.js
|
|
109608
|
-
import { existsSync as
|
|
109609
|
-
import { join as
|
|
109791
|
+
import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
|
|
109792
|
+
import { join as join16 } from "node:path";
|
|
109610
109793
|
function exists(dir, ...names) {
|
|
109611
|
-
return names.some((n) =>
|
|
109794
|
+
return names.some((n) => existsSync12(join16(dir, n)));
|
|
109612
109795
|
}
|
|
109613
109796
|
function readJson(path) {
|
|
109614
109797
|
try {
|
|
@@ -109637,8 +109820,8 @@ function detectDataMode(pkg, cwd) {
|
|
|
109637
109820
|
return { mode: "none" };
|
|
109638
109821
|
}
|
|
109639
109822
|
async function detectFramework(cwd) {
|
|
109640
|
-
const pkgPath =
|
|
109641
|
-
const pkg =
|
|
109823
|
+
const pkgPath = join16(cwd, "package.json");
|
|
109824
|
+
const pkg = existsSync12(pkgPath) ? readJson(pkgPath) : null;
|
|
109642
109825
|
if (exists(cwd, "Dockerfile")) {
|
|
109643
109826
|
return {
|
|
109644
109827
|
runtime: "docker",
|
|
@@ -109740,7 +109923,7 @@ async function detectFramework(cwd) {
|
|
|
109740
109923
|
}
|
|
109741
109924
|
const hasPython = exists(cwd, "requirements.txt", "pyproject.toml");
|
|
109742
109925
|
if (hasPython) {
|
|
109743
|
-
if (
|
|
109926
|
+
if (existsSync12(join16(cwd, "manage.py"))) {
|
|
109744
109927
|
return {
|
|
109745
109928
|
runtime: "python",
|
|
109746
109929
|
framework: "django",
|
|
@@ -109748,7 +109931,7 @@ async function detectFramework(cwd) {
|
|
|
109748
109931
|
data: detectDataMode(pkg, cwd)
|
|
109749
109932
|
};
|
|
109750
109933
|
}
|
|
109751
|
-
const mainPy =
|
|
109934
|
+
const mainPy = existsSync12(join16(cwd, "main.py")) ? readFileSync9(join16(cwd, "main.py"), "utf8") : "";
|
|
109752
109935
|
if (/FastAPI\s*\(/.test(mainPy) || /from\s+fastapi/.test(mainPy)) {
|
|
109753
109936
|
return {
|
|
109754
109937
|
runtime: "python",
|
|
@@ -109757,7 +109940,7 @@ async function detectFramework(cwd) {
|
|
|
109757
109940
|
data: detectDataMode(pkg, cwd)
|
|
109758
109941
|
};
|
|
109759
109942
|
}
|
|
109760
|
-
const appPy =
|
|
109943
|
+
const appPy = existsSync12(join16(cwd, "app.py")) ? readFileSync9(join16(cwd, "app.py"), "utf8") : "";
|
|
109761
109944
|
if (/Flask\s*\(/.test(appPy) || /from\s+flask/.test(appPy)) {
|
|
109762
109945
|
return {
|
|
109763
109946
|
runtime: "python",
|
|
@@ -109772,7 +109955,7 @@ async function detectFramework(cwd) {
|
|
|
109772
109955
|
data: detectDataMode(pkg, cwd)
|
|
109773
109956
|
};
|
|
109774
109957
|
}
|
|
109775
|
-
if (
|
|
109958
|
+
if (existsSync12(join16(cwd, "index.html"))) {
|
|
109776
109959
|
return { runtime: "static" };
|
|
109777
109960
|
}
|
|
109778
109961
|
return null;
|
|
@@ -109822,8 +110005,8 @@ function scanEnvVars(_cwd) {
|
|
|
109822
110005
|
return {};
|
|
109823
110006
|
}
|
|
109824
110007
|
async function init(ctx, input = {}) {
|
|
109825
|
-
const path =
|
|
109826
|
-
const exists2 =
|
|
110008
|
+
const path = join17(ctx.cwd, "percher.toml");
|
|
110009
|
+
const exists2 = existsSync13(path);
|
|
109827
110010
|
if (exists2 && !input.force) {
|
|
109828
110011
|
throw new PercherCoreError("percher.toml already exists", {
|
|
109829
110012
|
code: "init.exists",
|
|
@@ -109836,7 +110019,7 @@ async function init(ctx, input = {}) {
|
|
|
109836
110019
|
if (input.name) {
|
|
109837
110020
|
name = input.name;
|
|
109838
110021
|
} else {
|
|
109839
|
-
const suggestion = generateName(
|
|
110022
|
+
const suggestion = generateName(basename3(ctx.cwd));
|
|
109840
110023
|
const interactive = input.interactive ?? detectInteractive();
|
|
109841
110024
|
if (isSuspiciousAutoName(suggestion) && interactive) {
|
|
109842
110025
|
const answer = (await ctx.prompt(`Suggested app name: '${suggestion}'. Press Enter to accept, or type a different name: `, { default: suggestion })).trim();
|
|
@@ -109870,7 +110053,7 @@ async function init(ctx, input = {}) {
|
|
|
109870
110053
|
if (Object.keys(envVars).length > 0) {
|
|
109871
110054
|
config2.env = envVars;
|
|
109872
110055
|
}
|
|
109873
|
-
|
|
110056
|
+
writeFileSync8(path, serialize(config2), "utf8");
|
|
109874
110057
|
const scaffoldedFiles = [];
|
|
109875
110058
|
if (detected?.staticBuild) {
|
|
109876
110059
|
const targets = [
|
|
@@ -109886,10 +110069,10 @@ async function init(ctx, input = {}) {
|
|
|
109886
110069
|
}
|
|
109887
110070
|
];
|
|
109888
110071
|
for (const { name: name2, content } of targets) {
|
|
109889
|
-
const target =
|
|
109890
|
-
if (
|
|
110072
|
+
const target = join17(ctx.cwd, name2);
|
|
110073
|
+
if (existsSync13(target) && !input.force)
|
|
109891
110074
|
continue;
|
|
109892
|
-
|
|
110075
|
+
writeFileSync8(target, content, "utf8");
|
|
109893
110076
|
scaffoldedFiles.push(name2);
|
|
109894
110077
|
}
|
|
109895
110078
|
}
|
|
@@ -109973,7 +110156,7 @@ async function login(ctx, input = {}) {
|
|
|
109973
110156
|
return validateAndPersist(ctx, input.apiUrl, result.token);
|
|
109974
110157
|
}
|
|
109975
110158
|
if (code.interval > 0) {
|
|
109976
|
-
await new Promise((
|
|
110159
|
+
await new Promise((resolve7) => setTimeout(resolve7, code.interval * 1000));
|
|
109977
110160
|
}
|
|
109978
110161
|
}
|
|
109979
110162
|
throw new PercherCoreError("Login timed out. Re-run `percher login`.", {
|
|
@@ -110890,7 +111073,7 @@ function collectWarnings2(collections, rlsPolicies, unsupported) {
|
|
|
110890
111073
|
}
|
|
110891
111074
|
// ../core/dist/commands/migrate-supabase-rewrite.js
|
|
110892
111075
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
110893
|
-
import { dirname as
|
|
111076
|
+
import { dirname as dirname6, join as join20, relative as relative6, resolve as resolve9, sep as sep5 } from "node:path";
|
|
110894
111077
|
|
|
110895
111078
|
// ../core/dist/commands/migrate-supabase-recipes.js
|
|
110896
111079
|
var AUTH_RECIPES = {
|
|
@@ -111156,7 +111339,7 @@ function isSupabaseClientModule(source) {
|
|
|
111156
111339
|
// ../core/dist/commands/migrate-supabase-status.js
|
|
111157
111340
|
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
111158
111341
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
111159
|
-
import { join as
|
|
111342
|
+
import { join as join19, relative as relative5, resolve as resolve8 } from "node:path";
|
|
111160
111343
|
|
|
111161
111344
|
// ../core/dist/commands/migrate-supabase-sdk.js
|
|
111162
111345
|
var import_jscodeshift2 = __toESM(require_core3(), 1);
|
|
@@ -112093,7 +112276,7 @@ function applyRewrite(path, replacement, kind, pattern, note, flags, state) {
|
|
|
112093
112276
|
// ../core/dist/commands/migrate-supabase-walker.js
|
|
112094
112277
|
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
112095
112278
|
import { mkdir as mkdir2, readdir, readFile as readFile3, stat, writeFile as writeFile2 } from "node:fs/promises";
|
|
112096
|
-
import { dirname as
|
|
112279
|
+
import { dirname as dirname5, isAbsolute as isAbsolute3, join as join18, relative as relative4, resolve as resolve7, sep as sep4 } from "node:path";
|
|
112097
112280
|
var REWRITABLE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
112098
112281
|
var DEFAULT_EXCLUDES = [
|
|
112099
112282
|
"node_modules",
|
|
@@ -112114,7 +112297,7 @@ var DEFAULT_EXCLUDES = [
|
|
|
112114
112297
|
"pb_migrations"
|
|
112115
112298
|
];
|
|
112116
112299
|
async function walkSupabaseProject(input) {
|
|
112117
|
-
const rootAbs =
|
|
112300
|
+
const rootAbs = resolve7(input.rootDir);
|
|
112118
112301
|
const ig = import_ignore3.default().add(DEFAULT_EXCLUDES);
|
|
112119
112302
|
if (input.extraExcludes && input.extraExcludes.length > 0) {
|
|
112120
112303
|
ig.add(input.extraExcludes);
|
|
@@ -112123,7 +112306,7 @@ async function walkSupabaseProject(input) {
|
|
|
112123
112306
|
const skipped = [];
|
|
112124
112307
|
const pendingConfig = [];
|
|
112125
112308
|
for await (const absPath of walkTree(rootAbs, rootAbs, ig)) {
|
|
112126
|
-
const rel =
|
|
112309
|
+
const rel = relative4(rootAbs, absPath).split(sep4).join("/");
|
|
112127
112310
|
const kind = classifyFile2(rel);
|
|
112128
112311
|
if (kind === null)
|
|
112129
112312
|
continue;
|
|
@@ -112245,8 +112428,8 @@ async function* walkTree(dir, rootAbs, ig) {
|
|
|
112245
112428
|
return;
|
|
112246
112429
|
}
|
|
112247
112430
|
for (const name of entries) {
|
|
112248
|
-
const abs =
|
|
112249
|
-
const rel =
|
|
112431
|
+
const abs = join18(dir, name);
|
|
112432
|
+
const rel = relative4(rootAbs, abs).split(sep4).join("/");
|
|
112250
112433
|
if (rel.length > 0 && ig.ignores(rel))
|
|
112251
112434
|
continue;
|
|
112252
112435
|
let st;
|
|
@@ -112395,19 +112578,19 @@ function extractPublicPrefix(key) {
|
|
|
112395
112578
|
return "";
|
|
112396
112579
|
}
|
|
112397
112580
|
async function writeWalkResult(input) {
|
|
112398
|
-
const targetAbs =
|
|
112581
|
+
const targetAbs = resolve7(input.targetDir);
|
|
112399
112582
|
const changedOnly = input.changedOnly !== false;
|
|
112400
112583
|
const written = [];
|
|
112401
112584
|
for (const file2 of input.result.files) {
|
|
112402
112585
|
if (changedOnly && !file2.changed)
|
|
112403
112586
|
continue;
|
|
112404
|
-
const abs =
|
|
112405
|
-
const rel =
|
|
112406
|
-
const isParentTraversal = rel === ".." || rel.startsWith(`..${
|
|
112407
|
-
if (rel.length === 0 || isParentTraversal ||
|
|
112587
|
+
const abs = resolve7(targetAbs, file2.relativePath);
|
|
112588
|
+
const rel = relative4(targetAbs, abs);
|
|
112589
|
+
const isParentTraversal = rel === ".." || rel.startsWith(`..${sep4}`) || rel.startsWith("../");
|
|
112590
|
+
if (rel.length === 0 || isParentTraversal || isAbsolute3(rel)) {
|
|
112408
112591
|
throw new Error(`writeWalkResult refused path-traversing file "${file2.relativePath}" → "${abs}" (would escape targetDir "${targetAbs}").`);
|
|
112409
112592
|
}
|
|
112410
|
-
await mkdir2(
|
|
112593
|
+
await mkdir2(dirname5(abs), { recursive: true });
|
|
112411
112594
|
await writeFile2(abs, file2.rewritten, "utf8");
|
|
112412
112595
|
written.push(file2.relativePath);
|
|
112413
112596
|
}
|
|
@@ -112620,8 +112803,8 @@ var STATE_SUMMARY = {
|
|
|
112620
112803
|
complete: "Migration looks complete — no Supabase usage remains."
|
|
112621
112804
|
};
|
|
112622
112805
|
async function migrationStatus(ctx, input) {
|
|
112623
|
-
const rootAbs = input.rootDir ?
|
|
112624
|
-
ctx.status(`Scanning ${
|
|
112806
|
+
const rootAbs = input.rootDir ? resolve8(ctx.cwd, input.rootDir) : resolve8(ctx.cwd);
|
|
112807
|
+
ctx.status(`Scanning ${relative5(ctx.cwd, rootAbs) || "."} for migration status...`);
|
|
112625
112808
|
let files;
|
|
112626
112809
|
try {
|
|
112627
112810
|
const walk2 = await walkSupabaseProject({ rootDir: rootAbs });
|
|
@@ -112682,7 +112865,7 @@ function buildPrompt(state, failing, warning, build) {
|
|
|
112682
112865
|
async function readManualRlsCount(rootAbs) {
|
|
112683
112866
|
for (const dir of ["migration-preview", "."]) {
|
|
112684
112867
|
try {
|
|
112685
|
-
const notes = await readFile4(
|
|
112868
|
+
const notes = await readFile4(join19(rootAbs, dir, "MIGRATION_NOTES.md"), "utf8");
|
|
112686
112869
|
const m = notes.match(/\*\*RLS policies:\*\*\s*\d+\s*\((\d+)\s*need manual review\)/);
|
|
112687
112870
|
if (m?.[1] !== undefined)
|
|
112688
112871
|
return Number.parseInt(m[1], 10);
|
|
@@ -112694,7 +112877,7 @@ async function readManualRlsCount(rootAbs) {
|
|
|
112694
112877
|
async function runProjectBuild(rootAbs) {
|
|
112695
112878
|
let hasBuildScript = false;
|
|
112696
112879
|
try {
|
|
112697
|
-
const pkg = JSON.parse(await readFile4(
|
|
112880
|
+
const pkg = JSON.parse(await readFile4(join19(rootAbs, "package.json"), "utf8"));
|
|
112698
112881
|
hasBuildScript = typeof pkg.scripts?.build === "string";
|
|
112699
112882
|
} catch {
|
|
112700
112883
|
return { ran: false, passed: false, detail: "No readable package.json — nothing to build." };
|
|
@@ -112726,7 +112909,7 @@ ${tail}` : ""}`
|
|
|
112726
112909
|
async function detectPackageManager(rootAbs) {
|
|
112727
112910
|
const has = async (name) => {
|
|
112728
112911
|
try {
|
|
112729
|
-
await readFile4(
|
|
112912
|
+
await readFile4(join19(rootAbs, name), "utf8");
|
|
112730
112913
|
return true;
|
|
112731
112914
|
} catch {
|
|
112732
112915
|
return false;
|
|
@@ -112741,7 +112924,7 @@ async function detectPackageManager(rootAbs) {
|
|
|
112741
112924
|
return "npm";
|
|
112742
112925
|
}
|
|
112743
112926
|
function spawnCapture(cmd, args, cwd, timeoutMs) {
|
|
112744
|
-
return new Promise((
|
|
112927
|
+
return new Promise((resolve9) => {
|
|
112745
112928
|
const child = import_cross_spawn.default(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
112746
112929
|
let output = "";
|
|
112747
112930
|
const onData = (chunk) => {
|
|
@@ -112758,11 +112941,11 @@ function spawnCapture(cmd, args, cwd, timeoutMs) {
|
|
|
112758
112941
|
}, timeoutMs);
|
|
112759
112942
|
child.on("error", (err) => {
|
|
112760
112943
|
clearTimeout(timer);
|
|
112761
|
-
|
|
112944
|
+
resolve9({ code: 1, output, timedOut, spawnError: err.message });
|
|
112762
112945
|
});
|
|
112763
112946
|
child.on("close", (code) => {
|
|
112764
112947
|
clearTimeout(timer);
|
|
112765
|
-
|
|
112948
|
+
resolve9({ code: code ?? 1, output, timedOut });
|
|
112766
112949
|
});
|
|
112767
112950
|
});
|
|
112768
112951
|
}
|
|
@@ -112805,10 +112988,10 @@ var rewriteSupabaseClientInputSchema = exports_external.object({
|
|
|
112805
112988
|
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.")
|
|
112806
112989
|
});
|
|
112807
112990
|
async function rewriteSupabaseClient(ctx, input) {
|
|
112808
|
-
const rootAbs = input.rootDir ?
|
|
112991
|
+
const rootAbs = input.rootDir ? resolve9(ctx.cwd, input.rootDir) : resolve9(ctx.cwd);
|
|
112809
112992
|
const apply = input.apply === true;
|
|
112810
112993
|
const mode = apply ? "apply" : "preview";
|
|
112811
|
-
ctx.status(`Scanning ${
|
|
112994
|
+
ctx.status(`Scanning ${relative6(ctx.cwd, rootAbs) || "."} for Supabase SDK calls...`);
|
|
112812
112995
|
let walk2;
|
|
112813
112996
|
try {
|
|
112814
112997
|
walk2 = await walkSupabaseProject({
|
|
@@ -112817,7 +113000,7 @@ async function rewriteSupabaseClient(ctx, input) {
|
|
|
112817
113000
|
supabaseIdentifiers: input.supabaseIdentifiers
|
|
112818
113001
|
});
|
|
112819
113002
|
} catch (err) {
|
|
112820
|
-
return failure3(rootAbs, mode, err, `Couldn't scan ${
|
|
113003
|
+
return failure3(rootAbs, mode, err, `Couldn't scan ${relative6(ctx.cwd, rootAbs) || "."}: check the path exists and is readable, then re-run.`);
|
|
112821
113004
|
}
|
|
112822
113005
|
const changed = walk2.files.filter((f) => f.changed);
|
|
112823
113006
|
const flags = collectManualFlags(walk2);
|
|
@@ -112856,8 +113039,8 @@ async function rewriteSupabaseClient(ctx, input) {
|
|
|
112856
113039
|
flags.push(...scaffold.flags);
|
|
112857
113040
|
}
|
|
112858
113041
|
const reportNeeded = hadRewrites || flags.length > 0 || walk2.skipped.length > 0;
|
|
112859
|
-
const backupDir = apply && changed.length > 0 ?
|
|
112860
|
-
const rewriteTarget = apply ? rootAbs : input.outputDir ?
|
|
113042
|
+
const backupDir = apply && changed.length > 0 ? join20(rootAbs, "migration-preview", "backup") : null;
|
|
113043
|
+
const rewriteTarget = apply ? rootAbs : input.outputDir ? resolve9(ctx.cwd, input.outputDir) : join20(rootAbs, "migration-preview", "rewritten");
|
|
112861
113044
|
const filesWritten = [];
|
|
112862
113045
|
let clientModuleWritten = null;
|
|
112863
113046
|
try {
|
|
@@ -112877,19 +113060,19 @@ async function rewriteSupabaseClient(ctx, input) {
|
|
|
112877
113060
|
changedOnly: true
|
|
112878
113061
|
});
|
|
112879
113062
|
for (const rel of out.written) {
|
|
112880
|
-
filesWritten.push(
|
|
113063
|
+
filesWritten.push(relative6(ctx.cwd, join20(rewriteTarget, rel)));
|
|
112881
113064
|
}
|
|
112882
113065
|
if (scaffold?.clientModule) {
|
|
112883
|
-
const moduleAbs =
|
|
112884
|
-
await mkdir3(
|
|
113066
|
+
const moduleAbs = join20(rewriteTarget, scaffold.clientModule.relativePath);
|
|
113067
|
+
await mkdir3(dirname6(moduleAbs), { recursive: true });
|
|
112885
113068
|
await writeFile3(moduleAbs, scaffold.clientModule.content, "utf8");
|
|
112886
|
-
clientModuleWritten =
|
|
113069
|
+
clientModuleWritten = relative6(ctx.cwd, moduleAbs).split(sep5).join("/");
|
|
112887
113070
|
filesWritten.push(clientModuleWritten);
|
|
112888
113071
|
}
|
|
112889
113072
|
}
|
|
112890
113073
|
if (reportNeeded) {
|
|
112891
|
-
const reportAbs =
|
|
112892
|
-
await mkdir3(
|
|
113074
|
+
const reportAbs = join20(rootAbs, "migration-preview", "REWRITE_NOTES.md");
|
|
113075
|
+
await mkdir3(dirname6(reportAbs), { recursive: true });
|
|
112893
113076
|
const analysis = analyzeMigration(walk2.files.map((f) => ({
|
|
112894
113077
|
relativePath: f.relativePath,
|
|
112895
113078
|
kind: f.kind,
|
|
@@ -112905,7 +113088,7 @@ async function rewriteSupabaseClient(ctx, input) {
|
|
|
112905
113088
|
scaffoldedClient: scaffold?.clientModule?.relativePath ?? null,
|
|
112906
113089
|
scaffoldSkippedExisting: scaffold?.skippedReason === "pb_client_exists"
|
|
112907
113090
|
}), "utf8");
|
|
112908
|
-
filesWritten.push(
|
|
113091
|
+
filesWritten.push(relative6(ctx.cwd, reportAbs));
|
|
112909
113092
|
}
|
|
112910
113093
|
} catch (err) {
|
|
112911
113094
|
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.");
|
|
@@ -113141,7 +113324,7 @@ function failure3(rootAbs, mode, err, suggestion) {
|
|
|
113141
113324
|
}
|
|
113142
113325
|
// ../core/dist/commands/migrate-supabase-schema.js
|
|
113143
113326
|
import { mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
|
|
113144
|
-
import { isAbsolute as
|
|
113327
|
+
import { isAbsolute as isAbsolute4, join as join21, relative as relative7, resolve as resolve10 } from "node:path";
|
|
113145
113328
|
|
|
113146
113329
|
// ../core/dist/commands/migrate-supabase-scripts.js
|
|
113147
113330
|
function generateDataImportScripts(preview) {
|
|
@@ -113589,7 +113772,7 @@ var migrateSupabaseSchemaInputSchema = exports_external.object({
|
|
|
113589
113772
|
});
|
|
113590
113773
|
async function migrateSupabaseSchema(ctx, input) {
|
|
113591
113774
|
const outputDirAbs = resolveOutputDir(ctx.cwd, input.outputDir);
|
|
113592
|
-
const outputDirRel =
|
|
113775
|
+
const outputDirRel = relative7(ctx.cwd, outputDirAbs) || ".";
|
|
113593
113776
|
ctx.status(`Inspecting Supabase project ${input.projectRef}...`);
|
|
113594
113777
|
const inspection = await inspectSupabase(ctx, {
|
|
113595
113778
|
projectRef: input.projectRef,
|
|
@@ -113653,28 +113836,28 @@ async function migrateSupabaseSchema(ctx, input) {
|
|
|
113653
113836
|
}
|
|
113654
113837
|
function resolveOutputDir(cwd, requested) {
|
|
113655
113838
|
const raw = requested ?? "./migration-preview";
|
|
113656
|
-
return
|
|
113839
|
+
return isAbsolute4(raw) ? raw : resolve10(cwd, raw);
|
|
113657
113840
|
}
|
|
113658
113841
|
async function writePreviewFiles(ctx, outputDir, preview) {
|
|
113659
113842
|
await mkdir4(outputDir, { recursive: true });
|
|
113660
113843
|
const schemaJson = renderSchemaJson(preview);
|
|
113661
113844
|
const notesMd = renderMigrationNotes(preview);
|
|
113662
113845
|
const scripts = generateDataImportScripts(preview);
|
|
113663
|
-
const schemaPath =
|
|
113664
|
-
const notesPath =
|
|
113665
|
-
const migratePath =
|
|
113666
|
-
const storagePath =
|
|
113846
|
+
const schemaPath = join21(outputDir, "pb_schema.json");
|
|
113847
|
+
const notesPath = join21(outputDir, "MIGRATION_NOTES.md");
|
|
113848
|
+
const migratePath = join21(outputDir, "pb_migrate.js");
|
|
113849
|
+
const storagePath = join21(outputDir, "pb_migrate_storage.js");
|
|
113667
113850
|
await writeFile4(schemaPath, schemaJson, "utf8");
|
|
113668
113851
|
await writeFile4(notesPath, notesMd, "utf8");
|
|
113669
113852
|
await writeFile4(migratePath, scripts.pbMigrate, "utf8");
|
|
113670
113853
|
const written = [
|
|
113671
|
-
|
|
113672
|
-
|
|
113673
|
-
|
|
113854
|
+
relative7(ctx.cwd, schemaPath),
|
|
113855
|
+
relative7(ctx.cwd, notesPath),
|
|
113856
|
+
relative7(ctx.cwd, migratePath)
|
|
113674
113857
|
];
|
|
113675
113858
|
if (scripts.pbMigrateStorage !== null) {
|
|
113676
113859
|
await writeFile4(storagePath, scripts.pbMigrateStorage, "utf8");
|
|
113677
|
-
written.push(
|
|
113860
|
+
written.push(relative7(ctx.cwd, storagePath));
|
|
113678
113861
|
}
|
|
113679
113862
|
return written;
|
|
113680
113863
|
}
|
|
@@ -113889,8 +114072,8 @@ async function previewBranchShow(ctx, input = {}) {
|
|
|
113889
114072
|
};
|
|
113890
114073
|
}
|
|
113891
114074
|
// ../core/dist/commands/publish.js
|
|
113892
|
-
import { existsSync as
|
|
113893
|
-
import { join as
|
|
114075
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
114076
|
+
import { join as join24 } from "node:path";
|
|
113894
114077
|
|
|
113895
114078
|
// ../shared/dist/pow.js
|
|
113896
114079
|
import { createHash as createHash3 } from "node:crypto";
|
|
@@ -114265,9 +114448,20 @@ async function runDeployWithRetry(opts) {
|
|
|
114265
114448
|
throw lastErr;
|
|
114266
114449
|
}
|
|
114267
114450
|
|
|
114451
|
+
// ../core/dist/toml-recovery.js
|
|
114452
|
+
function tomlErrorToRecoveryProblems(err) {
|
|
114453
|
+
if (err.issues?.length) {
|
|
114454
|
+
return err.issues.map((i) => ({
|
|
114455
|
+
file: "percher.toml",
|
|
114456
|
+
message: `${i.path.join(".") || "(root)"}: ${i.message}`
|
|
114457
|
+
}));
|
|
114458
|
+
}
|
|
114459
|
+
return [{ file: "percher.toml", message: err.message }];
|
|
114460
|
+
}
|
|
114461
|
+
|
|
114268
114462
|
// ../core/dist/commands/env-scan.js
|
|
114269
114463
|
import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
|
|
114270
|
-
import { join as
|
|
114464
|
+
import { join as join22 } from "node:path";
|
|
114271
114465
|
var SOURCE_EXTS = new Set([
|
|
114272
114466
|
".ts",
|
|
114273
114467
|
".tsx",
|
|
@@ -114304,7 +114498,7 @@ function scanForMissingBuildEnvRefs(cwd, existingKeys) {
|
|
|
114304
114498
|
continue;
|
|
114305
114499
|
let content;
|
|
114306
114500
|
try {
|
|
114307
|
-
content = readFileSync10(
|
|
114501
|
+
content = readFileSync10(join22(cwd, rel), "utf8");
|
|
114308
114502
|
} catch {
|
|
114309
114503
|
continue;
|
|
114310
114504
|
}
|
|
@@ -114336,7 +114530,7 @@ function* walkDir(dir, base) {
|
|
|
114336
114530
|
for (const name of entries) {
|
|
114337
114531
|
if (SKIP_DIRS.has(name))
|
|
114338
114532
|
continue;
|
|
114339
|
-
const full =
|
|
114533
|
+
const full = join22(dir, name);
|
|
114340
114534
|
let st;
|
|
114341
114535
|
try {
|
|
114342
114536
|
st = statSync3(full);
|
|
@@ -114696,19 +114890,19 @@ function titleFromCode(code) {
|
|
|
114696
114890
|
}
|
|
114697
114891
|
|
|
114698
114892
|
// ../core/dist/commands/publish-node.js
|
|
114699
|
-
import { existsSync as
|
|
114700
|
-
import { join as
|
|
114893
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11 } from "node:fs";
|
|
114894
|
+
import { join as join23 } from "node:path";
|
|
114701
114895
|
function resolveNodeVersion(cwd) {
|
|
114702
|
-
const nvmrc =
|
|
114703
|
-
if (
|
|
114896
|
+
const nvmrc = join23(cwd, ".nvmrc");
|
|
114897
|
+
if (existsSync14(nvmrc)) {
|
|
114704
114898
|
try {
|
|
114705
114899
|
const v = readFileSync11(nvmrc, "utf8").trim();
|
|
114706
114900
|
if (v)
|
|
114707
114901
|
return { value: v, source: ".nvmrc" };
|
|
114708
114902
|
} catch {}
|
|
114709
114903
|
}
|
|
114710
|
-
const pkgPath =
|
|
114711
|
-
if (!
|
|
114904
|
+
const pkgPath = join23(cwd, "package.json");
|
|
114905
|
+
if (!existsSync14(pkgPath))
|
|
114712
114906
|
return null;
|
|
114713
114907
|
try {
|
|
114714
114908
|
const pkg = JSON.parse(readFileSync11(pkgPath, "utf8"));
|
|
@@ -114733,7 +114927,7 @@ var publishInputSchema = exports_external.object({
|
|
|
114733
114927
|
var SUSPICIOUS_BYTES = 50 * 1024 * 1024;
|
|
114734
114928
|
var SUSPICIOUS_FILES = 1e4;
|
|
114735
114929
|
function tomlPathFor2(cwd) {
|
|
114736
|
-
return
|
|
114930
|
+
return join24(cwd, "percher.toml");
|
|
114737
114931
|
}
|
|
114738
114932
|
async function buildReplacedResult2(opts) {
|
|
114739
114933
|
const { ctx, app, deployment, tarball, cwd } = opts;
|
|
@@ -114780,9 +114974,9 @@ function buildLiveSummary(opts) {
|
|
|
114780
114974
|
const replaced = opts.replacedPreview ? " — replaced previous preview" : "";
|
|
114781
114975
|
return `${opts.appName} ${verb}${fwSuffix} → ${opts.url}${replaced}`;
|
|
114782
114976
|
}
|
|
114783
|
-
async function publish(ctx, input = {}) {
|
|
114977
|
+
async function publish(ctx, input = {}, preParsedConfig) {
|
|
114784
114978
|
try {
|
|
114785
|
-
return await publishInner(ctx, input);
|
|
114979
|
+
return await publishInner(ctx, input, preParsedConfig);
|
|
114786
114980
|
} catch (err) {
|
|
114787
114981
|
const classified = classifyPublishApiError(err, {
|
|
114788
114982
|
configPath: tomlPathFor2(ctx.cwd),
|
|
@@ -114811,7 +115005,7 @@ async function publish(ctx, input = {}) {
|
|
|
114811
115005
|
};
|
|
114812
115006
|
}
|
|
114813
115007
|
}
|
|
114814
|
-
async function publishInner(ctx, input) {
|
|
115008
|
+
async function publishInner(ctx, input, preParsedConfig) {
|
|
114815
115009
|
const t0 = Date.now();
|
|
114816
115010
|
if (!input.dryRun) {
|
|
114817
115011
|
try {
|
|
@@ -114822,7 +115016,7 @@ async function publishInner(ctx, input) {
|
|
|
114822
115016
|
ctx.status("[1/4] Reading config...");
|
|
114823
115017
|
let config2;
|
|
114824
115018
|
try {
|
|
114825
|
-
config2 = await loadOrGenerate(ctx);
|
|
115019
|
+
config2 = await loadOrGenerate(ctx, preParsedConfig);
|
|
114826
115020
|
} catch (err) {
|
|
114827
115021
|
if (err instanceof PercherTomlError) {
|
|
114828
115022
|
if (err.code === "PARSE_ERROR") {
|
|
@@ -114836,7 +115030,7 @@ async function publishInner(ctx, input) {
|
|
|
114836
115030
|
suggestion: "Fix the syntax error and retry publish."
|
|
114837
115031
|
},
|
|
114838
115032
|
recovery: recoveryFixConfig({
|
|
114839
|
-
problems:
|
|
115033
|
+
problems: tomlErrorToRecoveryProblems(err),
|
|
114840
115034
|
reasonCode: "config_invalid"
|
|
114841
115035
|
}),
|
|
114842
115036
|
summary: "percher.toml has invalid TOML syntax — fix and retry.",
|
|
@@ -114845,10 +115039,7 @@ async function publishInner(ctx, input) {
|
|
|
114845
115039
|
};
|
|
114846
115040
|
}
|
|
114847
115041
|
if (err.code === "VALIDATION_ERROR") {
|
|
114848
|
-
const problems = (err
|
|
114849
|
-
file: "percher.toml",
|
|
114850
|
-
message: `${i.path.join(".") || "(root)"}: ${i.message}`
|
|
114851
|
-
}));
|
|
115042
|
+
const problems = tomlErrorToRecoveryProblems(err);
|
|
114852
115043
|
const bullets = problems.map((p) => ` - ${p.message}`).join(`
|
|
114853
115044
|
`);
|
|
114854
115045
|
const count = problems.length;
|
|
@@ -114892,6 +115083,30 @@ ${bullets}`,
|
|
|
114892
115083
|
bundle: { fileCount: 0, bytes: 0 }
|
|
114893
115084
|
};
|
|
114894
115085
|
}
|
|
115086
|
+
if (preParsedConfig && !input.dryRun && !existsSync15(join24(ctx.cwd, "percher.toml"))) {
|
|
115087
|
+
return {
|
|
115088
|
+
status: "failed",
|
|
115089
|
+
fileCount: 0,
|
|
115090
|
+
bytes: 0,
|
|
115091
|
+
error: {
|
|
115092
|
+
title: "percher.toml missing from the project",
|
|
115093
|
+
explanation: "A pre-parsed config was supplied, but no percher.toml exists in the project directory. The file is packaged into the upload, so it must be present on disk for a real deploy.",
|
|
115094
|
+
suggestion: "Run `percher init` (or write percher.toml) before publishing."
|
|
115095
|
+
},
|
|
115096
|
+
recovery: recoveryFixConfig({
|
|
115097
|
+
problems: [
|
|
115098
|
+
{
|
|
115099
|
+
file: "percher.toml",
|
|
115100
|
+
message: "percher.toml must exist on disk for a real upload (it ships in the tarball)."
|
|
115101
|
+
}
|
|
115102
|
+
],
|
|
115103
|
+
reasonCode: "config_missing"
|
|
115104
|
+
}),
|
|
115105
|
+
summary: "percher.toml missing — required on disk for a real upload.",
|
|
115106
|
+
configPath: tomlPathFor2(ctx.cwd),
|
|
115107
|
+
bundle: { fileCount: 0, bytes: 0 }
|
|
115108
|
+
};
|
|
115109
|
+
}
|
|
114895
115110
|
ctx.status("[2/4] Packaging files...");
|
|
114896
115111
|
const tarball = await createTarball({ cwd: ctx.cwd, config: config2 });
|
|
114897
115112
|
const packageMs = Date.now() - t0;
|
|
@@ -115397,11 +115612,14 @@ async function handleAnonymousPublish(ctx, config2, input, tarball) {
|
|
|
115397
115612
|
]
|
|
115398
115613
|
};
|
|
115399
115614
|
}
|
|
115400
|
-
async function loadOrGenerate(ctx) {
|
|
115401
|
-
|
|
115402
|
-
|
|
115615
|
+
async function loadOrGenerate(ctx, preParsed) {
|
|
115616
|
+
if (preParsed)
|
|
115617
|
+
return structuredClone(preParsed);
|
|
115618
|
+
const tomlPath = join24(ctx.cwd, "percher.toml");
|
|
115619
|
+
if (!existsSync15(tomlPath)) {
|
|
115403
115620
|
ctx.status("No percher.toml found — detecting framework...");
|
|
115404
|
-
await init(ctx);
|
|
115621
|
+
const generated = await init(ctx);
|
|
115622
|
+
return validate(generated.config);
|
|
115405
115623
|
}
|
|
115406
115624
|
return parseFile(tomlPath);
|
|
115407
115625
|
}
|
|
@@ -115448,8 +115666,8 @@ function emitPreflight(ctx, config2, tarball) {
|
|
|
115448
115666
|
}
|
|
115449
115667
|
}
|
|
115450
115668
|
// ../core/dist/commands/push.js
|
|
115451
|
-
import { existsSync as
|
|
115452
|
-
import { join as
|
|
115669
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
115670
|
+
import { join as join25 } from "node:path";
|
|
115453
115671
|
var pushInputSchema = exports_external.object({
|
|
115454
115672
|
dryRun: exports_external.boolean().optional(),
|
|
115455
115673
|
force: exports_external.boolean().optional(),
|
|
@@ -115460,8 +115678,8 @@ var SUSPICIOUS_BYTES2 = 50 * 1024 * 1024;
|
|
|
115460
115678
|
var SUSPICIOUS_FILES2 = 1e4;
|
|
115461
115679
|
var PLACEHOLDER_PREFIXES = ["add-your-", "your-key-here"];
|
|
115462
115680
|
async function loadOrGenerate2(ctx) {
|
|
115463
|
-
const tomlPath =
|
|
115464
|
-
if (!
|
|
115681
|
+
const tomlPath = join25(ctx.cwd, "percher.toml");
|
|
115682
|
+
if (!existsSync16(tomlPath)) {
|
|
115465
115683
|
ctx.status("No percher.toml found — detecting framework...");
|
|
115466
115684
|
const result = await init(ctx);
|
|
115467
115685
|
const answer = await ctx.prompt(`Generated percher.toml for ${result.detected?.framework ?? result.detected?.runtime ?? "node"}. Continue? [Y/n]`, { default: "y" });
|
|
@@ -115572,7 +115790,7 @@ async function push(ctx, input = {}, internals = {}) {
|
|
|
115572
115790
|
fileCount: tarball.fileCount,
|
|
115573
115791
|
recovery: RECOVERY_NONE,
|
|
115574
115792
|
summary: `Dry run for ${config2.app.name}: ${tarball.fileCount} files, ${(tarball.bytes / 1024).toFixed(1)} KB — no deploy performed.`,
|
|
115575
|
-
configPath:
|
|
115793
|
+
configPath: join25(ctx.cwd, "percher.toml"),
|
|
115576
115794
|
bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
|
|
115577
115795
|
};
|
|
115578
115796
|
}
|
|
@@ -115755,7 +115973,7 @@ ${deployment.errorMessage}` : "";
|
|
|
115755
115973
|
fileCount: tarball.fileCount,
|
|
115756
115974
|
recovery: RECOVERY_NONE,
|
|
115757
115975
|
summary,
|
|
115758
|
-
configPath:
|
|
115976
|
+
configPath: join25(ctx.cwd, "percher.toml"),
|
|
115759
115977
|
bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
|
|
115760
115978
|
};
|
|
115761
115979
|
}
|
|
@@ -116084,8 +116302,8 @@ function failureResult(error48) {
|
|
|
116084
116302
|
};
|
|
116085
116303
|
}
|
|
116086
116304
|
// ../core/dist/commands/rename.js
|
|
116087
|
-
import { existsSync as
|
|
116088
|
-
import { join as
|
|
116305
|
+
import { existsSync as existsSync17, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
|
|
116306
|
+
import { join as join26 } from "node:path";
|
|
116089
116307
|
var renameInputSchema = exports_external.object({
|
|
116090
116308
|
app: exports_external.string().optional(),
|
|
116091
116309
|
name: exports_external.string().min(3).max(40)
|
|
@@ -116105,8 +116323,8 @@ async function rename2(ctx, input) {
|
|
|
116105
116323
|
};
|
|
116106
116324
|
}
|
|
116107
116325
|
function updateLocalTomlName(cwd, oldName, newName) {
|
|
116108
|
-
const p =
|
|
116109
|
-
if (!
|
|
116326
|
+
const p = join26(cwd, "percher.toml");
|
|
116327
|
+
if (!existsSync17(p))
|
|
116110
116328
|
return false;
|
|
116111
116329
|
try {
|
|
116112
116330
|
const src = readFileSync12(p, "utf8");
|
|
@@ -116115,25 +116333,25 @@ function updateLocalTomlName(cwd, oldName, newName) {
|
|
|
116115
116333
|
const next = src.replace(new RegExp(`(name\\s*=\\s*")${oldName}(")`), `$1${newName}$2`);
|
|
116116
116334
|
if (next === src || parse5(next).app.name !== newName)
|
|
116117
116335
|
return false;
|
|
116118
|
-
|
|
116336
|
+
writeFileSync9(p, next);
|
|
116119
116337
|
return true;
|
|
116120
116338
|
} catch {
|
|
116121
116339
|
return false;
|
|
116122
116340
|
}
|
|
116123
116341
|
}
|
|
116124
116342
|
// ../core/dist/commands/reproduce.js
|
|
116125
|
-
import { mkdtempSync, writeFileSync as
|
|
116343
|
+
import { mkdtempSync, writeFileSync as writeFileSync10 } from "node:fs";
|
|
116126
116344
|
import { tmpdir } from "node:os";
|
|
116127
|
-
import { join as
|
|
116345
|
+
import { join as join27 } from "node:path";
|
|
116128
116346
|
var import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
|
|
116129
116347
|
function runProcessExit(cmd, args, opts = {}) {
|
|
116130
|
-
return new Promise((
|
|
116348
|
+
return new Promise((resolve11, reject) => {
|
|
116131
116349
|
const child = import_cross_spawn2.default(cmd, args, {
|
|
116132
116350
|
cwd: opts.cwd,
|
|
116133
116351
|
stdio: opts.inherit ? "inherit" : "ignore"
|
|
116134
116352
|
});
|
|
116135
116353
|
child.on("error", reject);
|
|
116136
|
-
child.on("close", (code) =>
|
|
116354
|
+
child.on("close", (code) => resolve11(code ?? 1));
|
|
116137
116355
|
});
|
|
116138
116356
|
}
|
|
116139
116357
|
var reproduceInputSchema = exports_external.object({
|
|
@@ -116219,9 +116437,9 @@ async function reproduce(ctx, input) {
|
|
|
116219
116437
|
const envMap = await ctx.client.env.list(app.id);
|
|
116220
116438
|
currentAppEnvKeys = Object.keys(envMap).sort();
|
|
116221
116439
|
} catch {}
|
|
116222
|
-
const tmpDir = mkdtempSync(
|
|
116223
|
-
const tarballPath =
|
|
116224
|
-
|
|
116440
|
+
const tmpDir = mkdtempSync(join27(tmpdir(), `percher-reproduce-${input.deployId}-`));
|
|
116441
|
+
const tarballPath = join27(tmpDir, "source.tar.gz");
|
|
116442
|
+
writeFileSync10(tarballPath, bytes);
|
|
116225
116443
|
let extracted = false;
|
|
116226
116444
|
try {
|
|
116227
116445
|
extracted = await runProcessExit("tar", ["-xzf", tarballPath, "-C", tmpDir]) === 0;
|
|
@@ -116658,7 +116876,6 @@ var PLAN_CATALOG = {
|
|
|
116658
116876
|
priceEur: 0,
|
|
116659
116877
|
limits: {
|
|
116660
116878
|
apps: 3,
|
|
116661
|
-
deploysPerMonth: 50,
|
|
116662
116879
|
deploysPerHour: 12,
|
|
116663
116880
|
memory: "256mb",
|
|
116664
116881
|
cpu: 0.25,
|
|
@@ -116690,7 +116907,6 @@ var PLAN_CATALOG = {
|
|
|
116690
116907
|
priceEur: 3,
|
|
116691
116908
|
limits: {
|
|
116692
116909
|
apps: 10,
|
|
116693
|
-
deploysPerMonth: 200,
|
|
116694
116910
|
deploysPerHour: 30,
|
|
116695
116911
|
memory: "512mb",
|
|
116696
116912
|
cpu: 0.25,
|
|
@@ -116722,7 +116938,6 @@ var PLAN_CATALOG = {
|
|
|
116722
116938
|
priceEur: 12,
|
|
116723
116939
|
limits: {
|
|
116724
116940
|
apps: 20,
|
|
116725
|
-
deploysPerMonth: 500,
|
|
116726
116941
|
deploysPerHour: 60,
|
|
116727
116942
|
memory: "1gb",
|
|
116728
116943
|
cpu: 0.5,
|
|
@@ -116754,7 +116969,6 @@ var PLAN_CATALOG = {
|
|
|
116754
116969
|
priceEur: 29,
|
|
116755
116970
|
limits: {
|
|
116756
116971
|
apps: 40,
|
|
116757
|
-
deploysPerMonth: "unlimited",
|
|
116758
116972
|
deploysPerHour: 120,
|
|
116759
116973
|
memory: "1gb",
|
|
116760
116974
|
cpu: 1,
|
|
@@ -116787,7 +117001,6 @@ var PLAN_CATALOG = {
|
|
|
116787
117001
|
hidden: true,
|
|
116788
117002
|
limits: {
|
|
116789
117003
|
apps: 1,
|
|
116790
|
-
deploysPerMonth: 20,
|
|
116791
117004
|
deploysPerHour: 6,
|
|
116792
117005
|
memory: "128mb",
|
|
116793
117006
|
cpu: 0.25,
|
|
@@ -117479,6 +117692,36 @@ function registerAppsCommands(cli, ctx) {
|
|
|
117479
117692
|
await writeLine(ctx, `${import_picocolors4.default.green("✓")} wrote ${file2}`);
|
|
117480
117693
|
}
|
|
117481
117694
|
});
|
|
117695
|
+
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) => {
|
|
117696
|
+
const result = await appstoreKit(ctx, {
|
|
117697
|
+
name: options.name,
|
|
117698
|
+
url: options.url,
|
|
117699
|
+
packageName: options.package,
|
|
117700
|
+
fingerprint: options.fingerprint,
|
|
117701
|
+
teamId: options.teamId,
|
|
117702
|
+
bundleId: options.bundleId,
|
|
117703
|
+
outDir: options.out,
|
|
117704
|
+
force: options.force
|
|
117705
|
+
});
|
|
117706
|
+
for (const file2 of result.written) {
|
|
117707
|
+
await writeLine(ctx, `${import_picocolors4.default.green("✓")} wrote ${file2}`);
|
|
117708
|
+
}
|
|
117709
|
+
for (const file2 of result.skipped) {
|
|
117710
|
+
await writeLine(ctx, `${import_picocolors4.default.dim("•")} skipped ${file2} (exists — pass --force to overwrite)`);
|
|
117711
|
+
}
|
|
117712
|
+
await writeLine(ctx, "");
|
|
117713
|
+
await writeLine(ctx, `${import_picocolors4.default.bold("Make it an installable PWA:")} link the manifest from your HTML`);
|
|
117714
|
+
await writeLine(ctx, ` <link rel="manifest" href="/manifest.json">`);
|
|
117715
|
+
await writeLine(ctx, "and register the service worker from your app entry:");
|
|
117716
|
+
await writeLine(ctx, result.swRegistration);
|
|
117717
|
+
await writeLine(ctx, "");
|
|
117718
|
+
await writeLine(ctx, `${import_picocolors4.default.bold("Wrap for Google Play (TWA):")}`);
|
|
117719
|
+
await writeLine(ctx, result.bubblewrapCommand);
|
|
117720
|
+
await writeLine(ctx, "");
|
|
117721
|
+
await writeLine(ctx, `The two ${import_picocolors4.default.dim(".well-known")} files are trust assertions for your origin — add real values`);
|
|
117722
|
+
await writeLine(ctx, `after you sign the apps, then serve them yourself or let Percher serve them from the`);
|
|
117723
|
+
await writeLine(ctx, "App store kit at https://percher.app. Full guide: /docs/app-stores");
|
|
117724
|
+
});
|
|
117482
117725
|
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) => {
|
|
117483
117726
|
const { detectCiBranchMessage: detectCiBranchMessage2 } = await Promise.resolve().then(() => exports_ci_env);
|
|
117484
117727
|
let messageOverride = options.message;
|
|
@@ -117560,8 +117803,8 @@ function registerAppsCommands(cli, ctx) {
|
|
|
117560
117803
|
deployId,
|
|
117561
117804
|
timeoutSeconds: Math.min(Math.ceil(remainingMs / 1000), 30)
|
|
117562
117805
|
}, { signal: callController.signal }),
|
|
117563
|
-
new Promise((
|
|
117564
|
-
raceTimer = setTimeout(() =>
|
|
117806
|
+
new Promise((resolve11) => {
|
|
117807
|
+
raceTimer = setTimeout(() => resolve11(null), remainingMs);
|
|
117565
117808
|
})
|
|
117566
117809
|
]);
|
|
117567
117810
|
} finally {
|
|
@@ -118805,7 +119048,7 @@ async function renderError(stderr, error48) {
|
|
|
118805
119048
|
// package.json
|
|
118806
119049
|
var package_default = {
|
|
118807
119050
|
name: "percher",
|
|
118808
|
-
version: "0.5.
|
|
119051
|
+
version: "0.5.10",
|
|
118809
119052
|
description: "CLI for the Percher hosting platform — publish apps with one command",
|
|
118810
119053
|
type: "module",
|
|
118811
119054
|
bin: {
|
|
@@ -118886,18 +119129,18 @@ async function showTelemetryNotice() {
|
|
|
118886
119129
|
if (isDisabled())
|
|
118887
119130
|
return;
|
|
118888
119131
|
const { homedir: homedir2 } = await import("node:os");
|
|
118889
|
-
const { existsSync:
|
|
118890
|
-
const { join:
|
|
118891
|
-
const configDir =
|
|
118892
|
-
const markerFile =
|
|
118893
|
-
if (
|
|
119132
|
+
const { existsSync: existsSync18, mkdirSync: mkdirSync7, writeFileSync: writeFileSync11 } = await import("node:fs");
|
|
119133
|
+
const { join: join28 } = await import("node:path");
|
|
119134
|
+
const configDir = join28(homedir2(), ".percher");
|
|
119135
|
+
const markerFile = join28(configDir, ".telemetry-notice-shown");
|
|
119136
|
+
if (existsSync18(markerFile))
|
|
118894
119137
|
return;
|
|
118895
119138
|
console.log("Percher sends non-account-linked usage stats (command, result, error type, OS, Bun version).");
|
|
118896
119139
|
console.log(`Disable with PERCHER_NO_TELEMETRY=1
|
|
118897
119140
|
`);
|
|
118898
119141
|
try {
|
|
118899
|
-
|
|
118900
|
-
|
|
119142
|
+
mkdirSync7(configDir, { recursive: true });
|
|
119143
|
+
writeFileSync11(markerFile, new Date().toISOString());
|
|
118901
119144
|
} catch {}
|
|
118902
119145
|
}
|
|
118903
119146
|
|