percher 0.5.12 → 0.5.15
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 +64 -12
- package/dist/package.json +2 -2
- package/package.json +2 -2
package/dist/bin/percher.js
CHANGED
|
@@ -104733,7 +104733,15 @@ var percherConfigSchema = exports_external.object({
|
|
|
104733
104733
|
crons: cronsSchema.optional(),
|
|
104734
104734
|
addons: addonsSchema.optional(),
|
|
104735
104735
|
checks: exports_external.record(exports_external.string(), checkSchema).optional()
|
|
104736
|
-
}).strict()
|
|
104736
|
+
}).strict().superRefine((cfg, ctx) => {
|
|
104737
|
+
if (cfg.app?.runtime === "static" && cfg.build?.command) {
|
|
104738
|
+
ctx.addIssue({
|
|
104739
|
+
code: exports_external.ZodIssueCode.custom,
|
|
104740
|
+
path: ["build", "command"],
|
|
104741
|
+
message: 'runtime = "static" serves pre-built files and does not run a build command. Remove [build].command (commit the built output), or switch to runtime = "docker" for a build step.'
|
|
104742
|
+
});
|
|
104743
|
+
}
|
|
104744
|
+
});
|
|
104737
104745
|
|
|
104738
104746
|
// ../toml/dist/parse.js
|
|
104739
104747
|
function parse5(source) {
|
|
@@ -106572,10 +106580,10 @@ class LogsResource {
|
|
|
106572
106580
|
const query = buildLogFilterQuery(options ?? {}, { lines: String(lines) });
|
|
106573
106581
|
return this.http.get(`/apps/${encodeURIComponent(appId)}/logs?${query}`);
|
|
106574
106582
|
}
|
|
106575
|
-
streamRaw(appRef, options) {
|
|
106583
|
+
streamRaw(appRef, options, signal) {
|
|
106576
106584
|
const query = buildLogFilterQuery(options ?? {});
|
|
106577
106585
|
const suffix = query ? `?${query}` : "";
|
|
106578
|
-
return this.http.stream(`/apps/${encodeURIComponent(appRef)}/logs/stream${suffix}
|
|
106586
|
+
return this.http.stream(`/apps/${encodeURIComponent(appRef)}/logs/stream${suffix}`, signal);
|
|
106579
106587
|
}
|
|
106580
106588
|
async* stream(appId, options) {
|
|
106581
106589
|
const query = buildLogFilterQuery(options ?? {});
|
|
@@ -107267,6 +107275,7 @@ function recoveryFromErrorClass(errorClass, failure = {}) {
|
|
|
107267
107275
|
switch (errorClass) {
|
|
107268
107276
|
case "missing_env":
|
|
107269
107277
|
return recoveryEnv({
|
|
107278
|
+
app: failure.appName,
|
|
107270
107279
|
keys: failure.missingEnvVars ?? [],
|
|
107271
107280
|
reasonCode: "missing_env"
|
|
107272
107281
|
});
|
|
@@ -107647,7 +107656,7 @@ var patterns = [
|
|
|
107647
107656
|
result: {
|
|
107648
107657
|
title: "Health check failed",
|
|
107649
107658
|
explanation: "Your app started but did not respond to the health check endpoint in time.",
|
|
107650
|
-
suggestion: "Make sure your app listens on process.env.PORT and returns HTTP 200
|
|
107659
|
+
suggestion: "Make sure your app listens on the injected port (process.env.PORT) and that your configured health path ([web].health in percher.toml, default '/') returns HTTP 200. Run `percher doctor --app <name>` for deeper analysis, then publish again.",
|
|
107651
107660
|
errorClass: "health_check_timeout",
|
|
107652
107661
|
phase: "health_check",
|
|
107653
107662
|
cause: "timeout",
|
|
@@ -107961,6 +107970,7 @@ var DEFAULT_IGNORE = [
|
|
|
107961
107970
|
"*.log",
|
|
107962
107971
|
".DS_Store"
|
|
107963
107972
|
];
|
|
107973
|
+
var ALWAYS_IGNORE_SECRETS = [".env", ".env.*"];
|
|
107964
107974
|
function* walk(dir, baseDir, ig) {
|
|
107965
107975
|
const entries = readdirSync2(dir);
|
|
107966
107976
|
for (const name of entries) {
|
|
@@ -108026,14 +108036,25 @@ function buildTarball(fileBuffers) {
|
|
|
108026
108036
|
const nodeStream = pack.pipe(gzip);
|
|
108027
108037
|
const webStream = Readable.toWeb(nodeStream);
|
|
108028
108038
|
const topFiles = [...fileBuffers].sort((a, b) => b.size - a.size).slice(0, 5).map((f) => ({ path: f.path, size: f.size }));
|
|
108039
|
+
const entrySizes = new Map;
|
|
108040
|
+
for (const f of fileBuffers) {
|
|
108041
|
+
const slash = f.path.indexOf("/");
|
|
108042
|
+
const key = slash === -1 ? f.path : `${f.path.slice(0, slash)}/`;
|
|
108043
|
+
entrySizes.set(key, (entrySizes.get(key) ?? 0) + f.size);
|
|
108044
|
+
}
|
|
108045
|
+
const topEntries = [...entrySizes.entries()].map(([path, size]) => ({ path, size, isDir: path.endsWith("/") })).sort((a, b) => b.size - a.size).slice(0, 5);
|
|
108029
108046
|
return {
|
|
108030
108047
|
stream: webStream,
|
|
108031
108048
|
bytes: totalBytes,
|
|
108032
108049
|
fileCount: fileBuffers.length,
|
|
108033
108050
|
topFiles,
|
|
108051
|
+
topEntries,
|
|
108034
108052
|
contentHash
|
|
108035
108053
|
};
|
|
108036
108054
|
}
|
|
108055
|
+
function formatBiggestEntries(entries) {
|
|
108056
|
+
return entries.map((e) => `${e.path} ${(e.size / 1024 / 1024).toFixed(1)} MB`).join(", ");
|
|
108057
|
+
}
|
|
108037
108058
|
async function createTarball(options) {
|
|
108038
108059
|
if (isFilesOptions(options)) {
|
|
108039
108060
|
return createTarballFromFiles(options.files, options.config);
|
|
@@ -108044,8 +108065,13 @@ async function createTarball(options) {
|
|
|
108044
108065
|
if (existsSync6(gitignorePath)) {
|
|
108045
108066
|
ig.add(readFileSync6(gitignorePath, "utf8"));
|
|
108046
108067
|
}
|
|
108068
|
+
const percherignorePath = join10(options.cwd, ".percherignore");
|
|
108069
|
+
if (existsSync6(percherignorePath)) {
|
|
108070
|
+
ig.add(readFileSync6(percherignorePath, "utf8"));
|
|
108071
|
+
}
|
|
108047
108072
|
if (options.extraIgnore)
|
|
108048
108073
|
ig.add(options.extraIgnore);
|
|
108074
|
+
ig.add(ALWAYS_IGNORE_SECRETS);
|
|
108049
108075
|
const fileBuffers = [];
|
|
108050
108076
|
for (const rel of walk(options.cwd, options.cwd, ig)) {
|
|
108051
108077
|
const data2 = readFileSync6(join10(options.cwd, rel));
|
|
@@ -114641,6 +114667,27 @@ function tomlErrorToRecoveryProblems(err) {
|
|
|
114641
114667
|
// ../core/dist/commands/env-scan.js
|
|
114642
114668
|
import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
|
|
114643
114669
|
import { join as join22 } from "node:path";
|
|
114670
|
+
function platformInjectedClientEnvKeys(config2) {
|
|
114671
|
+
const data2 = config2.data;
|
|
114672
|
+
if (!data2)
|
|
114673
|
+
return [];
|
|
114674
|
+
switch (data2.mode) {
|
|
114675
|
+
case "pocketbase":
|
|
114676
|
+
return ["VITE_POCKETBASE_URL", "VITE_PERCHER_AI_URL"];
|
|
114677
|
+
case "convex":
|
|
114678
|
+
return data2.convex?.deployment_url ? ["VITE_CONVEX_URL"] : [];
|
|
114679
|
+
case "supabase": {
|
|
114680
|
+
const keys = [];
|
|
114681
|
+
if (data2.supabase?.url)
|
|
114682
|
+
keys.push("VITE_SUPABASE_URL");
|
|
114683
|
+
if (data2.supabase?.anon_key)
|
|
114684
|
+
keys.push("VITE_SUPABASE_ANON_KEY");
|
|
114685
|
+
return keys;
|
|
114686
|
+
}
|
|
114687
|
+
default:
|
|
114688
|
+
return [];
|
|
114689
|
+
}
|
|
114690
|
+
}
|
|
114644
114691
|
var SOURCE_EXTS = new Set([
|
|
114645
114692
|
".ts",
|
|
114646
114693
|
".tsx",
|
|
@@ -115297,10 +115344,10 @@ ${bullets}`,
|
|
|
115297
115344
|
error: {
|
|
115298
115345
|
title: "Repository too large",
|
|
115299
115346
|
explanation: `The project is ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB, which exceeds the 500 MB limit.`,
|
|
115300
|
-
suggestion: `Add large files/folders to .gitignore. Biggest: ${tarball.
|
|
115347
|
+
suggestion: `Add large files/folders to .gitignore or .percherignore. Biggest: ${formatBiggestEntries(tarball.topEntries)}`
|
|
115301
115348
|
},
|
|
115302
115349
|
recovery: recoveryAsk({
|
|
115303
|
-
prompt: `Repository is ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB, which exceeds the 500 MB upload limit. Add large files/folders to .gitignore (biggest: ${tarball.
|
|
115350
|
+
prompt: `Repository is ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB, which exceeds the 500 MB upload limit. Add large files/folders to .gitignore or .percherignore (biggest: ${formatBiggestEntries(tarball.topEntries)}) and try again.`,
|
|
115304
115351
|
reasonCode: "unknown"
|
|
115305
115352
|
}),
|
|
115306
115353
|
summary: `Repository too large (${(tarball.bytes / 1024 / 1024).toFixed(1)} MB exceeds 500 MB limit).`,
|
|
@@ -115309,7 +115356,7 @@ ${bullets}`,
|
|
|
115309
115356
|
};
|
|
115310
115357
|
}
|
|
115311
115358
|
if (!input.force && (tarball.fileCount > SUSPICIOUS_FILES || tarball.bytes > SUSPICIOUS_BYTES)) {
|
|
115312
|
-
ctx.status(`Warning: ${tarball.fileCount} files, ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB — auto-continuing (MCP mode).`);
|
|
115359
|
+
ctx.status(`Warning: ${tarball.fileCount} files, ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB — auto-continuing (MCP mode). Biggest: ${formatBiggestEntries(tarball.topEntries)}. Trim the upload by adding large items to .gitignore or .percherignore.`);
|
|
115313
115360
|
}
|
|
115314
115361
|
emitPreflight(ctx, config2, {
|
|
115315
115362
|
fileCount: tarball.fileCount,
|
|
@@ -115340,6 +115387,8 @@ ${bullets}`,
|
|
|
115340
115387
|
let missingBuildEnvKeys = [];
|
|
115341
115388
|
try {
|
|
115342
115389
|
const existingEnvKeys = new Set(Object.keys(await ctx.client.env.list(app.id)));
|
|
115390
|
+
for (const k of platformInjectedClientEnvKeys(config2))
|
|
115391
|
+
existingEnvKeys.add(k);
|
|
115343
115392
|
missingBuildEnvKeys = scanForMissingBuildEnvRefs(ctx.cwd, existingEnvKeys);
|
|
115344
115393
|
} catch {}
|
|
115345
115394
|
if (missingBuildEnvKeys.length > 0 && !input.force) {
|
|
@@ -115968,17 +116017,17 @@ async function push(ctx, input = {}, internals = {}) {
|
|
|
115968
116017
|
if (tarball.bytes > MAX_TARBALL_BYTES) {
|
|
115969
116018
|
throw new PercherCoreError(`Repository is larger than 500 MB (current: ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB)`, {
|
|
115970
116019
|
code: "push.too-large",
|
|
115971
|
-
hint: `Biggest
|
|
116020
|
+
hint: `Biggest: ${formatBiggestEntries(tarball.topEntries)}`,
|
|
115972
116021
|
recovery: {
|
|
115973
116022
|
...recoveryAsk({
|
|
115974
|
-
prompt: `Repository is ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB, exceeding the 500 MB limit. Add large files/folders to .gitignore (biggest: ${tarball.
|
|
116023
|
+
prompt: `Repository is ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB, exceeding the 500 MB limit. Add large files/folders to .gitignore or .percherignore (biggest: ${formatBiggestEntries(tarball.topEntries)}) and re-run.`,
|
|
115975
116024
|
reasonCode: "unknown"
|
|
115976
116025
|
})
|
|
115977
116026
|
}
|
|
115978
116027
|
});
|
|
115979
116028
|
}
|
|
115980
116029
|
if (!input.force && (tarball.fileCount > SUSPICIOUS_FILES2 || tarball.bytes > SUSPICIOUS_BYTES2)) {
|
|
115981
|
-
ctx.status(`This looks suspicious: ${tarball.fileCount} files, ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB. Are node_modules / dist excluded?`);
|
|
116030
|
+
ctx.status(`This looks suspicious: ${tarball.fileCount} files, ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB. Biggest: ${formatBiggestEntries(tarball.topEntries)}. Are node_modules / dist excluded?`);
|
|
115982
116031
|
const answer = await ctx.prompt("Continue anyway? [y/N]", { default: "n" });
|
|
115983
116032
|
if (!/^y(es)?$/i.test(answer.trim())) {
|
|
115984
116033
|
throw new PercherCoreError("Push aborted — looked suspicious", {
|
|
@@ -117280,6 +117329,9 @@ var BLOCKED_APP_NAMES = new Set([
|
|
|
117280
117329
|
"caddy",
|
|
117281
117330
|
"git",
|
|
117282
117331
|
"percher",
|
|
117332
|
+
"mcp",
|
|
117333
|
+
"preview",
|
|
117334
|
+
"metrics",
|
|
117283
117335
|
"login",
|
|
117284
117336
|
"signin",
|
|
117285
117337
|
"signup",
|
|
@@ -119308,7 +119360,7 @@ async function renderError(stderr, error48) {
|
|
|
119308
119360
|
// package.json
|
|
119309
119361
|
var package_default = {
|
|
119310
119362
|
name: "percher",
|
|
119311
|
-
version: "0.5.
|
|
119363
|
+
version: "0.5.15",
|
|
119312
119364
|
description: "CLI for the Percher hosting platform — publish apps with one command",
|
|
119313
119365
|
type: "module",
|
|
119314
119366
|
bin: {
|
|
@@ -119333,7 +119385,7 @@ var package_default = {
|
|
|
119333
119385
|
},
|
|
119334
119386
|
dependencies: {
|
|
119335
119387
|
"@percher/client": "^0.2.16",
|
|
119336
|
-
"@percher/core": "^0.4.
|
|
119388
|
+
"@percher/core": "^0.4.18",
|
|
119337
119389
|
"@percher/toml": "^0.1.5",
|
|
119338
119390
|
cac: "^7.0.0",
|
|
119339
119391
|
picocolors: "^1.1.1"
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "percher",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.15",
|
|
4
4
|
"description": "CLI for the Percher hosting platform \u2014 publish apps with one command",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@percher/client": "^0.2.16",
|
|
28
|
-
"@percher/core": "^0.4.
|
|
28
|
+
"@percher/core": "^0.4.18",
|
|
29
29
|
"@percher/toml": "^0.1.5",
|
|
30
30
|
"cac": "^7.0.0",
|
|
31
31
|
"picocolors": "^1.1.1"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "percher",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.15",
|
|
4
4
|
"description": "CLI for the Percher hosting platform \u2014 publish apps with one command",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@percher/client": "^0.2.16",
|
|
28
|
-
"@percher/core": "^0.4.
|
|
28
|
+
"@percher/core": "^0.4.18",
|
|
29
29
|
"@percher/toml": "^0.1.5",
|
|
30
30
|
"cac": "^7.0.0",
|
|
31
31
|
"picocolors": "^1.1.1"
|