openxiangda-devkit-core 2.26.0 → 2.27.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.
@@ -1,5 +1,6 @@
1
1
  import { runCommandProcess } from './command-process.js';
2
2
  import { uploadBackendOciLayout } from './backend-image-upload.js';
3
+ import { withBackendImageCandidate } from './backend-image-candidate.js';
3
4
  import { existsSync, mkdtempSync, readFileSync, rmSync, } from "node:fs";
4
5
  import { tmpdir } from "node:os";
5
6
  import { isAbsolute, join, relative, resolve } from "node:path";
@@ -129,20 +130,21 @@ export async function publishBackendImage(input) {
129
130
  throw new BackendImageBuildError("OPENXIANGDA_DOCKERIGNORE_MISSING", "工作区缺少模板 .dockerignore,拒绝上传未受约束的构建上下文");
130
131
  }
131
132
  const docker = input.dockerExecutable || "docker";
132
- const version = await runDocker(docker, ["buildx", "version"], root);
133
- if (version.error?.code === "ENOENT") {
134
- throw new BackendImageBuildError("OPENXIANGDA_DOCKER_REQUIRED", "未找到 Docker CLI,请安装并启动 Docker Desktop");
135
- }
136
- if (version.error || version.status !== 0) {
137
- throw new BackendImageBuildError("OPENXIANGDA_DOCKER_BUILDX_REQUIRED", "当前 Docker CLI 未提供可用的 Buildx");
138
- }
133
+ const assertBuilder = async () => {
134
+ const version = await runDocker(docker, ["buildx", "version"], root);
135
+ if (version.error?.code === "ENOENT") {
136
+ throw new BackendImageBuildError("OPENXIANGDA_DOCKER_REQUIRED", "未找到 Docker CLI,请安装并启动 Docker Desktop");
137
+ }
138
+ if (version.error || version.status !== 0) {
139
+ throw new BackendImageBuildError("OPENXIANGDA_DOCKER_BUILDX_REQUIRED", "当前 Docker CLI 未提供可用的 Buildx");
140
+ }
141
+ };
139
142
  if (input.target.upload) {
140
143
  if (!input.uploader) {
141
144
  throw new BackendImageBuildError('OPENXIANGDA_BACKEND_IMAGE_UPLOADER_REQUIRED', '缺少平台登录态镜像上传通道');
142
145
  }
143
- const scratch = mkdtempSync(join(tmpdir(), 'openxiangda-oci-'));
144
- const directory = join(scratch, 'image');
145
- try {
146
+ const build = async (directory) => {
147
+ await assertBuilder();
146
148
  const built = await runDocker(docker, ['buildx', 'build', '--file', dockerfile,
147
149
  '--platform', input.target.platform, '--provenance=false', '--sbom=false',
148
150
  '--tag', input.target.repository,
@@ -156,13 +158,32 @@ export async function publishBackendImage(input) {
156
158
  }
157
159
  throw new BackendImageBuildError('OPENXIANGDA_BACKEND_IMAGE_BUILD_FAILED', '本地后端镜像构建失败');
158
160
  }
159
- const uploaded = await uploadBackendOciLayout({ directory, ...input.target.upload, uploader: input.uploader });
161
+ };
162
+ const upload = async (directory, expectedDigest, assertOwnership) => {
163
+ const uploaded = await uploadBackendOciLayout({ directory, ...input.target.upload, uploader: input.uploader,
164
+ ...(expectedDigest ? { expectedDigest } : {}), ...(assertOwnership ? { assertOwnership } : {}) });
160
165
  return { repository: uploaded.reference.split('@')[0], platform: input.target.platform, ...uploaded };
166
+ };
167
+ // Local recovery capacity must not lower the platform's accepted image limit.
168
+ if (input.recoveryScope && input.target.upload.maxImageBytes <= 8 * 1024 ** 3) {
169
+ if (input.recoveryScope.appCode !== input.target.upload.appCode) {
170
+ throw new BackendImageBuildError('OPENXIANGDA_BACKEND_IMAGE_RECOVERY_SCOPE_INVALID', '恢复应用与上传目标不一致');
171
+ }
172
+ return withBackendImageCandidate({ root, dockerfile, scope: input.recoveryScope,
173
+ maxImageBytes: input.target.upload.maxImageBytes,
174
+ ...(input.candidateCacheRoot ? { cacheRoot: input.candidateCacheRoot } : {}), build, upload });
175
+ }
176
+ const scratch = mkdtempSync(join(tmpdir(), 'openxiangda-oci-'));
177
+ const directory = join(scratch, 'image');
178
+ try {
179
+ await build(directory);
180
+ return await upload(directory);
161
181
  }
162
182
  finally {
163
183
  rmSync(scratch, { recursive: true, force: true });
164
184
  }
165
185
  }
186
+ await assertBuilder();
166
187
  const scratch = mkdtempSync(join(tmpdir(), "openxiangda-buildx-"));
167
188
  const metadataFile = join(scratch, "metadata.json");
168
189
  const revision = String(input.sourceRevision || "").toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"file":"backend-image-build.js","sourceRoot":"","sources":["../src/backend-image-build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAA6B,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EACL,UAAU,EACV,WAAW,EACX,YAAY,EACZ,MAAM,GACP,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AACzC,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAC1C,MAAM,8BAA8B,GAAG,CAAC,CAAC;AACzC,MAAM,qCAAqC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAU,CAAC;AAClE,MAAM,oBAAoB,GAAG,2CAA2C,CAAC;AACzE,MAAM,gBAAgB,GAAG,mCAAmC,CAAC;AAC7D,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAiB9C,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAEpC;IAEA;IAHX,YACW,IAAY,EACrB,OAAe,EACN,YAAY,KAAK;QAE1B,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QAJpB,SAAI,GAAJ,IAAI,CAAQ;QAEZ,cAAS,GAAT,SAAS,CAAQ;QAG1B,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,UAAU,uBAAuB,CACrC,YAAkC,EAClC,OAAe;IAEf,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,EAAE,kBAAkB,CAAC;IAC3D,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,MAAM,CAAC,aAAa,KAAK,qCAAqC,IAAI,MAAM,CAAC,KAAK,KAAK,UAAU;YAC/F,MAAM,CAAC,QAAQ,KAAK,aAAa,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY;YACnE,MAAM,CAAC,gBAAgB,KAAK,2DAA2D;YACvF,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC;YACvE,MAAM,CAAC,aAAa,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;YACtH,MAAM,IAAI,sBAAsB,CAAC,gDAAgD,EAAE,YAAY,CAAC,CAAC;QACnG,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,sBAAsB,CAAC,8CAA8C,EAAE,qBAAqB,CAAC,CAAC;QAC1G,CAAC;QACD,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,sBAAsB,CAAC,4CAA4C,EAAE,QAAQ,CAAC,CAAC;QAC3F,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,qBAAqB,OAAO,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACnF,MAAM,EAAE;gBACN,OAAO;gBACP,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACzE,EAAE,CAAC;IACR,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACzD,IACE,CAAC,KAAK;QACN,KAAK,CAAC,KAAK,KAAK,eAAe;QAC/B,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS;QACpC,KAAK,CAAC,QAAQ,KAAK,aAAa,EAChC,CAAC;QACD,MAAM,IAAI,sBAAsB,CAC9B,gDAAgD,EAChD,oBAAoB,CACrB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,sBAAsB,CAC9B,6CAA6C,EAC7C,kCAAkC,CACnC,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,CAAC;IACtC,IACE,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,CAAC,IAAI,EAAE,KAAK,MAAM;QACxB,CAAC,wBAAwB,CAAC,MAAM,CAAC,EACjC,CAAC;QACD,MAAM,IAAI,sBAAsB,CAC9B,8CAA8C,EAC9C,oDAAoD,CACrD,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,sBAAsB,CAC9B,4CAA4C,EAC5C,gBAAgB,CACjB,CAAC;IACJ,CAAC;IACD,OAAO;QACL,UAAU,EAAE,GAAG,MAAM,IAAI,OAAO,SAAS;QACzC,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAa;IAC7C,IACE,CAAC,KAAK;QACN,KAAK,CAAC,MAAM,GAAG,4BAA4B;QAC3C,KAAK,KAAK,KAAK,CAAC,WAAW,EAAE;QAC7B,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QACrB,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EACxB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IACE,QAAQ,CAAC,MAAM,GAAG,8BAA8B;QAChD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI,CAAC,EACzE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,GAAG,QAAQ,CAAC;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,gBAAgB,GACpB,KAAK,KAAK,WAAW;QACrB,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QACnB,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QACnB,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,gBAAgB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5D,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnE,OAAO,kBAAkB,CAAC,KAAK,CAC7B,OAAO,CAAC,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CACxE,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,kCAAkC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7D,OAAO,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,KAAK,GAAG,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;IACvB,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,SAAS,CAAC,KAAyB;IAC1C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAOzC;IACC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAClE,MAAM,kBAAkB,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACtD,IACE,CAAC,kBAAkB;QACnB,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC;QACnC,UAAU,CAAC,kBAAkB,CAAC,EAC9B,CAAC;QACD,MAAM,IAAI,sBAAsB,CAC9B,kDAAkD,EAClD,0BAA0B,CAC3B,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,sBAAsB,CAC9B,wCAAwC,EACxC,wBAAwB,kBAAkB,EAAE,CAC7C,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,sBAAsB,CAC9B,kCAAkC,EAClC,sCAAsC,CACvC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,IAAI,QAAQ,CAAC;IAClD,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;IACrE,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,IAAI,sBAAsB,CAC9B,6BAA6B,EAC7B,sCAAsC,CACvC,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,sBAAsB,CAC9B,oCAAoC,EACpC,6BAA6B,CAC9B,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,IAAI,sBAAsB,CAAC,6CAA6C,EAAE,eAAe,CAAC,CAAC;QACnG,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU;gBAC5E,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,oBAAoB,EAAE,cAAc;gBACzE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU;gBAChC,UAAU,EAAE,iBAAiB,SAAS,YAAY,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtC,IAAI,6DAA6D,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBACrF,MAAM,IAAI,sBAAsB,CAAC,wCAAwC,EACvE,uIAAuI,CAAC,CAAC;gBAC7I,CAAC;gBACD,IAAI,oEAAoE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC5F,MAAM,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACnC,CAAC;gBACD,MAAM,IAAI,sBAAsB,CAAC,wCAAwC,EAAE,YAAY,CAAC,CAAC;YAC3F,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC/G,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;QACzG,CAAC;gBAAS,CAAC;YAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;IAClE,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAClE,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC;QACjD,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACvB,CAAC,CAAC,OAAO,CAAC;IACZ,MAAM,GAAG,GAAG,OAAO,SAAS,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC3D,IAAI,CAAC;QACH,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,8BAA8B,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YAC9E,MAAM,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACtC,MAAM,KAAK,GAAG,MAAM,SAAS,CAC3B,MAAM,EACN;gBACE,QAAQ;gBACR,OAAO;gBACP,QAAQ;gBACR,UAAU;gBACV,YAAY;gBACZ,KAAK,CAAC,MAAM,CAAC,QAAQ;gBACrB,oBAAoB;gBACpB,OAAO;gBACP,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,EAAE;gBACnC,iBAAiB;gBACjB,YAAY;gBACZ,QAAQ;gBACR,IAAI;aACL,EACD,IAAI,CACL,CAAC;YACF,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,MAAM,IAAI,sBAAsB,CAC9B,6BAA6B,EAC7B,sCAAsC,CACvC,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM;YAE9C,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3C,IACE,OAAO,CAAC,IAAI,KAAK,uCAAuC;gBACxD,OAAO,KAAK,8BAA8B,EAC1C,CAAC;gBACD,IACE,OAAO,CAAC,IAAI,KAAK,uCAAuC;oBACxD,OAAO,KAAK,8BAA8B,EAC1C,CAAC;oBACD,MAAM,IAAI,sBAAsB,CAC9B,OAAO,CAAC,IAAI,EACZ,eAAe,8BAA8B,YAAY,EACzD,IAAI,CACL,CAAC;gBACJ,CAAC;gBACD,MAAM,OAAO,CAAC;YAChB,CAAC;YACD,MAAM,IAAI,CAAC,qCAAqC,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,QAAiC,CAAC;QACtC,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,sBAAsB,CAC9B,0CAA0C,EAC1C,mCAAmC,CACpC,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7E,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,sBAAsB,CAC9B,0CAA0C,EAC1C,oCAAoC,CACrC,CAAC;QACJ,CAAC;QACD,OAAO;YACL,GAAG,KAAK,CAAC,MAAM;YACf,MAAM;YACN,SAAS,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,EAAE;SAClD,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,UAAkB,EAAE,IAAc,EAAE,GAAW;IACtE,MAAM,WAAW,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACvC,OAAO,WAAW,CAAC,iBAAiB,CAAC;IACrC,OAAO,WAAW,CAAC,yBAAyB,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IACpF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAA0C;QACxD,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,IAAI,CAAC,OAAe;IAC3B,OAAO,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,YAAY,CAAC,MAAc;IAClC,IAAI,oEAAoE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtF,OAAO,IAAI,sBAAsB,CAC/B,uCAAuC,EACvC,0CAA0C,EAC1C,IAAI,CACL,CAAC;IACJ,CAAC;IACD,IAAI,wEAAwE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1F,OAAO,IAAI,sBAAsB,CAC/B,oCAAoC,EACpC,6CAA6C,CAC9C,CAAC;IACJ,CAAC;IACD,IACE,0KAA0K,CAAC,IAAI,CAC7K,MAAM,CACP,EACD,CAAC;QACD,OAAO,IAAI,sBAAsB,CAC/B,uCAAuC,EACvC,mBAAmB,EACnB,IAAI,CACL,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,sBAAsB,CAC/B,wCAAwC,EACxC,4CAA4C,CAC7C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"backend-image-build.js","sourceRoot":"","sources":["../src/backend-image-build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAA6B,MAAM,2BAA2B,CAAC;AAC9F,OAAO,EAAE,yBAAyB,EAAkC,MAAM,8BAA8B,CAAC;AACzG,OAAO,EACL,UAAU,EACV,WAAW,EACX,YAAY,EACZ,MAAM,GACP,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AACzC,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAC1C,MAAM,8BAA8B,GAAG,CAAC,CAAC;AACzC,MAAM,qCAAqC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAU,CAAC;AAClE,MAAM,oBAAoB,GAAG,2CAA2C,CAAC;AACzE,MAAM,gBAAgB,GAAG,mCAAmC,CAAC;AAC7D,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAiB9C,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAEpC;IAEA;IAHX,YACW,IAAY,EACrB,OAAe,EACN,YAAY,KAAK;QAE1B,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QAJpB,SAAI,GAAJ,IAAI,CAAQ;QAEZ,cAAS,GAAT,SAAS,CAAQ;QAG1B,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,UAAU,uBAAuB,CACrC,YAAkC,EAClC,OAAe;IAEf,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,EAAE,kBAAkB,CAAC;IAC3D,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,MAAM,CAAC,aAAa,KAAK,qCAAqC,IAAI,MAAM,CAAC,KAAK,KAAK,UAAU;YAC/F,MAAM,CAAC,QAAQ,KAAK,aAAa,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY;YACnE,MAAM,CAAC,gBAAgB,KAAK,2DAA2D;YACvF,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC;YACvE,MAAM,CAAC,aAAa,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;YACtH,MAAM,IAAI,sBAAsB,CAAC,gDAAgD,EAAE,YAAY,CAAC,CAAC;QACnG,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,sBAAsB,CAAC,8CAA8C,EAAE,qBAAqB,CAAC,CAAC;QAC1G,CAAC;QACD,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,sBAAsB,CAAC,4CAA4C,EAAE,QAAQ,CAAC,CAAC;QAC3F,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,qBAAqB,OAAO,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACnF,MAAM,EAAE;gBACN,OAAO;gBACP,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACzE,EAAE,CAAC;IACR,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACzD,IACE,CAAC,KAAK;QACN,KAAK,CAAC,KAAK,KAAK,eAAe;QAC/B,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS;QACpC,KAAK,CAAC,QAAQ,KAAK,aAAa,EAChC,CAAC;QACD,MAAM,IAAI,sBAAsB,CAC9B,gDAAgD,EAChD,oBAAoB,CACrB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,sBAAsB,CAC9B,6CAA6C,EAC7C,kCAAkC,CACnC,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,CAAC;IACtC,IACE,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,CAAC,IAAI,EAAE,KAAK,MAAM;QACxB,CAAC,wBAAwB,CAAC,MAAM,CAAC,EACjC,CAAC;QACD,MAAM,IAAI,sBAAsB,CAC9B,8CAA8C,EAC9C,oDAAoD,CACrD,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,sBAAsB,CAC9B,4CAA4C,EAC5C,gBAAgB,CACjB,CAAC;IACJ,CAAC;IACD,OAAO;QACL,UAAU,EAAE,GAAG,MAAM,IAAI,OAAO,SAAS;QACzC,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAa;IAC7C,IACE,CAAC,KAAK;QACN,KAAK,CAAC,MAAM,GAAG,4BAA4B;QAC3C,KAAK,KAAK,KAAK,CAAC,WAAW,EAAE;QAC7B,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QACrB,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EACxB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IACE,QAAQ,CAAC,MAAM,GAAG,8BAA8B;QAChD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI,CAAC,EACzE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,GAAG,QAAQ,CAAC;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,gBAAgB,GACpB,KAAK,KAAK,WAAW;QACrB,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QACnB,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QACnB,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,gBAAgB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5D,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnE,OAAO,kBAAkB,CAAC,KAAK,CAC7B,OAAO,CAAC,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CACxE,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,kCAAkC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7D,OAAO,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,KAAK,GAAG,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;IACvB,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,SAAS,CAAC,KAAyB;IAC1C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAUzC;IACC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAClE,MAAM,kBAAkB,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACtD,IACE,CAAC,kBAAkB;QACnB,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC;QACnC,UAAU,CAAC,kBAAkB,CAAC,EAC9B,CAAC;QACD,MAAM,IAAI,sBAAsB,CAC9B,kDAAkD,EAClD,0BAA0B,CAC3B,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,sBAAsB,CAC9B,wCAAwC,EACxC,wBAAwB,kBAAkB,EAAE,CAC7C,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,sBAAsB,CAC9B,kCAAkC,EAClC,sCAAsC,CACvC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,gBAAgB,IAAI,QAAQ,CAAC;IAClD,MAAM,aAAa,GAAG,KAAK,IAAI,EAAE;QAC/B,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;QACrE,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,sBAAsB,CAC9B,6BAA6B,EAC7B,sCAAsC,CACvC,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,sBAAsB,CAC9B,oCAAoC,EACpC,6BAA6B,CAC9B,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,IAAI,sBAAsB,CAAC,6CAA6C,EAAE,eAAe,CAAC,CAAC;QACnG,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,EAAE,SAAiB,EAAE,EAAE;YACxC,MAAM,aAAa,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU;gBAC5E,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,oBAAoB,EAAE,cAAc;gBACzE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU;gBAChC,UAAU,EAAE,iBAAiB,SAAS,YAAY,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtC,IAAI,6DAA6D,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBACrF,MAAM,IAAI,sBAAsB,CAAC,wCAAwC,EACvE,uIAAuI,CAAC,CAAC;gBAC7I,CAAC;gBACD,IAAI,oEAAoE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC5F,MAAM,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACnC,CAAC;gBACD,MAAM,IAAI,sBAAsB,CAAC,wCAAwC,EAAE,YAAY,CAAC,CAAC;YAC3F,CAAC;QACH,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,KAAK,EAAE,SAAiB,EAAE,cAAuB,EAAE,eAA4B,EAAE,EAAE;YAChG,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,MAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAS;gBAC3G,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACpG,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;QACzG,CAAC,CAAC;QACF,8EAA8E;QAC9E,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;YAC9E,IAAI,KAAK,CAAC,aAAa,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAChE,MAAM,IAAI,sBAAsB,CAAC,kDAAkD,EAAE,cAAc,CAAC,CAAC;YACvG,CAAC;YACD,OAAO,yBAAyB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,aAAa;gBAC7E,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa;gBAChD,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACnG,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;YACvB,OAAO,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;gBAAS,CAAC;YAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;IAClE,CAAC;IAED,MAAM,aAAa,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAClE,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC;QACjD,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACvB,CAAC,CAAC,OAAO,CAAC;IACZ,MAAM,GAAG,GAAG,OAAO,SAAS,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC3D,IAAI,CAAC;QACH,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,8BAA8B,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YAC9E,MAAM,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACtC,MAAM,KAAK,GAAG,MAAM,SAAS,CAC3B,MAAM,EACN;gBACE,QAAQ;gBACR,OAAO;gBACP,QAAQ;gBACR,UAAU;gBACV,YAAY;gBACZ,KAAK,CAAC,MAAM,CAAC,QAAQ;gBACrB,oBAAoB;gBACpB,OAAO;gBACP,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,EAAE;gBACnC,iBAAiB;gBACjB,YAAY;gBACZ,QAAQ;gBACR,IAAI;aACL,EACD,IAAI,CACL,CAAC;YACF,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,MAAM,IAAI,sBAAsB,CAC9B,6BAA6B,EAC7B,sCAAsC,CACvC,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM;YAE9C,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC3C,IACE,OAAO,CAAC,IAAI,KAAK,uCAAuC;gBACxD,OAAO,KAAK,8BAA8B,EAC1C,CAAC;gBACD,IACE,OAAO,CAAC,IAAI,KAAK,uCAAuC;oBACxD,OAAO,KAAK,8BAA8B,EAC1C,CAAC;oBACD,MAAM,IAAI,sBAAsB,CAC9B,OAAO,CAAC,IAAI,EACZ,eAAe,8BAA8B,YAAY,EACzD,IAAI,CACL,CAAC;gBACJ,CAAC;gBACD,MAAM,OAAO,CAAC;YAChB,CAAC;YACD,MAAM,IAAI,CAAC,qCAAqC,CAAC,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,QAAiC,CAAC;QACtC,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,sBAAsB,CAC9B,0CAA0C,EAC1C,mCAAmC,CACpC,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7E,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,sBAAsB,CAC9B,0CAA0C,EAC1C,oCAAoC,CACrC,CAAC;QACJ,CAAC;QACD,OAAO;YACL,GAAG,KAAK,CAAC,MAAM;YACf,MAAM;YACN,SAAS,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,EAAE;SAClD,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,UAAkB,EAAE,IAAc,EAAE,GAAW;IACtE,MAAM,WAAW,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACvC,OAAO,WAAW,CAAC,iBAAiB,CAAC;IACrC,OAAO,WAAW,CAAC,yBAAyB,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IACpF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAA0C;QACxD,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,IAAI,CAAC,OAAe;IAC3B,OAAO,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,YAAY,CAAC,MAAc;IAClC,IAAI,oEAAoE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtF,OAAO,IAAI,sBAAsB,CAC/B,uCAAuC,EACvC,0CAA0C,EAC1C,IAAI,CACL,CAAC;IACJ,CAAC;IACD,IAAI,wEAAwE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1F,OAAO,IAAI,sBAAsB,CAC/B,oCAAoC,EACpC,6CAA6C,CAC9C,CAAC;IACJ,CAAC;IACD,IACE,0KAA0K,CAAC,IAAI,CAC7K,MAAM,CACP,EACD,CAAC;QACD,OAAO,IAAI,sBAAsB,CAC/B,uCAAuC,EACvC,mBAAmB,EACnB,IAAI,CACL,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,sBAAsB,CAC/B,wCAAwC,EACxC,4CAA4C,CAC7C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface BackendImageRecoveryScope {
2
+ platform: string;
3
+ tenantId: string;
4
+ userId: string;
5
+ appCode: string;
6
+ environmentKey: string;
7
+ environmentId?: string;
8
+ configurationDigest: string;
9
+ toolchainVersion: string;
10
+ }
11
+ export declare class BackendImageCandidateError extends Error {
12
+ readonly code: string;
13
+ readonly data: Record<string, unknown>;
14
+ readonly retryable: boolean;
15
+ constructor(code: string, message: string, data?: Record<string, unknown>, retryable?: boolean);
16
+ }
17
+ /** Hash the actual local Docker context, including dirty/untracked files; never use a commit as a cache key. */
18
+ export declare function backendImageContextDigest(root: string, dockerfile: string): Promise<string>;
19
+ export declare function withBackendImageCandidate<T>(input: {
20
+ root: string;
21
+ dockerfile: string;
22
+ scope: BackendImageRecoveryScope;
23
+ maxImageBytes: number;
24
+ /** @internal Temporary private directory for executable tests. */
25
+ cacheRoot?: string;
26
+ build: (directory: string) => Promise<void>;
27
+ upload: (directory: string, digest: string, assertOwnership: () => void) => Promise<T>;
28
+ }): Promise<T>;
29
+ //# sourceMappingURL=backend-image-candidate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-image-candidate.d.ts","sourceRoot":"","sources":["../src/backend-image-candidate.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAWD,qBAAa,0BAA2B,SAAQ,KAAK;IAEvC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAAmB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAD1F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;gBACP,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAW,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAAE,SAAS,UAAQ;CAKnH;AA8DD,gHAAgH;AAChH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDjG;AA4DD,wBAAsB,yBAAyB,CAAC,CAAC,EAAE,KAAK,EAAE;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,yBAAyB,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACxF,GAAG,OAAO,CAAC,CAAC,CAAC,CAiDb"}
@@ -0,0 +1,304 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { dirname, join, relative, resolve } from 'node:path';
5
+ import { createRequire } from 'node:module';
6
+ import { lock } from 'proper-lockfile';
7
+ import { inspectBackendOciLayout } from './backend-image-upload.js';
8
+ const SCHEMA = 'openxiangda.backend-image-candidate/v1';
9
+ const KEY = /^[a-f0-9]{64}$/;
10
+ const DIGEST = /^sha256:[a-f0-9]{64}$/;
11
+ const TTL = 24 * 60 * 60 * 1000;
12
+ const MAX_ENTRIES = 8;
13
+ const MAX_BYTES = 8 * 1024 ** 3;
14
+ const CANDIDATE_BYTES = MAX_BYTES;
15
+ const dockerignore = createRequire(import.meta.url)('@balena/dockerignore');
16
+ export class BackendImageCandidateError extends Error {
17
+ code;
18
+ data;
19
+ retryable;
20
+ constructor(code, message, data = {}, retryable = false) {
21
+ super(`${code}: ${message}`);
22
+ this.code = code;
23
+ this.data = data;
24
+ this.name = 'BackendImageCandidateError';
25
+ this.retryable = retryable;
26
+ }
27
+ }
28
+ function fail(code, message) {
29
+ throw new BackendImageCandidateError(`OPENXIANGDA_BACKEND_IMAGE_${code}`, message);
30
+ }
31
+ function privateDirectory(path, create = true) {
32
+ if (!existsSync(path)) {
33
+ if (!create)
34
+ fail('CACHE_INVALID', '镜像缓存目录无效');
35
+ const parent = dirname(path);
36
+ if (!existsSync(parent))
37
+ privateDirectory(parent);
38
+ try {
39
+ mkdirSync(path, { mode: 0o700 });
40
+ }
41
+ catch (error) {
42
+ if (error.code !== 'EEXIST')
43
+ throw error;
44
+ }
45
+ }
46
+ const stat = lstatSync(path);
47
+ if (stat.isSymbolicLink() || !stat.isDirectory() || (stat.mode & 0o077) !== 0 ||
48
+ (process.getuid && stat.uid !== process.getuid())) {
49
+ fail('CACHE_PATH_INVALID', '镜像缓存必须是当前用户的私有目录');
50
+ }
51
+ }
52
+ function readCandidate(directory, key) {
53
+ privateDirectory(directory, false);
54
+ const path = join(directory, 'candidate.json');
55
+ const stat = lstatSync(path);
56
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 4096 || (stat.mode & 0o077) !== 0) {
57
+ fail('CACHE_INVALID', '镜像缓存描述无效,未上传任何内容');
58
+ }
59
+ const x = JSON.parse(readFileSync(path, 'utf8'));
60
+ if (x.schemaVersion !== SCHEMA || x.key !== key || !KEY.test(x.key) ||
61
+ !Number.isSafeInteger(x.createdAt) || x.createdAt < 1 || x.createdAt > Date.now() + 60_000 ||
62
+ !Number.isSafeInteger(x.reservedBytes) || x.reservedBytes < 1 || x.reservedBytes > CANDIDATE_BYTES ||
63
+ !['building', 'sealed'].includes(x.state) ||
64
+ (x.state === 'sealed' && !DIGEST.test(String(x.digest))))
65
+ fail('CACHE_INVALID', '镜像缓存描述无效,未上传任何内容');
66
+ return x;
67
+ }
68
+ function saveCandidate(directory, candidate) {
69
+ const temporary = join(directory, `candidate-${randomUUID()}.tmp`);
70
+ writeFileSync(temporary, JSON.stringify(candidate), { mode: 0o600, flag: 'wx' });
71
+ renameSync(temporary, join(directory, 'candidate.json'));
72
+ }
73
+ async function lease(path, retries = 0) {
74
+ let compromised = false;
75
+ try {
76
+ const release = await lock(path, { realpath: false, stale: 300_000, update: 30_000,
77
+ retries: { retries, minTimeout: 50, maxTimeout: 250, randomize: true },
78
+ onCompromised: () => { compromised = true; } });
79
+ return {
80
+ assert: () => { if (compromised)
81
+ fail('CACHE_LEASE_LOST', '镜像缓存租约已失效,停止继续上传'); },
82
+ release: async () => { await release().catch(() => undefined); },
83
+ };
84
+ }
85
+ catch (error) {
86
+ if (error.code === 'ELOCKED') {
87
+ throw new BackendImageCandidateError('OPENXIANGDA_BACKEND_IMAGE_BUSY', '同一镜像候选正在使用,请等待原操作结束后重试', {}, true);
88
+ }
89
+ throw error;
90
+ }
91
+ }
92
+ /** Hash the actual local Docker context, including dirty/untracked files; never use a commit as a cache key. */
93
+ export async function backendImageContextDigest(root, dockerfile) {
94
+ const ignorePath = existsSync(`${dockerfile}.dockerignore`) ? `${dockerfile}.dockerignore` : join(root, '.dockerignore');
95
+ for (const path of [dockerfile, ignorePath]) {
96
+ const stat = lstatSync(path);
97
+ const real = realpathSync(path);
98
+ if (!stat.isFile() || stat.isSymbolicLink() || !(real === root || real.startsWith(`${root}/`)))
99
+ fail('CONTEXT_INVALID', 'Dockerfile 和 ignore 文件必须是工作区内的普通文件');
100
+ }
101
+ const rules = readFileSync(ignorePath, 'utf8');
102
+ if (Buffer.byteLength(rules) > 256 * 1024)
103
+ fail('CONTEXT_LIMIT', 'Docker ignore 文件超过 256 KiB');
104
+ const matcher = dockerignore({ ignorecase: false }).add(rules);
105
+ const exceptions = rules.split(/\r?\n/).map(line => line.trim()).filter(line => line.startsWith('!')).map(line => line.slice(1).replace(/^\/+|\/+$/g, ''));
106
+ // When an exclusion can re-include descendants we must walk the excluded parent.
107
+ const mayInclude = (path) => exceptions.some(pattern => {
108
+ if (pattern.includes('\\') || pattern.includes('..') || pattern.startsWith('./'))
109
+ return true;
110
+ const prefix = pattern.split(/[?*\[]/, 1)[0];
111
+ return !prefix || prefix.startsWith(`${path}/`) || `${path}/`.startsWith(prefix);
112
+ });
113
+ const hash = createHash('sha256');
114
+ hash.update(JSON.stringify([relative(root, dockerfile), relative(root, ignorePath), rules]));
115
+ let entries = 0;
116
+ let bytes = 0;
117
+ const deadline = Date.now() + 60_000;
118
+ const walk = async (directory) => {
119
+ for (const name of readdirSync(directory).sort()) {
120
+ if (++entries > 100_000 || Date.now() > deadline)
121
+ fail('CONTEXT_LIMIT', '构建上下文超过恢复校验预算,请缩小 .dockerignore 定义的构建上下文');
122
+ const path = join(directory, name);
123
+ const relativePath = relative(root, path).replaceAll('\\', '/');
124
+ const stat = lstatSync(path);
125
+ const included = path === dockerfile || path === ignorePath || !matcher.ignores(relativePath);
126
+ if (stat.isDirectory()) {
127
+ if (included)
128
+ hash.update(JSON.stringify(['d', relativePath, stat.mode & 0o777]));
129
+ if (included || mayInclude(relativePath) || dockerfile.startsWith(`${path}/`) || ignorePath.startsWith(`${path}/`))
130
+ await walk(path);
131
+ }
132
+ else if (included && stat.isSymbolicLink()) {
133
+ hash.update(JSON.stringify(['l', relativePath, readlinkSync(path)]));
134
+ }
135
+ else if (included && stat.isFile()) {
136
+ bytes += stat.size;
137
+ if (bytes > MAX_BYTES)
138
+ fail('CONTEXT_LIMIT', '构建上下文超过 8 GiB,无法安全绑定恢复候选');
139
+ hash.update(JSON.stringify(['f', relativePath, stat.mode & 0o777, stat.size]));
140
+ for await (const chunk of createReadStream(path)) {
141
+ if (Date.now() > deadline)
142
+ fail('CONTEXT_LIMIT', '构建上下文校验超时');
143
+ hash.update(chunk);
144
+ }
145
+ const after = lstatSync(path);
146
+ if (stat.ino !== after.ino || stat.size !== after.size || stat.mtimeMs !== after.mtimeMs)
147
+ fail('CONTEXT_CHANGED', '校验期间源码发生变化,请在保存完成后重试');
148
+ }
149
+ else if (included) {
150
+ fail('CONTEXT_INVALID', '构建上下文包含不受支持的设备或管道文件');
151
+ }
152
+ }
153
+ };
154
+ await walk(root);
155
+ return `sha256:${hash.digest('hex')}`;
156
+ }
157
+ async function acquireCandidate(cacheRoot, key, reservedBytes) {
158
+ privateDirectory(cacheRoot);
159
+ const global = await lease(join(cacheRoot, '.registry'), 8);
160
+ try {
161
+ const names = readdirSync(cacheRoot).filter(name => KEY.test(name));
162
+ if (names.length > 64)
163
+ fail('CACHE_LIMIT', '缓存目录超出安全扫描范围');
164
+ const candidates = names.map(name => ({ directory: join(cacheRoot, name), candidate: readCandidate(join(cacheRoot, name), name) }));
165
+ const existing = candidates.find(item => item.candidate.key === key);
166
+ // Locks live beside candidates, so removing candidate files never releases another process's lock.
167
+ const owned = await lease(join(cacheRoot, key));
168
+ try {
169
+ let selected = existing?.candidate;
170
+ if (selected && Date.now() - selected.createdAt >= TTL) {
171
+ rmSync(join(cacheRoot, key), { recursive: true });
172
+ selected = undefined;
173
+ }
174
+ if (selected)
175
+ return { directory: join(cacheRoot, key), candidate: selected, owned };
176
+ let remaining = candidates.filter(item => item.candidate.key !== key);
177
+ for (const item of [...remaining].sort((a, b) => a.candidate.createdAt - b.candidate.createdAt)) {
178
+ const overBudget = remaining.length >= MAX_ENTRIES || remaining.reduce((sum, c) => sum + c.candidate.reservedBytes, reservedBytes) > MAX_BYTES;
179
+ if (!overBudget && Date.now() - item.candidate.createdAt < TTL)
180
+ continue;
181
+ let cleanup;
182
+ try {
183
+ cleanup = await lease(item.directory);
184
+ }
185
+ catch (error) {
186
+ if (error instanceof BackendImageCandidateError && error.code.endsWith('_BUSY'))
187
+ continue;
188
+ throw error;
189
+ }
190
+ try {
191
+ global.assert();
192
+ cleanup.assert();
193
+ rmSync(item.directory, { recursive: true });
194
+ remaining = remaining.filter(other => other !== item);
195
+ }
196
+ finally {
197
+ await cleanup.release();
198
+ }
199
+ }
200
+ if (remaining.length >= MAX_ENTRIES || remaining.reduce((sum, c) => sum + c.candidate.reservedBytes, reservedBytes) > MAX_BYTES) {
201
+ fail('CACHE_FULL', '镜像缓存空间被活动候选占用,请等待原上传完成');
202
+ }
203
+ global.assert();
204
+ owned.assert();
205
+ const directory = join(cacheRoot, key);
206
+ const candidate = { schemaVersion: SCHEMA, key, createdAt: Date.now(), reservedBytes, state: 'building' };
207
+ const staging = join(cacheRoot, `.prepare-${randomUUID()}`);
208
+ privateDirectory(staging);
209
+ try {
210
+ saveCandidate(staging, candidate);
211
+ global.assert();
212
+ owned.assert();
213
+ renameSync(staging, directory);
214
+ }
215
+ finally {
216
+ rmSync(staging, { recursive: true, force: true });
217
+ }
218
+ return { directory, candidate, owned };
219
+ }
220
+ catch (error) {
221
+ await owned.release();
222
+ throw error;
223
+ }
224
+ }
225
+ finally {
226
+ await global.release();
227
+ }
228
+ }
229
+ async function removeOwnedCandidate(cacheRoot, directory, owned) {
230
+ const global = await lease(join(cacheRoot, '.registry'), 8);
231
+ try {
232
+ global.assert();
233
+ owned.assert();
234
+ rmSync(directory, { recursive: true, force: true });
235
+ }
236
+ finally {
237
+ await global.release();
238
+ }
239
+ }
240
+ export async function withBackendImageCandidate(input) {
241
+ const scope = input.scope;
242
+ const platform = new URL(scope.platform);
243
+ if (platform.username || platform.password || platform.search || platform.hash || !['http:', 'https:'].includes(platform.protocol))
244
+ fail('RECOVERY_SCOPE_INVALID', '恢复目标无效');
245
+ for (const value of [scope.tenantId, scope.userId, scope.appCode, scope.environmentKey, scope.configurationDigest, scope.toolchainVersion]) {
246
+ if (typeof value !== 'string' || !value || value.length > 256)
247
+ fail('RECOVERY_SCOPE_INVALID', '恢复身份不完整');
248
+ }
249
+ const root = realpathSync(input.root);
250
+ const dockerfile = join(root, relative(resolve(input.root), input.dockerfile));
251
+ const contextDigest = await backendImageContextDigest(root, dockerfile);
252
+ const key = createHash('sha256').update(JSON.stringify([SCHEMA, root, relative(root, input.dockerfile), platform.href.replace(/\/+$/, ''),
253
+ scope.tenantId, scope.userId, scope.appCode, scope.environmentKey, scope.environmentId ?? '', scope.configurationDigest, scope.toolchainVersion, contextDigest])).digest('hex');
254
+ const cacheRoot = resolve(input.cacheRoot || join(realpathSync(homedir()), '.openxiangda', 'cache', 'backend-images'));
255
+ if (cacheRoot === root || cacheRoot.startsWith(`${root}/`))
256
+ fail('CACHE_PATH_INVALID', '镜像缓存不能进入 Docker 构建上下文');
257
+ for (let path = cacheRoot; path !== dirname(path); path = dirname(path)) {
258
+ if (existsSync(path) && lstatSync(path).isSymbolicLink())
259
+ fail('CACHE_PATH_INVALID', '镜像缓存路径不能经过符号链接');
260
+ }
261
+ if (!Number.isSafeInteger(input.maxImageBytes) || input.maxImageBytes < 1 || input.maxImageBytes > MAX_BYTES)
262
+ fail('CACHE_LIMIT', '当前候选超过 8 GiB 本机恢复预算');
263
+ const selected = await acquireCandidate(cacheRoot, key, Math.min(CANDIDATE_BYTES, input.maxImageBytes));
264
+ const directory = join(selected.directory, 'image');
265
+ let sealed = selected.candidate.state === 'sealed';
266
+ try {
267
+ if (!sealed) {
268
+ rmSync(directory, { recursive: true, force: true });
269
+ await input.build(directory);
270
+ selected.owned.assert();
271
+ if (await backendImageContextDigest(root, dockerfile) !== contextDigest)
272
+ fail('CONTEXT_CHANGED', '构建期间源码发生变化,未上传混合候选;保存后重试');
273
+ const inspected = await inspectBackendOciLayout({ directory, maxImageBytes: selected.candidate.reservedBytes });
274
+ selected.candidate = { ...selected.candidate, state: 'sealed', digest: inspected.digest };
275
+ saveCandidate(selected.directory, selected.candidate);
276
+ sealed = true;
277
+ }
278
+ selected.owned.assert();
279
+ const result = await input.upload(directory, selected.candidate.digest, selected.owned.assert);
280
+ // A local cleanup error must never turn a confirmed remote success into a failure.
281
+ try {
282
+ await removeOwnedCandidate(cacheRoot, selected.directory, selected.owned);
283
+ }
284
+ catch { /* bounded cache will reclaim it */ }
285
+ return result;
286
+ }
287
+ catch (error) {
288
+ if (!sealed) {
289
+ try {
290
+ await removeOwnedCandidate(cacheRoot, selected.directory, selected.owned);
291
+ }
292
+ catch { /* retain incomplete state for the next owner */ }
293
+ throw error;
294
+ }
295
+ const causeCode = String(error?.code ?? 'UPLOAD_FAILED');
296
+ throw new BackendImageCandidateError('OPENXIANGDA_BACKEND_IMAGE_UPLOAD_PENDING', '原镜像候选已保留;恢复网络或登录后,在相同工作区重试 openxiangda deploy 即可继续原摘要上传', { candidateId: key, digest: selected.candidate.digest, expiresAt: new Date(selected.candidate.createdAt + TTL).toISOString(),
297
+ nextCommand: 'pnpm openxiangda deploy', remediation: '恢复网络或登录后,在原工作区执行 pnpm openxiangda deploy;保持原输入将恢复同一镜像摘要。',
298
+ causeCode: /^[A-Z0-9_]{1,128}$/.test(causeCode) ? causeCode : 'UPLOAD_FAILED' }, true);
299
+ }
300
+ finally {
301
+ await selected.owned.release();
302
+ }
303
+ }
304
+ //# sourceMappingURL=backend-image-candidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-image-candidate.js","sourceRoot":"","sources":["../src/backend-image-candidate.ts"],"names":[],"mappings":"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"}
@@ -23,12 +23,26 @@ export interface BackendImageUploader {
23
23
  }>;
24
24
  completeBackendImage(appCode: string, digest: string): Promise<BackendImageUploadReceipt>;
25
25
  }
26
+ export declare function inspectBackendOciLayout(input: {
27
+ directory: string;
28
+ maxImageBytes: number;
29
+ }): Promise<{
30
+ digest: string;
31
+ manifest: string;
32
+ sizeBytes: number;
33
+ blobs: Map<string, {
34
+ digest: string;
35
+ size: number;
36
+ }>;
37
+ }>;
26
38
  export declare function uploadBackendOciLayout(input: {
27
39
  directory: string;
28
40
  appCode: string;
29
41
  maxImageBytes: number;
30
42
  chunkEncoding?: BackendImageChunkEncoding;
31
43
  uploader: BackendImageUploader;
44
+ expectedDigest?: string;
45
+ assertOwnership?: () => void;
32
46
  }): Promise<{
33
47
  digest: string;
34
48
  reference: string;
@@ -1 +1 @@
1
- {"version":3,"file":"backend-image-upload.d.ts","sourceRoot":"","sources":["../src/backend-image-upload.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAE/C,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACnF;AAED,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACpH,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EACzF,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAClH,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;CAC3F;AAiCD,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,yBAAyB,CAAC;IAC1C,QAAQ,EAAE,oBAAoB,CAAC;CAChC,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAkEjD"}
1
+ {"version":3,"file":"backend-image-upload.d.ts","sourceRoot":"","sources":["../src/backend-image-upload.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAE/C,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACnF;AAED,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACpH,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EACzF,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAClH,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;CAC3F;AAiCD,wBAAsB,uBAAuB,CAAC,KAAK,EAAE;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;;;;;gBAgByC,MAAM;cAAQ,MAAM;;GAgC7D;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,yBAAyB,CAAC;IAC1C,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAgDjD"}
@@ -1,4 +1,4 @@
1
- import { createReadStream, lstatSync, readFileSync } from 'node:fs';
1
+ import { createReadStream, lstatSync, readFileSync, readdirSync } from 'node:fs';
2
2
  import { open } from 'node:fs/promises';
3
3
  import { createHash } from 'node:crypto';
4
4
  import { join } from 'node:path';
@@ -34,7 +34,12 @@ async function retry(operation) {
34
34
  }
35
35
  }
36
36
  }
37
- export async function uploadBackendOciLayout(input) {
37
+ export async function inspectBackendOciLayout(input) {
38
+ for (const path of [input.directory, join(input.directory, 'blobs'), join(input.directory, 'blobs', 'sha256')]) {
39
+ const stat = lstatSync(path);
40
+ if (!stat.isDirectory() || stat.isSymbolicLink())
41
+ invalid();
42
+ }
38
43
  const layout = JSON.parse(metadata(join(input.directory, 'oci-layout')));
39
44
  const index = JSON.parse(metadata(join(input.directory, 'index.json')));
40
45
  if (layout.imageLayoutVersion !== '1.0.0' || index.schemaVersion !== 2 ||
@@ -61,6 +66,20 @@ export async function uploadBackendOciLayout(input) {
61
66
  if (!Number.isSafeInteger(sizeBytes) || sizeBytes > input.maxImageBytes) {
62
67
  throw Object.assign(new Error('OPENXIANGDA_BACKEND_IMAGE_TOO_LARGE: 镜像超过平台上传额度'), { code: 'OPENXIANGDA_BACKEND_IMAGE_TOO_LARGE' });
63
68
  }
69
+ const expected = new Set([digest, ...blobs.keys()].map(value => value.slice(7)));
70
+ const paths = readdirSync(join(input.directory, 'blobs', 'sha256'));
71
+ const rootEntries = readdirSync(input.directory);
72
+ // Buildx/containerd leaves this empty staging directory after a completed export.
73
+ if (rootEntries.includes('ingest')) {
74
+ const ingest = join(input.directory, 'ingest');
75
+ const stat = lstatSync(ingest);
76
+ if (!stat.isDirectory() || stat.isSymbolicLink() || readdirSync(ingest).length)
77
+ invalid();
78
+ }
79
+ if (rootEntries.filter(name => name !== 'ingest').sort().join(',') !== 'blobs,index.json,oci-layout' ||
80
+ readdirSync(join(input.directory, 'blobs')).join(',') !== 'sha256' ||
81
+ paths.length !== expected.size || paths.some(path => !expected.has(path)))
82
+ invalid();
64
83
  for (const blob of blobs.values()) {
65
84
  const path = blobPath(input.directory, blob.digest);
66
85
  const stat = lstatSync(path);
@@ -72,11 +91,28 @@ export async function uploadBackendOciLayout(input) {
72
91
  if (`sha256:${hash.digest('hex')}` !== blob.digest)
73
92
  invalid();
74
93
  }
75
- let receipt = await retry(() => input.uploader.beginBackendImage(input.appCode, { digest, manifest }));
94
+ return { digest, manifest, sizeBytes, blobs };
95
+ }
96
+ export async function uploadBackendOciLayout(input) {
97
+ const { digest, manifest, sizeBytes, blobs } = await inspectBackendOciLayout(input);
98
+ if (input.expectedDigest !== undefined && input.expectedDigest !== digest)
99
+ invalid();
100
+ const owned = async (operation) => {
101
+ input.assertOwnership?.();
102
+ return operation();
103
+ };
104
+ let receipt = await retry(() => owned(() => input.uploader.beginBackendImage(input.appCode, { digest, manifest })));
76
105
  if (receipt.digest !== digest || receipt.sizeBytes !== sizeBytes || receipt.maxChunkBytes !== CHUNK_BYTES ||
106
+ !['ready', 'uploading'].includes(receipt.status) ||
77
107
  !Array.isArray(receipt.blobs) || receipt.blobs.length !== blobs.size ||
78
108
  new Set(receipt.blobs.map(blob => blob.digest)).size !== blobs.size)
79
109
  invalid();
110
+ for (const progress of receipt.blobs) {
111
+ const blob = blobs.get(progress.digest);
112
+ if (!blob || progress.size !== blob.size || !Number.isSafeInteger(progress.offset) || progress.offset < 0 ||
113
+ progress.offset > blob.size || typeof progress.complete !== 'boolean' || (progress.complete && progress.offset !== blob.size))
114
+ invalid();
115
+ }
80
116
  if (receipt.status !== 'ready') {
81
117
  for (const progress of receipt.blobs) {
82
118
  const blob = blobs.get(progress.digest);
@@ -95,7 +131,7 @@ export async function uploadBackendOciLayout(input) {
95
131
  if (read.bytesRead !== content.length)
96
132
  invalid();
97
133
  const encoded = input.chunkEncoding === 'gzip' ? gzipSync(content) : content;
98
- const result = await retry(() => input.uploader.uploadBackendImageChunk(input.appCode, digest, blob.digest, offset, encoded, input.chunkEncoding));
134
+ const result = await retry(() => owned(() => input.uploader.uploadBackendImageChunk(input.appCode, digest, blob.digest, offset, encoded, input.chunkEncoding)));
99
135
  if (!Number.isSafeInteger(result.offset) || result.offset < 0 || result.offset > blob.size ||
100
136
  typeof result.complete !== 'boolean' || (result.complete && result.offset !== blob.size))
101
137
  invalid();
@@ -110,7 +146,7 @@ export async function uploadBackendOciLayout(input) {
110
146
  await file.close();
111
147
  }
112
148
  }
113
- receipt = await retry(() => input.uploader.completeBackendImage(input.appCode, digest));
149
+ receipt = await retry(() => owned(() => input.uploader.completeBackendImage(input.appCode, digest)));
114
150
  }
115
151
  if (receipt.digest !== digest || receipt.status !== 'ready' || typeof receipt.reference !== 'string' ||
116
152
  !receipt.reference.endsWith(`@${digest}`) || /[\s?#\\]/.test(receipt.reference))