openship 0.4.8 → 0.6.0

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.
Files changed (112) hide show
  1. package/README.md +27 -1
  2. package/dist/bare-FSUAM5V5.js +23 -0
  3. package/dist/{bowser-O3AEA6AN.js → bowser-HNOTPGJO.js} +2 -2
  4. package/dist/{chunk-5MZ624VX.js → chunk-2GWYYHOR.js} +1 -1
  5. package/dist/chunk-3FYIXVX5.js +8051 -0
  6. package/dist/{chunk-ILFETZOM.js → chunk-3LDWWY7U.js} +21 -1
  7. package/dist/{chunk-W73X43R7.js → chunk-3NQQXMDR.js} +3 -3
  8. package/dist/{chunk-OWED2GRM.js → chunk-42WQABXM.js} +2 -2
  9. package/dist/{chunk-TYVME3XD.js → chunk-6FH4AXVY.js} +20 -3
  10. package/dist/{chunk-OXWDY22G.js → chunk-6ODUBKUB.js} +3 -3
  11. package/dist/{chunk-DYPH4HCI.js → chunk-AO252K7Z.js} +1 -1
  12. package/dist/{chunk-XPPZ7B2J.js → chunk-B3CE2OMR.js} +14 -12
  13. package/dist/{chunk-IXCHURVK.js → chunk-DOD2BXHQ.js} +4 -4
  14. package/dist/{chunk-VWPEKOH6.js → chunk-DRK3MEDS.js} +3 -3
  15. package/dist/{chunk-V6AN6XLZ.js → chunk-EMXI4UCU.js} +125 -47
  16. package/dist/{chunk-GKHUSZCD.js → chunk-EP2TNALB.js} +2 -2
  17. package/dist/{chunk-SLTYVHU7.js → chunk-GUQ3QCJ7.js} +942 -519
  18. package/dist/chunk-I3DPMTSF.js +29 -0
  19. package/dist/{chunk-L2VOGB2X.js → chunk-IW2UKBVF.js} +3 -3
  20. package/dist/{chunk-VDMQJHPI.js → chunk-IXM5245F.js} +228 -13
  21. package/dist/{chunk-MZ2WEHHY.js → chunk-JIMUYEKN.js} +4 -4
  22. package/dist/chunk-OGY63DGD.js +705 -0
  23. package/dist/{chunk-O6ZZF52V.js → chunk-ONKEYSMY.js} +2 -2
  24. package/dist/{chunk-6APULWSU.js → chunk-OTLSJYAC.js} +1744 -118
  25. package/dist/{chunk-EI575GHN.js → chunk-PDW4L3NV.js} +3 -3
  26. package/dist/{chunk-5NYUCONN.js → chunk-PSZSKEPA.js} +33 -51
  27. package/dist/{chunk-KI2EY3WB.js → chunk-PXKCZB2I.js} +1 -1
  28. package/dist/{chunk-FXTBHTWY.js → chunk-QEH4QUBX.js} +649 -85
  29. package/dist/{chunk-6APIPIJY.js → chunk-QWHBRY2K.js} +5 -5
  30. package/dist/{chunk-6B5YCFFV.js → chunk-RVER2EOO.js} +5 -5
  31. package/dist/{chunk-Q2CIRAOK.js → chunk-RXQBD4ZY.js} +1 -1
  32. package/dist/{chunk-TGIINPVM.js → chunk-TWJCLD4W.js} +60 -10
  33. package/dist/{chunk-4Z5QO7N6.js → chunk-VDDMADOF.js} +3 -3
  34. package/dist/{chunk-BBHX7T4R.js → chunk-VE2YOK4I.js} +991 -254
  35. package/dist/{chunk-2D3I5G6P.js → chunk-VZ2ZHPS2.js} +73 -43
  36. package/dist/{chunk-AVIB7CT7.js → chunk-WNWQBB7F.js} +2 -2
  37. package/dist/{chunk-FRNAR33O.js → chunk-XZYFZ6A5.js} +3 -3
  38. package/dist/{chunk-RPHRPFEH.js → chunk-ZCFVHA25.js} +1 -1
  39. package/dist/{chunk-FPRHYBY2.js → chunk-ZFJXPCQP.js} +1 -1
  40. package/dist/{chunk-JYGD5WSN.js → chunk-ZWLDLTJP.js} +1 -1
  41. package/dist/cloud-E5M6VMCG.js +31 -0
  42. package/dist/{cloud-7QYOGF7F.js → cloud-KRTZ2IL5.js} +3 -3
  43. package/dist/{detect-AZLOHUFX.js → detect-ALF4GXRX.js} +7 -8
  44. package/dist/{dist-IQJ6H6UZ.js → dist-BM6NPWIH.js} +3 -3
  45. package/dist/{dist-es-X3B5QYKB.js → dist-es-2YRDXMUU.js} +6 -6
  46. package/dist/{dist-es-OSNJBLXB.js → dist-es-CCVZEFRZ.js} +5 -5
  47. package/dist/{dist-es-VNKHQVIB.js → dist-es-IOH6G4GM.js} +4 -4
  48. package/dist/{dist-es-RYHIPOTN.js → dist-es-JGBPABJI.js} +14 -14
  49. package/dist/{dist-es-JSTDUS7Q.js → dist-es-KWSMDPIP.js} +6 -6
  50. package/dist/{dist-es-5DY7K32L.js → dist-es-UYDDOVZ3.js} +6 -6
  51. package/dist/{dist-es-WV4AMOII.js → dist-es-XUOR4NQN.js} +8 -8
  52. package/dist/docker-QECQJ5P4.js +32 -0
  53. package/dist/docker-edge-executor-62N64MGS.js +17 -0
  54. package/dist/edge-import-CQWHN2Q3.js +48 -0
  55. package/dist/ensure-container-edge-MJVXJQG5.js +32 -0
  56. package/dist/{event-streams-EHRAKL75.js → event-streams-TR4GAC53.js} +4 -4
  57. package/dist/{executor-XJ6RP4Q2.js → executor-JELARVKC.js} +8 -8
  58. package/dist/index.js +1209 -560
  59. package/dist/{loadSso-46FQRIZS.js → loadSso-UGF4JMRK.js} +10 -10
  60. package/dist/{local-executor-V7U5VOZW.js → local-executor-WOFZD72X.js} +4 -4
  61. package/dist/nginx-AXGNWRKZ.js +31 -0
  62. package/dist/node-entry.js +4 -0
  63. package/dist/{noop-FMMFG2EZ.js → noop-NJ72F46T.js} +3 -3
  64. package/dist/openresty-lua-IE4P5YQX.js +81 -0
  65. package/dist/server/index.js +116248 -94749
  66. package/dist/server/lua/geo_country.lua +31 -6
  67. package/dist/server/lua/maxminddb.lua +403 -0
  68. package/dist/server/lua/mgmt_api.lua +431 -68
  69. package/dist/server/lua/pipe_log.lua +10 -4
  70. package/dist/server/lua/site_logger.lua +220 -12
  71. package/dist/server/migrations/0073_project_volumes_object_storage.sql +3 -0
  72. package/dist/server/migrations/0074_project_compose_path.sql +1 -0
  73. package/dist/server/migrations/0075_service_command_argv.sql +1 -0
  74. package/dist/server/migrations/0076_rollback_retention.sql +17 -0
  75. package/dist/server/migrations/0077_domain_redirect.sql +13 -0
  76. package/dist/server/migrations/0078_grant_source_scope.sql +30 -0
  77. package/dist/server/migrations/0079_project_readiness.sql +18 -0
  78. package/dist/server/migrations/0080_deployment_error_classification.sql +26 -0
  79. package/dist/server/migrations/0081_project_readiness_repair.sql +34 -0
  80. package/dist/server/migrations/0082_edge_target_verification.sql +39 -0
  81. package/dist/server/migrations/0083_service_incident.sql +84 -0
  82. package/dist/server/migrations/0084_analytics_daily_rollup.sql +72 -0
  83. package/dist/server/migrations/0085_resource_usage.sql +68 -0
  84. package/dist/server/migrations/0086_remote_infra_updates.sql +41 -0
  85. package/dist/server/migrations/0087_server_container_version_columns.sql +17 -0
  86. package/dist/server/migrations/0088_audit_source_and_settings.sql +27 -0
  87. package/dist/server/migrations/0089_auto_scan_infra.sql +7 -0
  88. package/dist/server/migrations/0090_project_collect_paths.sql +18 -0
  89. package/dist/server/migrations/0091_project_server_id.sql +26 -0
  90. package/dist/server/migrations/0092_project_internal_alias.sql +13 -0
  91. package/dist/server/migrations/0093_service_incident_org_index.sql +13 -0
  92. package/dist/server/migrations/0094_backup_restore_meta.sql +15 -0
  93. package/dist/server/migrations/0095_backup_restore_cancel.sql +19 -0
  94. package/dist/server/migrations/0096_backup_policy_retention_defaults.sql +20 -0
  95. package/dist/server/migrations/0097_update_status_upstream_only.sql +35 -0
  96. package/dist/server/migrations/meta/_journal.json +175 -0
  97. package/dist/setup-FA4PW4NU.js +21 -0
  98. package/dist/{signin-ITOPKKUB.js → signin-3M3UPB6K.js} +10 -10
  99. package/dist/{sso-oidc-NON2PD7Y.js → sso-oidc-3VDIYOEJ.js} +10 -10
  100. package/dist/{sts-HHFFSAY2.js → sts-B3WIYLXR.js} +9 -9
  101. package/package.json +6 -3
  102. package/dist/bare-JY5Y5ELU.js +0 -23
  103. package/dist/chunk-SJIFLLX4.js +0 -2931
  104. package/dist/chunk-VFINNTUL.js +0 -362
  105. package/dist/cloud-KYWY3RP4.js +0 -30
  106. package/dist/docker-LODK5Y2S.js +0 -16
  107. package/dist/docker-edge-executor-VHW3JPJS.js +0 -13
  108. package/dist/edge-import-ABUDKKJI.js +0 -45
  109. package/dist/ensure-container-edge-SW6HENSG.js +0 -31
  110. package/dist/nginx-3L4SIBJA.js +0 -24
  111. package/dist/openresty-lua-4WLGDSER.js +0 -42
  112. package/dist/setup-NU6T2PDU.js +0 -20
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
 
@@ -54,6 +54,25 @@ async function waitForPortListening(executor, port, opts = {}) {
54
54
  }
55
55
  return anyConclusive ? { listening: false, checked: true } : { listening: false, checked: false };
56
56
  }
57
+ async function waitForPortFree(executor, port, opts = {}) {
58
+ const timeoutMs = opts.timeoutMs ?? 15e3;
59
+ const intervalMs = opts.intervalMs ?? 500;
60
+ const deadline = Date.now() + timeoutMs;
61
+ let anyConclusive = false;
62
+ try {
63
+ for (; ; ) {
64
+ const result = await probePortListeningOnce(executor, port);
65
+ if (result === false) return { free: true, checked: true };
66
+ if (result === true) anyConclusive = true;
67
+ const remaining = deadline - Date.now();
68
+ if (remaining <= 0) break;
69
+ await delay(Math.min(intervalMs, remaining));
70
+ }
71
+ } catch {
72
+ return { free: false, checked: false };
73
+ }
74
+ return anyConclusive ? { free: false, checked: true } : { free: false, checked: false };
75
+ }
57
76
 
58
77
  // ../../packages/adapters/src/runtime/port-conflict.ts
59
78
  async function tryExec(executor, command) {
@@ -126,6 +145,7 @@ async function describeProcess(executor, pid) {
126
145
 
127
146
  export {
128
147
  waitForPortListening,
148
+ waitForPortFree,
129
149
  probeListeningPort,
130
150
  describeProcess
131
151
  };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
@@ -19,7 +19,7 @@ import {
19
19
  splitHeader,
20
20
  toBase64,
21
21
  toUtf8
22
- } from "./chunk-JYGD5WSN.js";
22
+ } from "./chunk-ZWLDLTJP.js";
23
23
 
24
24
  // ../../node_modules/@smithy/types/dist-es/middleware.js
25
25
  var SMITHY_CONTEXT_KEY = "__smithy_context";
@@ -1386,7 +1386,7 @@ var HttpProtocol = class extends SerdeContext {
1386
1386
  });
1387
1387
  }
1388
1388
  async loadEventStreamCapability() {
1389
- const { EventStreamSerde } = await import("./event-streams-EHRAKL75.js");
1389
+ const { EventStreamSerde } = await import("./event-streams-TR4GAC53.js");
1390
1390
  return new EventStreamSerde({
1391
1391
  marshaller: this.getEventStreamMarshaller(),
1392
1392
  serializer: this.serializer,
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  HttpResponse,
7
7
  buildQueryString
8
- } from "./chunk-W73X43R7.js";
8
+ } from "./chunk-3NQQXMDR.js";
9
9
 
10
10
  // ../../node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js
11
11
  function buildAbortError(abortSignal) {
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
@@ -8,7 +8,7 @@ import {
8
8
  getLocalShellPath,
9
9
  logEntry,
10
10
  sq
11
- } from "./chunk-FPRHYBY2.js";
11
+ } from "./chunk-ZFJXPCQP.js";
12
12
 
13
13
  // ../../packages/adapters/src/system/local-executor.ts
14
14
  import { exec, spawn } from "child_process";
@@ -41,25 +41,42 @@ var LocalExecutor = class {
41
41
  );
42
42
  });
43
43
  }
44
- streamExec(command, onLog) {
44
+ streamExec(command, onLog, opts) {
45
45
  return new Promise((resolve) => {
46
+ if (opts?.signal?.aborted) {
47
+ resolve({ code: 0, output: "" });
48
+ return;
49
+ }
46
50
  const child = spawn(getLocalShellPath(), getLocalShellArgs(command), {
47
51
  stdio: ["ignore", "pipe", "pipe"],
48
52
  env: getLocalExecEnv()
49
53
  });
54
+ const MAX_RETAINED_CHUNKS = 200;
50
55
  const chunks = [];
51
56
  const onChunk = (data, level) => {
52
57
  const text = data.toString();
53
58
  if (!text) return;
54
59
  chunks.push(text);
60
+ if (chunks.length > MAX_RETAINED_CHUNKS) chunks.shift();
55
61
  onLog(logEntry(text, level, data.toString("base64")));
56
62
  };
63
+ const signal = opts?.signal;
64
+ const onAbort = () => {
65
+ try {
66
+ child.kill("SIGTERM");
67
+ } catch {
68
+ }
69
+ };
70
+ signal?.addEventListener("abort", onAbort, { once: true });
71
+ const cleanup = () => signal?.removeEventListener("abort", onAbort);
57
72
  child.stdout.on("data", (data) => onChunk(data, "info"));
58
73
  child.stderr.on("data", (data) => onChunk(data, "warn"));
59
74
  child.on("close", (code) => {
75
+ cleanup();
60
76
  resolve({ code: code ?? 1, output: chunks.join("") });
61
77
  });
62
78
  child.on("error", (err) => {
79
+ cleanup();
63
80
  onLog(logEntry(`Process error: ${err.message}`, "error"));
64
81
  resolve({ code: 1, output: err.message });
65
82
  });
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  isSshAuthError,
7
7
  systemDebug
8
- } from "./chunk-RPHRPFEH.js";
8
+ } from "./chunk-ZCFVHA25.js";
9
9
  import {
10
10
  PACKAGE_ROOT_ONLY_EXCLUDES
11
- } from "./chunk-6APULWSU.js";
11
+ } from "./chunk-OTLSJYAC.js";
12
12
 
13
13
  // ../../packages/adapters/src/archive.ts
14
14
  import { execFile } from "child_process";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
@@ -9,25 +9,25 @@ import {
9
9
  openSshUnixSocket,
10
10
  prepareSourceTarArgs,
11
11
  reconcileKnownHosts
12
- } from "./chunk-OXWDY22G.js";
12
+ } from "./chunk-6ODUBKUB.js";
13
13
  import {
14
14
  SshDisconnectedError
15
- } from "./chunk-RPHRPFEH.js";
15
+ } from "./chunk-ZCFVHA25.js";
16
16
  import {
17
17
  LocalExecutor
18
- } from "./chunk-TYVME3XD.js";
18
+ } from "./chunk-6FH4AXVY.js";
19
19
  import {
20
20
  emitBufferedLines,
21
21
  flushBufferedLines,
22
22
  hasLocalCommand,
23
23
  logEntry,
24
24
  sq
25
- } from "./chunk-FPRHYBY2.js";
25
+ } from "./chunk-ZFJXPCQP.js";
26
26
  import {
27
27
  TRANSFER_EXCLUDES,
28
28
  formatBytes,
29
29
  safeErrorMessage
30
- } from "./chunk-6APULWSU.js";
30
+ } from "./chunk-OTLSJYAC.js";
31
31
 
32
32
  // ../../packages/adapters/src/system/executor.ts
33
33
  import { existsSync, readFileSync } from "fs";
@@ -36,7 +36,7 @@ import { existsSync, readFileSync } from "fs";
36
36
  import { createReadStream } from "fs";
37
37
  import { mkdtemp as mkdtemp2, rm as fsRm2, stat } from "fs/promises";
38
38
  import { tmpdir as tmpdir2 } from "os";
39
- import { dirname, join as join2 } from "path";
39
+ import { join as join2, posix } from "path";
40
40
 
41
41
  // ../../packages/adapters/src/system/remote-transfer.ts
42
42
  import { spawn } from "child_process";
@@ -211,6 +211,7 @@ async function uploadFileWithRsync(localFile, remoteFile, deps, onLog, opts) {
211
211
  }
212
212
 
213
213
  // ../../packages/adapters/src/system/ssh-executor.ts
214
+ var remoteDirname = posix.dirname;
214
215
  function clampWindow(value, fallback, min, max) {
215
216
  if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
216
217
  return Math.max(min, Math.min(max, Math.floor(value)));
@@ -479,7 +480,7 @@ var SshExecutor = class _SshExecutor {
479
480
  });
480
481
  }
481
482
  async writeFile(path, content) {
482
- const dir = dirname(path);
483
+ const dir = remoteDirname(path);
483
484
  try {
484
485
  await this.exec(`mkdir -p ${sq(dir)}`);
485
486
  } catch {
@@ -794,7 +795,7 @@ var SshExecutor = class _SshExecutor {
794
795
  onLog?.(logEntry("Packing source into a single archive..."));
795
796
  await packLocalArchive(tarArgs, localArchive);
796
797
  const totalBytes = (await stat(localArchive)).size;
797
- await this.exec(`mkdir -p ${sq(dirname(remoteArchive))}`);
798
+ await this.exec(`mkdir -p ${sq(remoteDirname(remoteArchive))}`);
798
799
  const rsync = await canUseRemoteRsync(deps);
799
800
  if (rsync.ok) {
800
801
  onLog?.(logEntry(`Uploading ${formatBytes(totalBytes)} archive via rsync (resumable)...`));
@@ -920,7 +921,7 @@ import { once } from "events";
920
921
  import { mkdtemp as mkdtemp3, rm as fsRm3, stat as stat2, unlink } from "fs/promises";
921
922
  import { connect as netConnect } from "net";
922
923
  import { tmpdir as tmpdir3 } from "os";
923
- import { dirname as dirname2, join as join3 } from "path";
924
+ import { join as join3, posix as posix2 } from "path";
924
925
  import { Duplex } from "stream";
925
926
  import { promisify as promisify2 } from "util";
926
927
  import { randomBytes as randomBytes2 } from "crypto";
@@ -1028,6 +1029,7 @@ async function openSystemSshReverseTunnel(opts) {
1028
1029
 
1029
1030
  // ../../packages/adapters/src/system/system-ssh-executor.ts
1030
1031
  var execFileAsync2 = promisify2(execFile2);
1032
+ var remoteDirname2 = posix2.dirname;
1031
1033
  function clampWindow2(value, fallback, min, max) {
1032
1034
  if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
1033
1035
  return Math.max(min, Math.min(max, Math.floor(value)));
@@ -1219,7 +1221,7 @@ var SystemSshExecutor = class _SystemSshExecutor {
1219
1221
  });
1220
1222
  }
1221
1223
  async writeFile(path, content) {
1222
- const remoteCommand = `mkdir -p ${sq(dirname2(path))} && cat > ${sq(path)}`;
1224
+ const remoteCommand = `mkdir -p ${sq(remoteDirname2(path))} && cat > ${sq(path)}`;
1223
1225
  const res = await this.runSsh(remoteCommand, { input: content });
1224
1226
  if (res.code !== 0) {
1225
1227
  throw new Error(res.stderr.trim() || `Failed to write ${path} (exit ${res.code})`);
@@ -1290,7 +1292,7 @@ var SystemSshExecutor = class _SystemSshExecutor {
1290
1292
  onLog?.(logEntry("Packing source into a single archive..."));
1291
1293
  await packLocalArchive(tarArgs, localArchive);
1292
1294
  const totalBytes = (await stat2(localArchive)).size;
1293
- await this.exec(`mkdir -p ${sq(dirname2(remoteArchive))}`);
1295
+ await this.exec(`mkdir -p ${sq(remoteDirname2(remoteArchive))}`);
1294
1296
  const rsync = await canUseRemoteRsync(deps);
1295
1297
  if (rsync.ok) {
1296
1298
  onLog?.(logEntry(`Uploading ${formatBytes(totalBytes)} archive via rsync (resumable)...`));
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  decorateServiceException,
7
7
  normalizeProvider as normalizeProvider2,
8
8
  setCredentialFeature
9
- } from "./chunk-VWPEKOH6.js";
9
+ } from "./chunk-DRK3MEDS.js";
10
10
  import {
11
11
  HttpRequest,
12
12
  HttpResponse,
@@ -17,14 +17,14 @@ import {
17
17
  getSmithyContext,
18
18
  normalizeProvider,
19
19
  toEndpointV1
20
- } from "./chunk-W73X43R7.js";
20
+ } from "./chunk-3NQQXMDR.js";
21
21
  import {
22
22
  fromHex,
23
23
  fromUtf8,
24
24
  isArrayBuffer,
25
25
  toHex,
26
26
  toUint8Array
27
- } from "./chunk-JYGD5WSN.js";
27
+ } from "./chunk-ZWLDLTJP.js";
28
28
 
29
29
  // ../../node_modules/@smithy/core/dist-es/submodules/schema/schemas/operation.js
30
30
  var operation = (namespace, name, traits, input, output) => ({
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
@@ -17,11 +17,11 @@ import {
17
17
  loadConfig,
18
18
  normalizeProvider,
19
19
  toEndpointV1
20
- } from "./chunk-W73X43R7.js";
20
+ } from "./chunk-3NQQXMDR.js";
21
21
  import {
22
22
  parseRfc7231DateTime,
23
23
  v4
24
- } from "./chunk-JYGD5WSN.js";
24
+ } from "./chunk-ZWLDLTJP.js";
25
25
 
26
26
  // ../../node_modules/@smithy/core/dist-es/submodules/client/middleware-stack/MiddlewareStack.js
27
27
  var getAllAliases = (name, aliases) => {
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
@@ -7,18 +7,18 @@ import {
7
7
  localGitSshWriter,
8
8
  materializeGitSsh,
9
9
  sq
10
- } from "./chunk-4Z5QO7N6.js";
10
+ } from "./chunk-VDDMADOF.js";
11
11
  import {
12
12
  getTarCreateEnv,
13
13
  prepareSourceTarArgs
14
- } from "./chunk-OXWDY22G.js";
14
+ } from "./chunk-6ODUBKUB.js";
15
15
  import {
16
16
  packageManagerEnsureCommand
17
- } from "./chunk-6APULWSU.js";
17
+ } from "./chunk-OTLSJYAC.js";
18
18
  import {
19
19
  __commonJS,
20
20
  __toESM
21
- } from "./chunk-KI2EY3WB.js";
21
+ } from "./chunk-PXKCZB2I.js";
22
22
 
23
23
  // ../../node_modules/ignore/index.js
24
24
  var require_ignore = __commonJS({
@@ -690,66 +690,115 @@ function workspacePrepareRunLine(config, envPrefix, workspacePrepare) {
690
690
  const body = pmEnsure ? `${pmEnsure} && ${workspacePrepare}` : workspacePrepare;
691
691
  return `RUN ${envPrefix}${body}`;
692
692
  }
693
- function installBuildRunLine(config, envPrefix) {
693
+ function stepsRunLine(config, envPrefix, opts) {
694
+ const install = opts.install ? config.installCommand : "";
695
+ const build = opts.build ? config.buildCommand : "";
694
696
  const steps = [];
695
- const pmEnsure = packageManagerEnsureCommand(config.packageManager);
696
- if (pmEnsure && (config.installCommand || config.buildCommand)) {
697
+ const pmEnsure = packageManagerEnsureCommand(opts.packageManager ?? config.packageManager);
698
+ if (pmEnsure && (install || build)) {
697
699
  steps.push(pmEnsure);
698
700
  }
699
- if (config.installCommand) {
701
+ if (install) {
700
702
  steps.push(`printf '${formatDockerBuildEvent("install", "running")}\\n'`);
701
- steps.push(buildRunCommand(config.installCommand, envPrefix));
703
+ steps.push(buildRunCommand(install, envPrefix));
702
704
  steps.push(`printf '${formatDockerBuildEvent("install", "completed")}\\n'`);
703
705
  }
704
- if (config.buildCommand) {
706
+ if (build) {
705
707
  steps.push(`printf '${formatDockerBuildEvent("build", "running")}\\n'`);
706
- steps.push(buildRunCommand(config.buildCommand, envPrefix));
708
+ steps.push(buildRunCommand(build, envPrefix));
707
709
  steps.push(`printf '${formatDockerBuildEvent("build", "completed")}\\n'`);
708
710
  }
709
711
  return steps.length > 0 ? `RUN ${steps.join(" && ")}` : null;
710
712
  }
713
+ function installBuildRunLine(config, envPrefix) {
714
+ return stepsRunLine(config, envPrefix, { install: true, build: true });
715
+ }
716
+ function installRunLine(config, envPrefix) {
717
+ return stepsRunLine(config, envPrefix, { install: true });
718
+ }
719
+ var JS_PACKAGE_MANAGERS = ["pnpm", "yarn", "bun", "npm"];
720
+ function buildOnlyRunLine(config, envPrefix) {
721
+ const command = config.buildCommand?.trim() ?? "";
722
+ const packageManager = JS_PACKAGE_MANAGERS.find(
723
+ (pm) => new RegExp(`(^|\\s|&&\\s*)${pm}\\s`).test(command)
724
+ );
725
+ return stepsRunLine(config, envPrefix, { build: true, packageManager });
726
+ }
711
727
  function isPhpRuntime(config) {
712
- return /^php:/.test(config.runtimeImage);
728
+ return /^php:/.test(config.runtimeImage) || /frankenphp/i.test(config.runtimeImage);
713
729
  }
714
- var PHP_NGINX_TEMPLATE_LINES = [
715
- "server {",
716
- " listen ${PORT} default_server;",
717
- " root /app/public;",
718
- " index index.php index.html;",
719
- " location / { try_files $uri $uri/ /index.php?$query_string; }",
720
- " location ~ \\.php$ {",
721
- " fastcgi_pass 127.0.0.1:9000;",
722
- " fastcgi_index index.php;",
723
- " include fastcgi_params;",
724
- " fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;",
725
- " }",
726
- "}"
730
+ var PHP_EXTENSIONS = [
731
+ "pdo_mysql",
732
+ "pdo_pgsql",
733
+ "redis",
734
+ "pcntl",
735
+ "bcmath",
736
+ "intl",
737
+ "zip",
738
+ "gd",
739
+ "opcache"
727
740
  ];
741
+ var PHP_EXT_INSTALLER_IMAGE = "mlocati/php-extension-installer:2";
742
+ var PHP_ASSET_BUILD_IMAGE = "node:22-bookworm-slim";
743
+ var PHP_EXT_INSTALL_LINE = `RUN install-php-extensions ${PHP_EXTENSIONS.join(" ")} > /dev/null`;
728
744
  function generatePhpDockerfile(config) {
729
745
  const sourceDir = builderSourceDir(
730
746
  normalizeDockerRootDirectory(config.rootDirectory, config.localPath)
731
747
  );
732
748
  const envPrefix = buildEnvPrefix(config.envVars);
733
- const stepsLine = installBuildRunLine(config, envPrefix);
734
- const nginxTemplate = PHP_NGINX_TEMPLATE_LINES.map((line) => `'${line}'`).join(" ");
749
+ const installLine = installRunLine(config, envPrefix);
750
+ const assetBuildLine = buildOnlyRunLine(config, envPrefix);
735
751
  const lines = [
736
752
  `FROM ${config.buildImage} AS builder`,
737
- `WORKDIR /workspace`,
738
- `COPY . /workspace`,
739
753
  // php:*-cli ships no Composer — pull the binary from the official image.
740
754
  `COPY --from=composer:2 /usr/bin/composer /usr/bin/composer`,
741
- // pdo_mysql is the common denominator (Laravel/Symfony + MySQL/MariaDB);
742
- // app-specific extensions are a per-project follow-on.
743
- `RUN docker-php-ext-install pdo_mysql > /dev/null`,
755
+ `COPY --from=${PHP_EXT_INSTALLER_IMAGE} /usr/bin/install-php-extensions /usr/bin/install-php-extensions`,
756
+ PHP_EXT_INSTALL_LINE,
757
+ `WORKDIR /workspace`,
758
+ `COPY . /workspace`,
744
759
  `WORKDIR ${sourceDir}`
745
760
  ];
746
- if (stepsLine) lines.push(stepsLine);
761
+ if (installLine) lines.push(installLine);
762
+ if (assetBuildLine) {
763
+ lines.push(
764
+ `FROM ${PHP_ASSET_BUILD_IMAGE} AS assets`,
765
+ `WORKDIR /workspace`,
766
+ `COPY . /workspace`,
767
+ `WORKDIR ${sourceDir}`,
768
+ assetBuildLine
769
+ );
770
+ }
771
+ const docroot = normalizeRelativePath(config.outputDirectory) || "public";
747
772
  lines.push(
748
773
  `FROM ${config.runtimeImage} AS runtime`,
749
- `RUN apt-get update && apt-get install -y --no-install-recommends nginx gettext-base && rm -rf /var/lib/apt/lists/* && rm -f /etc/nginx/sites-enabled/default && docker-php-ext-install pdo_mysql > /dev/null`,
750
- `COPY --from=builder ${sourceDir} /app`,
774
+ PHP_EXT_INSTALL_LINE,
775
+ // --chown on the COPY instead of a trailing `chown -R`: the recursive form
776
+ // rewrites every file into a second layer, doubling the app's size on disk.
777
+ // Ownership has to be settled HERE, before anything mounts: Docker seeds a
778
+ // fresh named volume from the image directory it covers, ownership included,
779
+ // so `/app/storage` is only writable by the runtime user if it was already
780
+ // owned by them in the image (see @repo/core volumes.ts).
781
+ `COPY --from=builder --chown=www-data:www-data ${sourceDir} /app`
782
+ );
783
+ if (assetBuildLine) {
784
+ lines.push(
785
+ `COPY --from=assets --chown=www-data:www-data ${sourceDir}/${docroot} /app/${docroot}`
786
+ );
787
+ }
788
+ lines.push(
751
789
  `WORKDIR /app`,
752
- `RUN printf '%s\\n' ${nginxTemplate} > /etc/nginx/app.conf.template`,
790
+ // FrankenPHP's bundled Caddyfile reads the docroot from SERVER_ROOT (default
791
+ // `public/`, resolved against WORKDIR). Setting it keeps the project's
792
+ // outputDirectory authoritative for BOTH what gets served and where the asset
793
+ // stage's output lands — otherwise a project that renamed its docroot builds
794
+ // assets into one directory and serves another.
795
+ `ENV SERVER_ROOT=${docroot}/`,
796
+ // Caddy's config + data dirs are root-owned in the base image, and it writes
797
+ // to both on startup — without this the non-root switch below fails at boot.
798
+ `RUN mkdir -p /data/caddy /config/caddy && chown -R www-data:www-data /data/caddy /config/caddy`,
799
+ // The frankenphp binary carries cap_net_bind_service, so dropping root here
800
+ // still leaves any port bindable.
801
+ `USER www-data`,
753
802
  `EXPOSE ${config.port}`
754
803
  );
755
804
  if (config.startCommand) {
@@ -914,23 +963,45 @@ var GENERATED_DOCKERFILE_NAME = "Dockerfile.openship";
914
963
  function toPosixPath2(value) {
915
964
  return value.split(sep2).filter(Boolean).join("/");
916
965
  }
966
+ function anchorDockerignorePattern(line) {
967
+ const trimmed = line.trim();
968
+ if (!trimmed || trimmed.startsWith("#")) return line;
969
+ const negated = trimmed.startsWith("!");
970
+ const pattern = negated ? trimmed.slice(1) : trimmed;
971
+ if (!pattern || pattern.startsWith("/") || pattern.startsWith("**/")) return line;
972
+ if (pattern.replace(/\/+$/, "").includes("/")) return line;
973
+ return `${negated ? "!" : ""}/${pattern}`;
974
+ }
917
975
  async function loadDockerignoreMatcher(rootPath) {
918
976
  try {
919
- return (0, import_ignore.default)().add(await readFile(join2(rootPath, ".dockerignore"), "utf-8"));
977
+ const contents = await readFile(join2(rootPath, ".dockerignore"), "utf-8");
978
+ return (0, import_ignore.default)().add(contents.split(/\r?\n/).map(anchorDockerignorePattern));
920
979
  } catch {
921
980
  return void 0;
922
981
  }
923
982
  }
924
- async function applyDockerignore(contextDir) {
983
+ function buildFilePaths(config) {
984
+ const paths = /* @__PURE__ */ new Set([".dockerignore"]);
985
+ const candidates = resolveDockerfileCandidates(config.rootDirectory, config.dockerfilePath);
986
+ for (const candidate of candidates) {
987
+ const segments = candidate.split("/");
988
+ for (let depth = 1; depth <= segments.length; depth += 1) {
989
+ paths.add(segments.slice(0, depth).join("/"));
990
+ }
991
+ }
992
+ return paths;
993
+ }
994
+ async function applyDockerignore(contextDir, config) {
925
995
  const matcher = await loadDockerignoreMatcher(contextDir);
926
996
  if (!matcher) return;
997
+ const buildFiles = buildFilePaths(config);
927
998
  const prune = async (currentPath) => {
928
999
  const entries = await readdir2(currentPath, { withFileTypes: true });
929
1000
  await Promise.all(
930
1001
  entries.map(async (entry) => {
931
1002
  const absolutePath = join2(currentPath, entry.name);
932
- const relativePath = relative2(contextDir, absolutePath);
933
- if (matcher.ignores(toPosixPath2(relativePath))) {
1003
+ const relativePath = toPosixPath2(relative2(contextDir, absolutePath));
1004
+ if (!buildFiles.has(relativePath) && matcher.ignores(relativePath)) {
934
1005
  await rm(absolutePath, { recursive: true, force: true });
935
1006
  return;
936
1007
  }
@@ -947,15 +1018,22 @@ async function materializeLocalSource(sourcePath, targetPath) {
947
1018
  const create = spawn("tar", args, { env: getTarCreateEnv() });
948
1019
  const extract = spawn("tar", ["-xzf", "-", "-C", targetPath]);
949
1020
  let err = "";
950
- create.stderr.on("data", (d) => err += d.toString());
1021
+ let createErr = "";
1022
+ let createCode = null;
1023
+ create.stderr.on("data", (d) => createErr += d.toString());
951
1024
  extract.stderr.on("data", (d) => err += d.toString());
952
1025
  create.on("error", reject);
953
1026
  extract.on("error", reject);
1027
+ create.on("close", (code) => createCode = code);
954
1028
  create.stdout.pipe(extract.stdin);
955
- extract.on(
956
- "close",
957
- (code) => code === 0 ? resolve() : reject(new Error(`context materialize failed (tar ${code}): ${err.trim().slice(-500)}`))
958
- );
1029
+ extract.on("close", (code) => {
1030
+ if (code === 0 && (createCode ?? 0) === 0) return resolve();
1031
+ const parts = [
1032
+ createCode ? `pack exited ${createCode}: ${createErr.trim().slice(-500)}` : "",
1033
+ code ? `extract exited ${code}: ${err.trim().slice(-500)}` : ""
1034
+ ].filter(Boolean);
1035
+ reject(new Error(`context materialize failed (${parts.join(" | ")})`));
1036
+ });
959
1037
  });
960
1038
  } finally {
961
1039
  await cleanup();
@@ -1021,7 +1099,7 @@ async function prepareSourceTree(config, opts) {
1021
1099
  } else {
1022
1100
  await cloneGitSource(config, contextDir, opts?.onLog);
1023
1101
  }
1024
- await applyDockerignore(contextDir);
1102
+ await applyDockerignore(contextDir, config);
1025
1103
  return {
1026
1104
  contextDir,
1027
1105
  cleanup: async () => {
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env sh
2
- ":" //# ; exec "$(command -v bun || command -v node)" "$0" "$@"
2
+ ":" //# ; exec "$(command -v node || command -v bun)" "$0" "$@"
3
3
  import { createRequire as __ospCreateRequire } from "node:module";
4
4
  const require = __ospCreateRequire(import.meta.url);
5
5
  import {
6
6
  COMPONENT_INSTALLERS,
7
7
  checkAll,
8
8
  checkComponents
9
- } from "./chunk-SLTYVHU7.js";
9
+ } from "./chunk-GUQ3QCJ7.js";
10
10
 
11
11
  // ../../packages/adapters/src/system/state.ts
12
12
  var DEFAULT_STATE_PATH = "/etc/openship/setup-state.json";