@h-ai/deploy 1.0.0-beta.22 → 1.0.0-beta.23
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/README.en.md +6 -10
- package/README.ja.md +5 -9
- package/README.md +5 -9
- package/dist/deploy-runtime-env.mjs +3 -11
- package/dist/index.d.ts +6 -38
- package/dist/index.js +92 -617
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/docs/credential-import.en.md +0 -40
- package/docs/credential-import.ja.md +0 -40
- package/docs/credential-import.md +0 -70
package/README.en.md
CHANGED
|
@@ -119,7 +119,7 @@ Bodyless authenticated envelopes use X-Hai-Transport. Generated proxies set larg
|
|
|
119
119
|
|
|
120
120
|
Dependency inputs are prepared under images/dependencies/ from package manifests, local archives and patches. Combine pnpm store caching with stable dependency layers. Source changes should reuse downloaded packages. Empty caches still permit online builds. Windows node_modules cannot supply Linux native dependencies. Offline builds additionally require base images, tools and matching ABI/architecture/libc binaries.
|
|
121
121
|
|
|
122
|
-
The root package.json.version identifies the application. `.hai/build/docker/<buildId>/` contains the manifest, selected image archives and SHA-256.
|
|
122
|
+
The root package.json.version identifies the application. `.hai/build/docker/<buildId>/` contains the manifest, selected image archives and SHA-256. Image artifacts use format 5. `webBasePath` records the public mount path, with an empty string for the domain root. partial marks incremental builds and hasWeb records topology. servContainerPort and webContainerPort retain explicitly configured serv/web listening ports, including the image left out of a partial build. Omitted ports keep the deployment defaults. Rebuilding the same application version is allowed; unique build IDs/image references distinguish contents. Publish the local build pointer only after all exports succeed. Pin base images, middleware and tools; do not use latest.
|
|
123
123
|
|
|
124
124
|
#### Website mount path
|
|
125
125
|
|
|
@@ -135,7 +135,7 @@ The default deployment name comes from `package.json.name` at the project root (
|
|
|
135
135
|
|
|
136
136
|
For a gateway that only exposes `/somepath/`, build with `PUBLIC_BASE_PATH=/somepath` and explicitly place Serv `http.apiPrefix`, health/readiness, docs and storage `publicEndpoint` under that prefix. The SDK generates proxy paths and browser API configuration from those effective settings. Preserve the prefix at the edge; handle internal probes and root ACME challenges separately. [Complete configuration and checks](../../docs/usage/configuration/delivery.md#所有对外业务路径必须带同一目录).
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
`primaryService` records the primary service (`serv` or `web`), and `hasWeb` describes the complete browser topology. Projects with both services get a same-origin API proxy.
|
|
139
139
|
|
|
140
140
|
Prepare `.env.<environment>` and the project root `hai.json`, with image/native configuration in `build` and application deployment in `deploy`. Fullstack scripts still point to packages/<project>-serv, and API workspaces to apps/<project>-serv, only to scan runtime dependencies and module YAML. Frontend and backend share the project configuration.
|
|
141
141
|
|
|
@@ -213,9 +213,7 @@ The server holds a nonblocking kernel lock with util-linux `flock` on `.deploy.l
|
|
|
213
213
|
|
|
214
214
|
Preflight verifies the actual named volume and backend family for self-hosted `db`, `storage` and `vecdb`. The server's `<remoteDir>/persistent-backends` ledger records these bindings before any service starts and preserves them when a service is removed, a first installation fails, or recovery runs. Removing PostgreSQL while retaining its volume and later adding MySQL is therefore refused. Protect and back up the ledger together with `managed-secrets.env` and the data volumes. Never delete or edit it to force adoption of an old volume. These are private deployment metadata, with no new public configuration option.
|
|
215
215
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
The separate [controlled credential import](docs/credential-import.md) path can supply evidence for an unclaimed volume: valid v2 state must bind the exact project, credential group and volume, and one running original container must confirm the same project/service through consistent Docker/Podman labels, actual mounts and image family. Missing evidence still fails closed. Import never overrides a known ledger claim or engine identity conflict and does not create a successful baseline. Without `current`, use the current CLI to create a **new full bundle with a new ID** for the first takeover; incremental updates require that full deployment to succeed first.
|
|
216
|
+
Each existing data volume must match the service, backend family and volume in the protected ledger. A missing active volume or ledger record stops deployment. Restore verified backups before retrying. Each new release saves `previous-state-backends` so recovery can revalidate its bindings against the ledger and existing volumes.
|
|
219
217
|
|
|
220
218
|
These checks apply to `apply.sh` on the **target Linux server over SSH**: keep the SSH user and local daemon/store fixed. Docker must use its default context; Podman must actually run locally. Remote connections and explicit storage overrides are refused. In production, pin `remote.runtime` to the verified `docker` or `podman`. If installing Podman changes the engine selected by `auto`, first restore the original runtime, SSH user and store. Intentional server, daemon or storage changes need a separate migration; matching user IDs or directory names do not prove compatibility. Building and packaging on Windows/macOS with Docker Desktop or a Podman VM, then deploying over SSH, remains supported.
|
|
221
219
|
|
|
@@ -301,7 +299,7 @@ Environment flags, initial account passwords and the transport key ring are also
|
|
|
301
299
|
|
|
302
300
|
Generators prefer field variables and retain JSON arrays. Handwritten JSON remains a base and appears before its module fields; fields in the same source win. Dynamic maps, JSON text and explicit empty objects preserve their meaning. Expanding a whole-object replacement retains its highest `{}` reset marker so old YAML fields cannot reappear. Container paths stay in delivery output without changing source settings.
|
|
303
301
|
|
|
304
|
-
The deployment archive contains `apply.sh`, `APPLY.txt`, `manifest.json`, `config/`, `images/`, and `.hai/` at the top level. `config/.env.runtime` is the single application environment file. `manifest.json.metadata` holds nonsecret layout, dependencies, health paths, image lists and managed bindings. `.hai/compose.json` is a complete snapshot; partial updates replace selected service definitions and retain other services without historical Compose chains. `.hai/` also contains native environment, the loader, Nginx/TLS, policy and checksums. Secrets stay out of the manifest; helper scripts are embedded in `apply.sh`. Failure recovery restores application configuration before services while protecting credentials, backend ledgers and volumes.
|
|
302
|
+
The deployment archive contains `apply.sh`, `APPLY.txt`, `manifest.json`, `config/`, `images/`, and `.hai/` at the top level. `config/.env.runtime` is the single application environment file. `manifest.json.metadata` holds nonsecret layout, dependencies, health paths, image lists and managed bindings. `.hai/compose.json` is a complete snapshot; partial updates replace selected service definitions and retain other services without historical Compose chains. `.hai/` also contains native environment, the loader, Nginx/TLS, policy and checksums. Secrets stay out of the manifest; helper scripts are embedded in `apply.sh`. Failure recovery restores application configuration before services while protecting credentials, backend ledgers and volumes. The deployment archive uses `bundleFormat: 2`. Runtime preparation reuses the already imported Node application image in a temporary container with networking disabled. It downloads no extra image and requires no host Node or jq.
|
|
305
303
|
|
|
306
304
|
Node backends (Serv / SvelteKit SSR) read `<deployment-root>/config/.env.runtime` on every start. This single application file includes managed connections. Edit a field such as `HAI_STORAGE_PUBLICENDPOINT`, then restart the backend; fields override parent JSON within the same source. The configuration directory is mounted read-only at `/run/hai/config`, so atomic file replacement is visible on restart. Private proxy identity and Node startup options remain deployment settings. Static Web, native middleware environment, ports/mounts, and Nginx routes or limits require deployment. Web/middleware-only updates retain the file; partial backend updates preserve managed connections, while full updates use the new package with existing managed credentials. Back up edits and copy permanent settings into the source environment.
|
|
307
305
|
|
|
@@ -325,7 +323,7 @@ Each delivery still generates `config/.env.runtime` inside the archive for Compo
|
|
|
325
323
|
|
|
326
324
|
Project-root `hai.json.deploy` stores deployment structure, `.env.<environment>` stores public settings, and `.env.<environment>.local` stores SSH settings and middleware secrets. Environment files default to the project/workspace root; override with `--env-dir`. After configuration, `pnpm run deploy --env test --build --bundle-only --yes` reuses complete settings without prompts; add `--skip-middleware` to retain middleware configuration. Interactive bundle-only mode offers to save or update SSH settings at the final configuration step; editing a delivery's `deploy-target.json` does not update the project.
|
|
327
325
|
|
|
328
|
-
The server persists managed middleware passwords in `<remoteDir>/managed-secrets.env` (mode 0600); back it up with data volumes. Each package supplies random first-use candidates without a build-machine cache. The online SDK, deploy.sh, deploy.ps1 and deploy-local.sh resolve server values under the deployment lock and update both application connections and native middleware variables. The delivery tar stays immutable; only private server runtime files receive resolved values. Missing state with an existing corresponding volume stops deployment before services change: restore the server credential backup. Deployment never silently rotates passwords or deletes data.
|
|
326
|
+
The server persists managed middleware passwords in `<remoteDir>/managed-secrets.env` (mode 0600); back it up with data volumes. Each package supplies random first-use candidates without a build-machine cache. The online SDK, deploy.sh, deploy.ps1 and deploy-local.sh resolve server values under the deployment lock and update both application connections and native middleware variables. The delivery tar stays immutable; only private server runtime files receive resolved values. Missing state with an existing corresponding volume stops deployment before services change: restore the server credential backup. Deployment never silently rotates passwords or deletes data.
|
|
329
327
|
|
|
330
328
|
### Read-only deployment plan
|
|
331
329
|
|
|
@@ -335,12 +333,10 @@ Use `--plan --inspect-remote` (SDK inspectRemote:true) to read current and the s
|
|
|
335
333
|
|
|
336
334
|
Resources use the complete execution topology. `containers` lists selected explicit container names; Compose-named LDAP/SMTP services appear in `composeManagedServices`. The SSR/API storage gateway appears in the actual selected or retained scope. `logicalVolumes` declares the complete Compose topology, including retained services and data volumes still mounted by the app; it does not mean those volumes will be created or replaced. Engine names are scoped by the Compose project. Unselected middleware has action keep, and cloud provisioning follows the actual selection without exposing credentials.
|
|
337
335
|
|
|
338
|
-
###
|
|
336
|
+
### Transport capacity
|
|
339
337
|
|
|
340
338
|
Explicit plaintext limits are preserved. Packaging rejects feedback requirements above an explicit limit with a configuration conflict. Omitted/auto values derive capacity; the Web proxy and Kit BODY_SIZE_LIMIT use the same encrypted budget. Plan target.runtime reports remote provider.remote.runtime separately from local packaging options.runtime; auto is not a detected runtime.
|
|
341
339
|
|
|
342
|
-
Use `importDeploymentSecrets({ directory, inputFile, runtime })` or run `hai deploy-secrets <directory> --import <private.json>` on the server for read-only verification. Only explicit `--apply` / dryRun:false imports state. The tool verifies projects, containers, volumes and live credentials; it never infers passwords from old bundles, rotates credentials or rebuilds services. V2 state supports special characters and is atomically written with mode 0600 under the deployment flock. Ordinary offline deployment still requires no server Node; this one-time import tool needs supported Node and installed CLI/deploy. See the [import and recovery procedure](docs/credential-import.en.md).
|
|
343
|
-
|
|
344
340
|
### Request policy files and trusted proxies
|
|
345
341
|
|
|
346
342
|
Serv `http.access` and SvelteKit `access` can reference separate yml/yaml files. Deployment reads effective application configuration, including environment overrides such as `HAI_SERV`, `HAI_SERV_HTTP_ACCESS` and `HAI_KIT_ACCESS`, validates the file and includes a normalized snapshot in the bundle. Runtime configuration points to `/run/hai/request-access.yml` with a read-only Compose mount. The project retains its original file reference. The snapshot participates in SHA-256 verification; missing or invalid files fail before upload. The upload archive and its policy snapshot are integrity-checked inputs; replacing the SDK-managed snapshot requires a new bundle and deployment. The deployed Node backend reads its mounted `.env.runtime` on restart as described above. Inline rule changes do not rewrite the policy snapshot or Nginx configuration.
|
package/README.ja.md
CHANGED
|
@@ -119,7 +119,7 @@ pnpm run deploy --env prod --build --bundle-only --image-source cn --npm-source
|
|
|
119
119
|
|
|
120
120
|
構築器はパッケージ情報、ローカルアーカイブとパッチを images/dependencies/ に準備し、pnpm store と依存レイヤーをキャッシュします。通常のソース変更で全依存を再ダウンロードしない構成です。キャッシュが空でもオンライン構築できます。Windows の node_modules は Linux のネイティブ依存を代替できません。完全オフライン構築には基底イメージ、ツールと一致する ABI・アーキテクチャ・libc のバイナリも準備します。
|
|
121
121
|
|
|
122
|
-
アプリの版はルートpackage.json.versionで管理します。`.hai/build/docker/<buildId>/`にmanifest、選択イメージのtarとSHA-256
|
|
122
|
+
アプリの版はルートpackage.json.versionで管理します。`.hai/build/docker/<buildId>/`にmanifest、選択イメージのtarとSHA-256を出力します。イメージ成果物は形式 5 を使用します。`webBasePath` に公開マウントパスを記録し、ドメインのルートは空文字で表します。partialは部分構築、hasWebは構成を記録します。servContainerPortとwebContainerPortは明示したserv/webの待受ポートを保持し、部分構築で選ばなかったイメージのポートも失いません。未指定のポートにはデプロイ時の既定値を使います。同じアプリ版でも再構築可能で、構築IDとイメージ参照で内容を区別します。全出力に成功してからローカルの構築参照を更新します。基底・ミドルウェア・ツールは版を固定し、latestを使いません。
|
|
123
123
|
|
|
124
124
|
#### サイトの公開ディレクトリー
|
|
125
125
|
|
|
@@ -135,7 +135,7 @@ SDKは対応するNginx、実行時設定URL、SSRヘルスチェック、公開
|
|
|
135
135
|
|
|
136
136
|
既定の配置名はプロジェクトルート(最も近い `hai.json` またはロックファイルのディレクトリ)の `package.json.name` を使い、未指定または無効な名前はエラーになります。明示した環境名を末尾に追加します。fullstack の `hai-delivery` で `packages/hai-delivery-serv` を走査しても、`--env test` は `/opt/hai/apps/hai-delivery-test` と `bundle-hai-delivery-test-<配置ID>-<版>.tar.gz` を生成します。接続先ディレクトリ、配布物、Compose プロジェクト、API/Web/ミドルウェアのコンテナー、ボリューム、サーバー認証状態のファイル名、増分基準で同じ名前を使います。実際のプロジェクト名に含まれる `-serv` は削除しません。
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
`primaryService` は主サービス(`serv` または `web`)を、`hasWeb` はブラウザー構成を記録します。同一オリジン API プロキシは両方のサービスがある場合に生成されます。
|
|
139
139
|
|
|
140
140
|
`.env.<環境>` とプロジェクトルートの `hai.json` を用意します。`build` にイメージ・ネイティブ構築、`deploy` にアプリ全体の配置設定を保存します。fullstack は packages/<プロジェクト>-serv、API workspace は apps/<プロジェクト>-serv を実行依存とモジュール YAML の走査入口として使います。フロントとバックエンドは同じ設定を共有します。
|
|
141
141
|
|
|
@@ -213,9 +213,7 @@ pnpm run deploy --env prod --build --bundle-only
|
|
|
213
213
|
|
|
214
214
|
事前検証で自前 `db`、`storage`、`vecdb` の実ボリューム名とバックエンド種類を確認します。サーバーの `<remoteDir>/persistent-backends` 台帳には起動前に対応関係を保存し、サービス削除、初回配置失敗、自動復元でも記録を残します。そのため、PostgreSQL を削除してボリュームを残した後に MySQL を追加する操作も拒否します。`managed-secrets.env`、データボリュームと一緒に保護・バックアップし、旧ボリュームを強制使用するために台帳を削除・編集しないでください。これらは配置内部のメタデータで、公開設定項目の追加はありません。
|
|
215
215
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
別途[管理された認証情報インポート](docs/credential-import.md)による補証も可能です。台帳に対象ボリュームの記録がない場合に限り、正しい v2 状態のプロジェクト・認証情報グループ・ボリュームが完全一致し、唯一の実行中旧コンテナーの Docker/Podman ラベル、実マウント、イメージ種類でも同じプロジェクトとサービスを確認します。一つでも不足すれば拒否し、既知の台帳やエンジン識別の競合を上書きしません。インポートは成功基準を作りません。`current` がなければ現在の CLI で**新 ID の全量パッケージ**を作り、最初の完全配置が成功してから増分を使います。
|
|
216
|
+
既存のデータボリュームは、保護された台帳のサービス、バックエンド種類、ボリューム名と一致する必要があります。稼働中のボリュームまたは台帳の記録がなければ配置を停止します。確認済みのバックアップを復元してから再試行してください。新しいリリースの `previous-state-backends` は、復旧前に台帳と実ボリュームを再検証するために使います。
|
|
219
217
|
|
|
220
218
|
この検査は **SSH 接続先の Linux サーバー**で `apply.sh` を実行するときに適用します。SSH ユーザーとローカル daemon/store を固定し、Docker は default context、Podman は実際のローカル実行が必要です。リモート接続や明示的な保存先上書きは拒否します。本番では `remote.runtime` を検証済みの `docker` または `podman` に固定してください。Podman の追加で `auto` が別エンジンを選んだ場合、まず元の runtime、SSH ユーザー、保存先に戻します。意図的なサーバー・daemon・保存先変更は個別に移行し、同じ uid やパスだけで互換性を判断しません。Windows/macOS の操作端末で Docker Desktop や Podman VM を使って構築・梱包し、SSH で配置する方法は引き続き利用できます。
|
|
221
219
|
|
|
@@ -325,7 +323,7 @@ Podman では設定済みの healthcheck を明示的に実行して状態を再
|
|
|
325
323
|
|
|
326
324
|
プロジェクトルートの `hai.json.deploy` に配置構造、`.env.<環境>` に公開設定、`.env.<環境>.local` に SSH とミドルウェアの認証情報を保存します。環境ファイルは既定でプロジェクト/workspace ルート、変更時は `--env-dir` を指定します。設定後は `pnpm run deploy --env test --build --bundle-only --yes` で再入力を省略でき、ミドルウェア設定を保持する場合は `--skip-middleware` を追加します。対話式 bundle-only は最後に SSH 設定の保存・変更を確認します。配布物の `deploy-target.json` の編集はプロジェクトに反映されません。
|
|
327
325
|
|
|
328
|
-
自前ミドルウェアのパスワードはサーバーの `<remoteDir>/managed-secrets.env`(権限 0600)で永続管理し、データボリュームと一緒にバックアップします。各パッケージは初回用の候補のみ生成し、ビルド端末のキャッシュに依存しません。オンライン SDK、deploy.sh、deploy.ps1、deploy-local.sh は配置ロック内でサーバー値を再利用し、アプリ接続とミドルウェア固有変数の両方へ反映します。配布 tar
|
|
326
|
+
自前ミドルウェアのパスワードはサーバーの `<remoteDir>/managed-secrets.env`(権限 0600)で永続管理し、データボリュームと一緒にバックアップします。各パッケージは初回用の候補のみ生成し、ビルド端末のキャッシュに依存しません。オンライン SDK、deploy.sh、deploy.ps1、deploy-local.sh は配置ロック内でサーバー値を再利用し、アプリ接続とミドルウェア固有変数の両方へ反映します。配布 tar は変更せず、サーバーの非公開実行ファイルだけに確定値を反映します。対応するボリュームが存在し状態がない場合、サービス変更前に停止してバックアップ復元を求めます。パスワードとデータは保持されます。
|
|
329
327
|
|
|
330
328
|
### 読み取り専用デプロイ計画
|
|
331
329
|
|
|
@@ -335,12 +333,10 @@ Podman では設定済みの healthcheck を明示的に実行して状態を再
|
|
|
335
333
|
|
|
336
334
|
リソースは実行側の完全な構成を共用します。`containers` は今回選択した明示名のみ、Compose が命名する LDAP/SMTP は `composeManagedServices` に表示します。SSR/API のストレージ gateway も更新・保持対象に表示します。`logicalVolumes` は保持サービスとアプリが継続使用するデータを含む構成全体の論理キーで、新規作成や再作成の指示ではありません。実際の名前は Compose プロジェクトのスコープで決まります。未選択ミドルウェアの action は keep で、クラウド開通は実際の選択範囲に従い、認証値を表示しません。
|
|
337
335
|
|
|
338
|
-
###
|
|
336
|
+
### 暗号化通信の容量
|
|
339
337
|
|
|
340
338
|
明示された平文上限を保持し、フィードバックの必要量が超える場合は競合を示して梱包を拒否します。省略/auto だけ自動計算し、Web プロキシと Kit BODY_SIZE_LIMIT は同じ暗号文予算を使います。計画の target.runtime はリモートの provider.remote.runtime を示し、ローカル梱包 options.runtime とは別です。auto を検出済みと表示しません。
|
|
341
339
|
|
|
342
|
-
`importDeploymentSecrets({ directory, inputFile, runtime })` またはサーバー上の `hai deploy-secrets <directory> --import <private.json>` で読み取り専用検査を行います。明示 `--apply` / dryRun:false のみ保存します。プロジェクト・コンテナ・ボリューム・実際の認証情報を検証し、古いパッケージからの推測、パスワード変更、サービス再作成はしません。特殊文字対応 v2 状態をデプロイ共通 flock 内で原子的に0600で保存します。通常のオフライン配布にサーバー Node は不要で、一度限りの移行ツールには対応 Node と CLI/deploy が必要です。[導入・復旧手順](docs/credential-import.ja.md)を参照してください。
|
|
343
|
-
|
|
344
340
|
### リクエストポリシーファイルと信頼する代理
|
|
345
341
|
|
|
346
342
|
Serv の `http.access` と SvelteKit の `access` は独立した yml/yaml を参照できます。配備は `HAI_SERV`、`HAI_SERV_HTTP_ACCESS`、`HAI_KIT_ACCESS` などの環境上書きを含む実効設定を読み、検証済みの正規化スナップショットを配布物へ含めます。実行時は `/run/hai/request-access.yml` を Compose の読み取り専用マウントで参照し、工程の元の参照先は変更しません。SHA-256 検証に含まれ、ファイル不足・不正はアップロード前に失敗します。アップロードするアーカイブとそのポリシースナップショットは整合性検証の対象です。SDK 管理のスナップショットを置き換える場合は新しい配布物を作成します。配置済み Node バックエンドのマウント済み `.env.runtime` は上記手順で編集・再起動できます。インライン規則の変更ではスナップショットや Nginx 設定は書き換わりません。
|
package/README.md
CHANGED
|
@@ -131,7 +131,7 @@ pnpm run deploy --env prod --build --bundle-only --image-source cn --npm-source
|
|
|
131
131
|
|
|
132
132
|
构建器将锁文件、包配置、本地归档和补丁准备为 `images/dependencies/` 输入,结合 pnpm store 缓存与 Docker 分层复用下载。源码修改不应重新下载全部依赖;缓存为空仍能联网构建。Windows node_modules 不用于 Linux 镜像。完全离线构建还需预先准备基础镜像、工具链和匹配 ABI/架构/libc 的原生预编译包。
|
|
133
133
|
|
|
134
|
-
版本来自应用根 package.json.version。制品位于 `.hai/build/docker/<buildId>/`,包括manifest.json、所选镜像tar和SHA-256
|
|
134
|
+
版本来自应用根 package.json.version。制品位于 `.hai/build/docker/<buildId>/`,包括manifest.json、所选镜像tar和SHA-256;镜像制品统一使用格式 5。`webBasePath` 记录公开挂载目录,空字符串表示域名根目录。partial 标识部分构建,hasWeb 保留工程拓扑。清单还会记住配置中填写的 serv/web 容器端口(servContainerPort、webContainerPort),只打包一个镜像也不会丢掉另一个的端口;没填写则沿用部署默认值。相同应用版本允许重建,构建编号和镜像引用区分实际内容;全部导出成功才更新本机构建入口。基础镜像、中间件及工具使用明确版本,不使用 latest。
|
|
135
135
|
|
|
136
136
|
#### 网站挂载目录
|
|
137
137
|
|
|
@@ -147,7 +147,7 @@ SDK据制品生成Nginx目录、运行配置入口、SSR健康路径和返回URL
|
|
|
147
147
|
|
|
148
148
|
全站仅开放 `/somepath/` 时,构建设置 `PUBLIC_BASE_PATH=/somepath`,并将 Serv 的 `http.apiPrefix`、健康/就绪和文档路径及存储 `publicEndpoint` 显式配置到同一目录。SDK 按这些有效配置生成代理和浏览器 API 地址;外层网关保留前缀,内部探活和 ACME 根路径单独处理。[完整配置与验收](../../docs/usage/configuration/delivery.md#所有对外业务路径必须带同一目录).
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
`primaryService` 记录主服务(`serv` 或 `web`),`hasWeb` 记录工程是否包含浏览器端。只有 `serv` 与 `web` 同时存在时才生成同源 API 代理。
|
|
151
151
|
|
|
152
152
|
准备 `.env.<环境>`(例如 `.env.prod`)和项目根 `hai.json`,其中 `build` 描述镜像与桌面构建,`deploy` 描述整个应用的部署。fullstack 的 deploy 参数仍指向 `packages/<项目>-serv`,API workspace 指向 `apps/<项目>-serv`,仅用于扫描运行依赖和模块 YAML;前后端构建与部署配置统一在项目根。
|
|
153
153
|
|
|
@@ -237,9 +237,7 @@ pnpm run deploy --env prod --build --bundle-only
|
|
|
237
237
|
|
|
238
238
|
部署前核对自建 `db`、`storage`、`vecdb` 的实际卷与后端家族;禁止把 PostgreSQL 数据卷交给 MySQL、RustFS 数据卷交给 MinIO,或在向量库引擎之间复用原卷。服务器 `<remoteDir>/persistent-backends` 长期记录这些绑定,在任何服务启动前保存;全量移除服务、首次安装失败和自动恢复都不会清掉记录。因此“移除 PostgreSQL → 保留卷 → 再加 MySQL”也会被拒绝。该文件与 `managed-secrets.env`、数据卷成套保护和备份,不得删除或编辑账本强行认领旧卷;这些是部署私有元数据,没有新增公开配置项。
|
|
239
239
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
另有明确的[受控凭据导入路径](docs/credential-import.md):账本尚未认领该卷时,合法 v2 状态必须绑定准确项目、凭据组和卷,并由同项目/服务的唯一运行原容器,以一致的 Docker/Podman 标签、真实 Mounts 和 Config.Image 家族共同补证。缺任一证据仍拒绝,导入不能覆盖已知账本或引擎身份冲突。导入不建立成功基线;没有 `current` 时,首次接管必须用当前 CLI 生成**新 ID 的完整全量包**,成功后才可增量。
|
|
240
|
+
已有数据卷必须与受保护账本中的服务、后端家族和卷名匹配。缺少活动卷或相应记录时停止部署,恢复已核验的备份后再试。每次发布保留 `previous-state-backends`,用于恢复前重新核验对应的账本记录与实际卷。
|
|
243
241
|
|
|
244
242
|
这些身份检查在 **SSH 目标 Linux 服务器**执行 `apply.sh` 时生效:使用固定 SSH 用户、固定本地 daemon/store,Docker 要求默认 context,Podman 要求实际本地模式;远程连接与显式存储覆盖环境会被拒绝。生产建议显式设置 `remote.runtime` 为已验收的 `docker` 或 `podman`。若 `auto` 因新装 Podman 换了引擎,应先恢复原 runtime、SSH 用户和存储,再重试;有意更换服务器、daemon 或数据存储则单独迁移,不能用相同 uid 或目录名证明数据兼容。Windows/macOS 操作机通过 Docker Desktop 或 Podman VM 构建、打包再 SSH 发布不受这一服务器限制。
|
|
245
243
|
|
|
@@ -352,7 +350,7 @@ Podman 部署会主动执行容器已有的 healthcheck 并重新核对状态,
|
|
|
352
350
|
|
|
353
351
|
项目根 `hai.json.deploy` 保存部署结构,`.env.<环境>` 保存公共配置,`.env.<环境>.local` 保存 SSH 及中间件秘密值。环境文件默认来自项目/workspace 根,`--env-dir` 可指定目录。完整配置后可使用 `pnpm run deploy --env test --build --bundle-only --yes` 无交互复用;只想保留现有中间件配置时追加 `--skip-middleware`。交互式仅打包会在最后询问是否保存或修改 SSH 信息;修改交付目录的 `deploy-target.json` 不会回写工程。
|
|
354
352
|
|
|
355
|
-
自建中间件的密码由服务器 `<remoteDir>/managed-secrets.env` 持久保存(权限 0600),应与数据卷一起备份。每次打包只生成首次初始化的随机候选,不依赖打包机缓存;在线 SDK、deploy.sh、deploy.ps1 和 deploy-local.sh 都在部署锁内复用服务器值,同时更新应用连接配置及中间件原生变量。交付 tar
|
|
353
|
+
自建中间件的密码由服务器 `<remoteDir>/managed-secrets.env` 持久保存(权限 0600),应与数据卷一起备份。每次打包只生成首次初始化的随机候选,不依赖打包机缓存;在线 SDK、deploy.sh、deploy.ps1 和 deploy-local.sh 都在部署锁内复用服务器值,同时更新应用连接配置及中间件原生变量。交付 tar 保持不可变,只有服务器私有运行文件使用定稿值。若状态缺失而对应数据卷已存在,部署在变更服务前明确停止,须恢复服务器凭据备份;不会自动换密或删除数据。
|
|
356
354
|
|
|
357
355
|
### 请求策略文件与可信代理
|
|
358
356
|
|
|
@@ -372,12 +370,10 @@ Serv 的 `http.access`、SvelteKit 的 `access` 可引用独立 yml/yaml。部
|
|
|
372
370
|
|
|
373
371
|
资源清单复用执行端的完整 sidecar 拓扑:`containers` 只列本次选中的显式容器名,LDAP/SMTP 等由 Compose 命名的服务列在 `composeManagedServices`;自建 S3 的 SSR/API gateway 也会列入实际更新或保留范围。`logicalVolumes` 是完整拓扑的 Compose 逻辑卷声明,包含保留服务和应用继续挂载的数据卷,不表示新建或重建这些卷;实际引擎卷名由 Compose 项目作用域决定。未选中间件的 action 为 keep,云开通仅按实际选择范围计算,不展示凭据值。
|
|
374
372
|
|
|
375
|
-
###
|
|
373
|
+
### 传输容量
|
|
376
374
|
|
|
377
375
|
传输明文上限保留显式设置;反馈需求超过显式值时拒绝打包并说明冲突。缺省/auto 才按模块预算推导,Web 代理和 Kit BODY_SIZE_LIMIT 使用同一密文预算。计划的 target.runtime 表示远端 provider.remote.runtime,与本地镜像打包 options.runtime 分离;auto 不冒充已探测事实。
|
|
378
376
|
|
|
379
|
-
旧目标可用 `importDeploymentSecrets({ directory, inputFile, runtime })` 或在服务器执行 `hai deploy-secrets <directory> --import <private.json>` 只读核验;显式 `--apply` / dryRun:false 才导入。工具核验项目、容器、卷和实际服务凭据,不猜测旧包、不轮换密码、不重建服务。新 v2 状态支持特殊字符并与部署共用 flock,原子写入权限 0600。常规离线部署无需服务器 Node;一次性导入工具需要受支持的 Node 与已安装的 CLI/deploy。详见[导入与恢复流程](docs/credential-import.md).
|
|
380
|
-
|
|
381
377
|
## 配置
|
|
382
378
|
|
|
383
379
|
生命周期:init 输入后端/业务配置,成功后才能使用;close 在释放借用依赖前等待完成。返回值以快速开始示例和公开签名为准。
|
|
@@ -103,12 +103,7 @@ function applyManagedPasswords(values, bindings, state) {
|
|
|
103
103
|
continue
|
|
104
104
|
if (!['DB_PASSWORD', 'STORAGE_PASSWORD', 'LDAP_PASSWORD'].includes(group) || !state[group])
|
|
105
105
|
throw new Error('Managed middleware credential state is missing')
|
|
106
|
-
|
|
107
|
-
if (state.FORMAT_VERSION === '2') {
|
|
108
|
-
if (!/^(?:[a-f0-9]{2})+$/.test(password))
|
|
109
|
-
throw new Error('Managed middleware credential encoding is invalid')
|
|
110
|
-
password = Buffer.from(password, 'hex').toString('utf8')
|
|
111
|
-
}
|
|
106
|
+
const password = state[group]
|
|
112
107
|
let configuration = {}
|
|
113
108
|
const parent = Object.hasOwn(values, prefix)
|
|
114
109
|
if (parent) {
|
|
@@ -191,15 +186,12 @@ function prepare(directory, previousManifest, previousEnvironment, credentialSta
|
|
|
191
186
|
}
|
|
192
187
|
const bindings = entries('managed-bindings').join('\n')
|
|
193
188
|
const state = readEnvironment(credentialState)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
throw new Error('Managed middleware credential project mismatch')
|
|
189
|
+
if (Object.entries(state).some(([key, value]) => !['DB_PASSWORD', 'STORAGE_PASSWORD', 'LDAP_PASSWORD'].includes(key) || !/^[\w-]{32}$/.test(value)))
|
|
190
|
+
throw new Error('Managed middleware credential state is invalid')
|
|
197
191
|
applyManagedPasswords(next, bindings, state)
|
|
198
192
|
validateRefreshCookie(next)
|
|
199
193
|
incoming.metadata['managed-app-keys'] = `${keys.join('\n')}${keys.length ? '\n' : ''}`
|
|
200
194
|
incoming.metadata['managed-bindings'] = `${bindings}${bindings ? '\n' : ''}`
|
|
201
|
-
if (project)
|
|
202
|
-
incoming.metadata['managed-project'] = project
|
|
203
195
|
const environment = serialize(next)
|
|
204
196
|
if (Buffer.byteLength(environment) > maximumBytes)
|
|
205
197
|
throw new Error('Prepared runtime environment exceeds 1 MiB')
|
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import * as _h_ai_core from '@h-ai/core';
|
|
|
3
3
|
import { HaiResult, HaiError } from '@h-ai/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* 镜像制品清单,例如 `{ version:
|
|
7
|
-
*
|
|
6
|
+
* 镜像制品清单,例如 `{ version: 5, webBasePath: '', primaryService: 'serv', appVersion: '1.2.3', buildId: '1.2.3-build1', partial: false, hasWeb: false, images: [...] }`。
|
|
7
|
+
* webBasePath 记录完整工程的挂载目录,空字符串表示域名根目录。
|
|
8
8
|
* 完整产物包含primaryService,hasWeb记录浏览器端拓扑;结构验证不能代替真实归档校验。
|
|
9
9
|
* @example
|
|
10
10
|
* ```ts
|
|
@@ -17,7 +17,7 @@ import { HaiResult, HaiError } from '@h-ai/core';
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
declare const DeploymentArtifactSchema: z.ZodObject<{
|
|
20
|
-
version: z.
|
|
20
|
+
version: z.ZodLiteral<5>;
|
|
21
21
|
primaryService: z.ZodEnum<{
|
|
22
22
|
serv: "serv";
|
|
23
23
|
web: "web";
|
|
@@ -30,7 +30,7 @@ declare const DeploymentArtifactSchema: z.ZodObject<{
|
|
|
30
30
|
}, z.core.$strip>>;
|
|
31
31
|
partial: z.ZodDefault<z.ZodBoolean>;
|
|
32
32
|
hasWeb: z.ZodDefault<z.ZodBoolean>;
|
|
33
|
-
webBasePath: z.
|
|
33
|
+
webBasePath: z.ZodString;
|
|
34
34
|
servContainerPort: z.ZodOptional<z.ZodNumber>;
|
|
35
35
|
webContainerPort: z.ZodOptional<z.ZodNumber>;
|
|
36
36
|
images: z.ZodArray<z.ZodObject<{
|
|
@@ -1077,7 +1077,7 @@ declare const deploy: DeployFunctions;
|
|
|
1077
1077
|
* const message = deployM('deploy_sshRequired')
|
|
1078
1078
|
* ```
|
|
1079
1079
|
*/
|
|
1080
|
-
declare const deployM: (key: "deploy_composeHostAddressInvalid" | "deploy_composeHostnameInvalid" | "deploy_composeHostnameConflict" | "deploy_composeProviderRequired" | "deploy_composeServiceUnavailable" | "deploy_notInitialized" | "deploy_initFailed" | "deploy_unsupportedProviderType" | "deploy_unsupportedProvisionerType" | "deploy_configTokenRequired" | "deploy_authRequired" | "deploy_authFailed" | "deploy_projectCreateFailed" | "deploy_uploadFailed" | "deploy_deployFailed" | "deploy_provisionFailed" | "deploy_adapterMissing" | "deploy_scanFailed" | "deploy_envVarFailed" | "deploy_credentialError" | "deploy_credentialInvalidKey" | "deploy_credentialSaved" | "deploy_credentialLoaded" | "deploy_configError" | "deploy_credentialMissing" | "deploy_apiError" | "deploy_fileUploadFailed" | "deploy_provisionNoResult" | "deploy_recoveryFailure" | "deploy_recoverySuggestion" | "deploy_commandTimeout" | "deploy_commandFailed" | "deploy_remoteConnectFailed" | "deploy_remoteRuntimeMissing" | "deploy_imageTransferFailed" | "deploy_healthCheckFailed" | "deploy_invalidEnvironment" | "deploy_environmentMissing" | "deploy_environmentReadFailed" | "deploy_environmentWriteFailed" | "deploy_multipleApplications" | "deploy_purposeSqlite" | "deploy_purposeDatabase" | "deploy_purposeMemory" | "deploy_purposeLocal" | "deploy_purposeCache" | "deploy_purposeStorage" | "deploy_purposeVector" | "deploy_purposeDisabled" | "deploy_purposeLdap" | "deploy_purposeConsole" | "deploy_purposeEmail" | "deploy_purposeSms" | "deploy_webProxyInvalid" | "deploy_webBaseConflict" | "deploy_storageProxyInvalid" | "deploy_storagePublicEndpointInvalid" | "deploy_storageBackendRequired" | "deploy_artifactInvalid" | "deploy_sshRequired" | "deploy_sshPasswordInvalid" | "deploy_sshAskpassFailed" | "deploy_sshAskpassCleanupFailed" | "deploy_targetAuth" | "deploy_targetPasswordEnv" | "deploy_bundleInstructions" | "deploy_bundleApplyGuide" | "deploy_bundleMetadata" | "deploy_targetHost" | "deploy_targetPort" | "deploy_targetUsername" | "deploy_targetIdentityFile" | "deploy_targetKnownHostsFile" | "deploy_targetStrictHostKeyChecking" | "deploy_targetConnectTimeoutSeconds" | "deploy_targetDirectory" | "deploy_targetBundle" | "deploy_bundleOnlyContainer" | "deploy_selectedContainerOnly" | "deploy_selectionInvalid" | "deploy_imageVersionRequired" | "deploy_bundleRuntimeRequired" | "deploy_bundleFailed" | "deploy_configFileInvalid" | "deploy_configFileUnreadable" | "deploy_bundleNameInvalid" | "deploy_localStopped" | "deploy_localUnknown" | "deploy_localNotStarted" | "deploy_commandOutputFailed" | "deploy_commandInputFailed" | "deploy_commandTreeActive" | "deploy_commandExecutionFailed" | "deploy_remoteUnknown" | "deploy_remoteFinished" | "deploy_bundleDirectoryExists" | "deploy_bundleFull" | "deploy_bundlePartial" | "deploy_bundleSelection" | "deploy_transportBodyLimitInvalid" | "deploy_transportKeyRingInvalid" | "deploy_uploadPasswordPrompt" | "deploy_uploadPasswordUnavailable" | "deploy_uploadPasswordCancelled" | "deploy_uploadPasswordInvalid" | "deploy_managedSecretsInvalid" | "
|
|
1080
|
+
declare const deployM: (key: "deploy_composeHostAddressInvalid" | "deploy_composeHostnameInvalid" | "deploy_composeHostnameConflict" | "deploy_composeProviderRequired" | "deploy_composeServiceUnavailable" | "deploy_notInitialized" | "deploy_initFailed" | "deploy_unsupportedProviderType" | "deploy_unsupportedProvisionerType" | "deploy_configTokenRequired" | "deploy_authRequired" | "deploy_authFailed" | "deploy_projectCreateFailed" | "deploy_uploadFailed" | "deploy_deployFailed" | "deploy_provisionFailed" | "deploy_adapterMissing" | "deploy_scanFailed" | "deploy_envVarFailed" | "deploy_credentialError" | "deploy_credentialInvalidKey" | "deploy_credentialSaved" | "deploy_credentialLoaded" | "deploy_configError" | "deploy_credentialMissing" | "deploy_apiError" | "deploy_fileUploadFailed" | "deploy_provisionNoResult" | "deploy_recoveryFailure" | "deploy_recoverySuggestion" | "deploy_commandTimeout" | "deploy_commandFailed" | "deploy_remoteConnectFailed" | "deploy_remoteRuntimeMissing" | "deploy_imageTransferFailed" | "deploy_healthCheckFailed" | "deploy_invalidEnvironment" | "deploy_environmentMissing" | "deploy_environmentReadFailed" | "deploy_environmentWriteFailed" | "deploy_multipleApplications" | "deploy_purposeSqlite" | "deploy_purposeDatabase" | "deploy_purposeMemory" | "deploy_purposeLocal" | "deploy_purposeCache" | "deploy_purposeStorage" | "deploy_purposeVector" | "deploy_purposeDisabled" | "deploy_purposeLdap" | "deploy_purposeConsole" | "deploy_purposeEmail" | "deploy_purposeSms" | "deploy_webProxyInvalid" | "deploy_webBaseConflict" | "deploy_storageProxyInvalid" | "deploy_storagePublicEndpointInvalid" | "deploy_storageBackendRequired" | "deploy_artifactInvalid" | "deploy_sshRequired" | "deploy_sshPasswordInvalid" | "deploy_sshAskpassFailed" | "deploy_sshAskpassCleanupFailed" | "deploy_targetAuth" | "deploy_targetPasswordEnv" | "deploy_bundleInstructions" | "deploy_bundleApplyGuide" | "deploy_bundleMetadata" | "deploy_targetHost" | "deploy_targetPort" | "deploy_targetUsername" | "deploy_targetIdentityFile" | "deploy_targetKnownHostsFile" | "deploy_targetStrictHostKeyChecking" | "deploy_targetConnectTimeoutSeconds" | "deploy_targetDirectory" | "deploy_targetBundle" | "deploy_bundleOnlyContainer" | "deploy_selectedContainerOnly" | "deploy_selectionInvalid" | "deploy_imageVersionRequired" | "deploy_bundleRuntimeRequired" | "deploy_bundleFailed" | "deploy_configFileInvalid" | "deploy_configFileUnreadable" | "deploy_bundleNameInvalid" | "deploy_localStopped" | "deploy_localUnknown" | "deploy_localNotStarted" | "deploy_commandOutputFailed" | "deploy_commandInputFailed" | "deploy_commandTreeActive" | "deploy_commandExecutionFailed" | "deploy_remoteUnknown" | "deploy_remoteFinished" | "deploy_bundleDirectoryExists" | "deploy_bundleFull" | "deploy_bundlePartial" | "deploy_bundleSelection" | "deploy_transportBodyLimitInvalid" | "deploy_transportKeyRingInvalid" | "deploy_uploadPasswordPrompt" | "deploy_uploadPasswordUnavailable" | "deploy_uploadPasswordCancelled" | "deploy_uploadPasswordInvalid" | "deploy_managedSecretsInvalid" | "deploy_projectNameRequired" | "deploy_requestAccessInvalid" | "deploy_httpsPortsInvalid" | "deploy_httpsCertificateInvalid" | "deploy_bundleRuntime" | "deploy_refreshCookieSecureInvalid" | "deploy_postgresPasswordConflict" | "deploy_bundleVariables" | "deploy_bundleHttpOnly" | "deploy_bundleHttps" | "deploy_bundleAcme" | "deploy_bundleAccounts" | "deploy_bundleDirectories" | "deploy_downloadInvalid" | "deploy_imageSourceMissing" | "deploy_proxySystemUnsupported" | "deploy_middlewareFieldInvalid" | "deploy_middlewareFieldError" | "deploy_middlewareRequired" | "deploy_middlewareInteger" | "deploy_middlewareBoolean" | "deploy_middlewareUrl" | "deploy_middlewareS3Endpoint" | "deploy_middlewareTlsSyntax" | "deploy_middlewareMysqlTls" | "deploy_middlewarePostgresTls" | "deploy_middlewareHeaders" | "deploy_middlewareMethod" | "deploy_configResolutionFailed" | "deploy_reachEmptyProviderOverride" | "deploy_s3Engine" | "deploy_downloadUnavailableTitle" | "deploy_downloadUnavailableInstruction", options?: _h_ai_core.MessageOptions) => string;
|
|
1081
1081
|
|
|
1082
1082
|
/**
|
|
1083
1083
|
* 部署中间件的后端与连接字段目录,供扫描、CLI 和容器规划共同使用。
|
|
@@ -1368,37 +1368,5 @@ declare function getDeployCommandState(error: HaiError): DeployCommandState | un
|
|
|
1368
1368
|
*/
|
|
1369
1369
|
declare function getDeployRecovery(error: HaiError): DeployRecoveryInfo | undefined;
|
|
1370
1370
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
/**
|
|
1374
|
-
* 在目标服务器导入前核验旧凭据;dryRun 默认 true,apply 需要 Linux flock 与运行中的原服务。
|
|
1375
|
-
* 输入文件必须由操作者明确指定,权限 0600;API 不读取旧部署包猜测密码。
|
|
1376
|
-
* @param options - 服务器项目目录、受保护的导入 JSON、容器引擎和只读开关。
|
|
1377
|
-
* @param options.directory - 目标 Linux 服务器上已存在的项目部署目录。
|
|
1378
|
-
* @param options.inputFile - 操作者提供的版本化私有 JSON 文件路径。
|
|
1379
|
-
* @param options.runtime - 实际使用的 Docker 或 Podman 引擎。
|
|
1380
|
-
* @param options.dryRun - 默认 true;只有显式 false 才在部署锁内保存状态。
|
|
1381
|
-
* @returns 仅包含项目、凭据组和卷名的回执,不包含密码;失败不推进 current 或改变服务。
|
|
1382
|
-
* @example
|
|
1383
|
-
* ```ts
|
|
1384
|
-
* import { importDeploymentSecrets } from '@h-ai/deploy'
|
|
1385
|
-
* const plan = await importDeploymentSecrets({ directory: '/opt/hai/apps/shop-test', inputFile: '/private/shop-import.json', runtime: 'docker' })
|
|
1386
|
-
* if (!plan.success) throw new Error(plan.error.message)
|
|
1387
|
-
* // 停止业务写入、备份数据后,用相同输入显式传 dryRun: false 导入。
|
|
1388
|
-
* ```
|
|
1389
|
-
*/
|
|
1390
|
-
declare function importDeploymentSecrets(options: {
|
|
1391
|
-
directory: string;
|
|
1392
|
-
inputFile: string;
|
|
1393
|
-
runtime: 'docker' | 'podman';
|
|
1394
|
-
dryRun?: boolean;
|
|
1395
|
-
}): Promise<HaiResult<{
|
|
1396
|
-
projectName: string;
|
|
1397
|
-
stateVersion: 2;
|
|
1398
|
-
groups: string[];
|
|
1399
|
-
volumes: string[];
|
|
1400
|
-
changed: boolean;
|
|
1401
|
-
}>>;
|
|
1402
|
-
|
|
1403
|
-
export { DEPLOY_MIDDLEWARE, DeployConfigSchema, DeploymentArtifactSchema, HaiDeployError, ProviderConfigSchema, artifactChecksum, canKeepMiddleware, createDeploymentPlan, deploy, describeMiddlewareBackend, getDeployCommandState, getDeployRecovery, importDeploymentSecrets, loadDeploymentConfig, loadDeploymentEnvironment, mergeEnvironmentLayers, normalizeProjectName, parseMiddlewareField, readDeploymentArtifact, resolveDownloadProxy, resolveImageReference, saveDeploymentEnvironment, saveMiddlewareEnvironment, validateMiddlewareField };
|
|
1371
|
+
export { DEPLOY_MIDDLEWARE, DeployConfigSchema, DeploymentArtifactSchema, HaiDeployError, ProviderConfigSchema, artifactChecksum, canKeepMiddleware, createDeploymentPlan, deploy, describeMiddlewareBackend, getDeployCommandState, getDeployRecovery, loadDeploymentConfig, loadDeploymentEnvironment, mergeEnvironmentLayers, normalizeProjectName, parseMiddlewareField, readDeploymentArtifact, resolveDownloadProxy, resolveImageReference, saveDeploymentEnvironment, saveMiddlewareEnvironment, validateMiddlewareField };
|
|
1404
1372
|
export type { DeployAppOptions, DeployCommandState, DeployConfig, DeployConfigInput, DeployCredentialOperations, DeployError, DeployFunctions, DeployRecoveryInfo, DeployResult, DeployScanOptions, DeploymentArtifact, DeploymentEnvironment, DockerSshProviderConfig, DownloadProxyConfig, ImageSourceConfig, MiddlewareBackend, MiddlewareField, MiddlewareMode, MiddlewareRequirement, PortExposeConfig, ProvisionResult, ScanResult, ServiceType, SshConfig };
|