@stacksjs/ts-cloud 0.2.27 → 0.3.1

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.
@@ -6,3 +6,5 @@ export * from './site-target';
6
6
  export * from './static-site';
7
7
  export * from './static-site-external-dns';
8
8
  export * from './static-site-helper';
9
+ export { buildFunctionEnv, type CodeSource, deployServerlessApp, type DeployServerlessOptions, infraEnvFromOutputs, redeployServerlessApp, type ResolvedContext, rollbackServerlessApp, runRemoteCommand, setMaintenance, } from './serverless-app';
10
+ export { buildAndPushServerlessImage, type BuildImageOptions, type BuiltImage, } from './serverless-image';
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Serverless application deploy orchestrator (Laravel-Vapor-equivalent).
3
+ *
4
+ * Drives the full pipeline for `environments.<env>.app`:
5
+ * build hooks → package → ensure artifact bucket → upload artifact →
6
+ * deploy/update CloudFormation stack → update function code + env →
7
+ * sync assets → run deploy hooks → health check.
8
+ *
9
+ * Plus the operational verbs: redeploy (no rebuild), rollback (previous
10
+ * release), and maintenance mode (down/up).
11
+ */
12
+ import type { CloudConfig, EnvironmentType, ServerlessAppConfig } from '@ts-cloud/core';
13
+ export interface DeployServerlessOptions {
14
+ /** Project root for entry resolution + build hooks. @default process.cwd() */
15
+ projectRoot?: string;
16
+ /** Skip the local build hooks (already run). */
17
+ skipBuild?: boolean;
18
+ /** Skip running the post-deploy `deploy` hooks. */
19
+ skipDeployHooks?: boolean;
20
+ /** Skip the post-deploy HTTP health check. */
21
+ skipHealthCheck?: boolean;
22
+ }
23
+ export interface ResolvedContext {
24
+ app: ServerlessAppConfig;
25
+ slug: string;
26
+ region: string;
27
+ stackName: string;
28
+ artifactBucket: string;
29
+ assetsBucket: string;
30
+ }
31
+ /**
32
+ * Derive framework env vars (DB/Redis hosts) from the deployed stack outputs so
33
+ * a Laravel app connects to the Aurora/RDS-Proxy/ElastiCache resources the
34
+ * composer created. Returns an empty map when nothing data-related is attached.
35
+ */
36
+ export declare function infraEnvFromOutputs(app: ServerlessAppConfig, outputs: Record<string, string>): Record<string, string>;
37
+ /** Build the complete environment for one function. Exported for testing. */
38
+ export declare function buildFunctionEnv(app: ServerlessAppConfig, ctx: ResolvedContext, environment: EnvironmentType, mode: 'http' | 'queue' | 'cli', secrets: Record<string, string>, assetUrl: string | undefined, queueName: string | undefined, infraEnv?: Record<string, string>): Record<string, string>;
39
+ /** Code source for a function update: an S3 zip or an ECR image. */
40
+ export type CodeSource = {
41
+ kind: 'zip';
42
+ bucket: string;
43
+ key: string;
44
+ } | {
45
+ kind: 'image';
46
+ imageUri: string;
47
+ };
48
+ export declare function deployServerlessApp(config: CloudConfig, environment: EnvironmentType, opts?: DeployServerlessOptions): Promise<void>;
49
+ export declare function redeployServerlessApp(config: CloudConfig, environment: EnvironmentType): Promise<void>;
50
+ export declare function rollbackServerlessApp(config: CloudConfig, environment: EnvironmentType): Promise<void>;
51
+ export declare function setMaintenance(config: CloudConfig, environment: EnvironmentType, enabled: boolean, bypassSecret?: string): Promise<void>;
52
+ /** Invoke the CLI function with an arbitrary command (e.g. `cloud command "migrate"`). */
53
+ export declare function runRemoteCommand(config: CloudConfig, environment: EnvironmentType, command: string): Promise<string>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Container-image build + push for serverless apps using `packaging: 'image'`.
3
+ *
4
+ * Stages a Docker build context (app files + a generated Dockerfile, plus the
5
+ * PHP runtime assets for PHP apps), builds the image, ensures an ECR repository,
6
+ * logs in, and pushes a content-tagged image. Returns the image URI the deploy
7
+ * orchestrator passes to CloudFormation + UpdateFunctionCode.
8
+ */
9
+ import type { ServerlessAppConfig } from '@ts-cloud/core';
10
+ export interface BuildImageOptions {
11
+ app: ServerlessAppConfig;
12
+ projectRoot: string;
13
+ region: string;
14
+ /** ECR repository name (created if missing). */
15
+ repository: string;
16
+ /** Skip local build hooks. */
17
+ skipBuild?: boolean;
18
+ onStep?: (m: string) => void;
19
+ }
20
+ export interface BuiltImage {
21
+ /** Full image URI including the content tag (repoUri:tag). */
22
+ imageUri: string;
23
+ /** The content tag (artifact hash). */
24
+ tag: string;
25
+ /** Lambda handler strings per function. */
26
+ handlers: {
27
+ http: string;
28
+ queue: string;
29
+ cli: string;
30
+ };
31
+ }
32
+ export declare function buildAndPushServerlessImage(opts: BuildImageOptions): Promise<BuiltImage>;
@@ -1,25 +1,29 @@
1
1
  /**
2
- * Provision on-box managed services (Forge single-server model): the database
3
- * engine, cache, and search, plus create the application database + user.
2
+ * Provision on-box managed services (Forge single-server model) via **pantry**:
3
+ * the database engine, cache, and search are installed from the pantry registry
4
+ * and run as boot-time systemd services, plus the application database + user
5
+ * are created. When the app points at a managed/external database instead,
6
+ * install nothing and just wire `.env` — see {@link buildManagedDbEnv}.
4
7
  *
5
- * These run at bootstrap (cloud-init), not on deploy, since installing an
6
- * engine is a machine-level, one-time operation. The app's database
7
- * credentials are referenced from the site's `.env` (`DB_*`). When the app
8
- * points at a managed/external database instead, install nothing and just wire
9
- * `.env` — see {@link buildManagedDbEnv}.
8
+ * pantry services listen on TCP localhost ports (mysql/mariadb 3306, postgres
9
+ * 5432, redis 6379, memcached 11211, meilisearch 7700); DB setup connects over
10
+ * TCP, and the engine clients are on PATH via `pantry env`.
10
11
  */
11
12
  import type { ComputeServicesConfig, DatabaseConfig } from '@ts-cloud/core';
12
13
  /**
13
- * Build apt install + enable commands for each requested on-box service.
14
- * Idempotent: apt install is a no-op when already present.
14
+ * Build pantry install + enable/start commands for each requested on-box
15
+ * service. Idempotent (pantry install/enable/start are no-ops when satisfied).
16
+ * `options.bindPrivate` is accepted for fleet compatibility; pantry's services
17
+ * already bind all interfaces behind the firewall.
15
18
  */
16
- export declare function buildServicesProvisionScript(services?: ComputeServicesConfig, options?: {
19
+ export declare function buildServicesProvisionScript(services?: ComputeServicesConfig, _options?: {
17
20
  bindPrivate?: boolean;
18
21
  }): string[];
19
22
  /**
20
23
  * Build the commands that create the application database + user on the on-box
21
24
  * engine. Idempotent (uses IF NOT EXISTS / existence guards). Returns `[]` when
22
- * the database points at a managed host or lacks a name.
25
+ * the database points at a managed host or lacks a name. The engine client is
26
+ * put on PATH via `pantry env` and connects over TCP localhost.
23
27
  */
24
28
  export declare function buildDatabaseSetupScript(database: DatabaseConfig | undefined, services?: ComputeServicesConfig): string[];
25
29
  /**
@@ -74,3 +74,15 @@ export declare function buildNginxVhost(options: NginxVhostOptions): string;
74
74
  * config, and reload. Re-runnable (overwrites the config + refreshes the symlink).
75
75
  */
76
76
  export declare function buildNginxVhostScript(options: NginxVhostOptions): string[];
77
+ /** Wrapper that runs the pantry-installed nginx binary inside pantry's env. */
78
+ export declare const NGINX_WRAPPER = "/usr/local/bin/ts-cloud-nginx";
79
+ /**
80
+ * Set up ts-cloud-managed nginx on top of the pantry-installed nginx binary:
81
+ * a wrapper that runs nginx within `pantry env` (so it + its shared libs
82
+ * resolve), a full `/etc/nginx/nginx.conf` that `include`s the per-site vhosts,
83
+ * and a systemd unit on :80/:443. Replaces apt's nginx service (pantry's own
84
+ * nginx service serves a minimal :8080 default and isn't started here).
85
+ *
86
+ * Run once at provision time, after the nginx binary is installed.
87
+ */
88
+ export declare function buildNginxServiceScript(projectDir?: string): string[];
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Pantry-based package manager for provisioned servers.
3
+ *
4
+ * Every server dependency ts-cloud installs — PHP, nginx, Composer, the
5
+ * databases/caches/search engines, and the language runtimes — comes from the
6
+ * pantry registry (`registry.pantry.dev`, Hetzner-backed object storage) via
7
+ * the `pantry` CLI instead of apt/ppa/curl installers. Long-running services
8
+ * are managed by pantry's own systemd integration, which runs in **system
9
+ * scope** when provisioning as root (units under `/etc/systemd/system`, started
10
+ * at boot) — see `PANTRY_SERVICE_SCOPE` in pantry's service controller.
11
+ *
12
+ * This module is the single chokepoint for "install package X" / "run service
13
+ * Y" so the Hetzner and AWS bootstrap paths share one implementation. It only
14
+ * emits shell command lines (the convention used across `drivers/shared`); the
15
+ * caller splices them into the Ubuntu cloud-init / SSM bootstrap.
16
+ */
17
+ /**
18
+ * Pantry package domains for the dependencies ts-cloud provisions. Domains
19
+ * (not aliases) are used because aliases aren't guaranteed in every released
20
+ * pantry binary. The recipes live in pantry's `src/packages/*` (e.g. `php.net`
21
+ * is a source build carrying the full Laravel extension matrix).
22
+ */
23
+ export declare const PANTRY_PACKAGES: {
24
+ readonly php: "php.net";
25
+ readonly nginx: "nginx.org";
26
+ readonly composer: "getcomposer.org";
27
+ readonly mysql: "mysql.com";
28
+ readonly mariadb: "mariadb.org";
29
+ readonly postgres: "postgresql.org";
30
+ readonly redis: "redis.io";
31
+ readonly memcached: "memcached.org";
32
+ readonly meilisearch: "meilisearch.com";
33
+ readonly git: "git-scm.com";
34
+ readonly certbot: "certbot.eff.org";
35
+ readonly bun: "bun.sh";
36
+ readonly node: "nodejs.org";
37
+ readonly deno: "deno.land";
38
+ };
39
+ /** Logical package key (`'php'`, `'nginx'`, …). */
40
+ export type PantryPackageKey = keyof typeof PANTRY_PACKAGES;
41
+ /** A fully-qualified pantry package domain (`'php.net'`, `'nginx.org'`, …). */
42
+ export type PantryPackageDomain = (typeof PANTRY_PACKAGES)[PantryPackageKey];
43
+ /** A package to install: a known domain, optionally pinned with `@<version>`. */
44
+ export type PantrySpec = PantryPackageDomain | `${PantryPackageDomain}@${string}`;
45
+ /** Where the `pantry` binary itself is installed (on PATH for all later steps). */
46
+ export declare const PANTRY_INSTALL_DIR = "/usr/local/bin";
47
+ /**
48
+ * Server-side pantry project root. `pantry install` is project-scoped — it
49
+ * writes packages under `<root>/pantry/` and exposes their binaries via
50
+ * `<root>/pantry/.bin`. Provisioning installs everything into this one fixed
51
+ * project so the env (and thus PATH) is stable across deploy/systemd steps.
52
+ */
53
+ export declare const PANTRY_PROJECT_DIR = "/opt/pantry";
54
+ export interface PantryBootstrapOptions {
55
+ /** Pin the pantry CLI version (e.g. `'0.9.39'`). @default latest release */
56
+ version?: string;
57
+ }
58
+ /**
59
+ * Bootstrap the `pantry` CLI on a fresh server (idempotent — skips when already
60
+ * present). Installs to {@link PANTRY_INSTALL_DIR} and selects system-scope
61
+ * service management so `pantry enable/start` provisions boot-time systemd
62
+ * units rather than the per-user units that can't run headlessly.
63
+ */
64
+ export declare function buildPantryBootstrapScript(options?: PantryBootstrapOptions): string[];
65
+ /**
66
+ * Shell snippet that puts the project's pantry-installed binaries (php,
67
+ * composer, …) on PATH for a deploy step. `pantry env` is project-scoped, so it
68
+ * is evaluated from {@link PANTRY_PROJECT_DIR}. Returns a single line to
69
+ * `eval`/source before invoking those binaries.
70
+ */
71
+ export declare function pantryEnvActivation(): string;
72
+ /**
73
+ * Install one or more pantry packages in a single resolve pass. Accepts known
74
+ * domains (optionally `domain@version`). Returns `[]` for an empty list.
75
+ */
76
+ export declare function buildPantryInstallScript(specs: readonly PantrySpec[]): string[];
77
+ /**
78
+ * Enable (start on boot) and start pantry-managed services now. Service names
79
+ * are pantry's own (`'php-fpm'`, `'nginx'`, `'mysql'`, `'redis'`, …), not the
80
+ * package domains.
81
+ */
82
+ export declare function buildPantryServiceScript(services: readonly string[]): string[];
83
+ /** Resolve a logical key (or an explicit domain) to its package domain. */
84
+ export declare function pantryDomain(pkg: PantryPackageKey | PantryPackageDomain): PantryPackageDomain;
@@ -1,38 +1,36 @@
1
1
  /**
2
- * Generate the apt provisioning script for a Forge-style PHP box: nginx,
3
- * one or more PHP-FPM versions (via `ppa:ondrej/php`), the standard Laravel
4
- * extension set, and Composer.
5
- *
6
- * Returns an array of shell command lines (matching the convention of
7
- * {@link import('./rpx-gateway').buildRpxProvisionScript}) so it can be spliced
8
- * into the Ubuntu cloud-init bootstrap. Each requested PHP version installs its
9
- * own `phpX.Y-fpm` pool so different sites can pin different versions and nginx
10
- * can `fastcgi_pass` to the matching unix socket
11
- * (`/run/php/phpX.Y-fpm.sock`).
12
- */
13
- /**
14
- * Baseline PHP extension package suffixes installed for every version
15
- * (`phpX.Y-<suffix>`). Covers Laravel's documented requirements plus the
16
- * common drivers (mysql/pgsql/sqlite/redis) and image/locale/number stack.
2
+ * The baseline Laravel PHP extensions. pantry's `php.net` is a single source
3
+ * build that already bundles these, so unlike apt there are no per-extension
4
+ * packages to install — this list documents the expectation and is asserted
5
+ * against `php -m` in tests.
17
6
  */
18
7
  export declare const LARAVEL_PHP_EXTENSIONS: readonly string[];
19
8
  export interface PhpProvisionOptions {
20
- /** PHP versions to install (e.g. `['8.3', '8.2']`). @default ['8.3'] */
9
+ /** PHP versions to install (first is the default). pantry runs one php-fpm. @default ['8.3'] */
21
10
  versions?: string[];
22
- /** Default PHP version (sets the `php` CLI alternative). @default first of `versions` */
11
+ /** Default PHP version. @default first of `versions` */
23
12
  default?: string;
24
- /** Extra extension suffixes beyond {@link LARAVEL_PHP_EXTENSIONS} (e.g. `['imagick']`). */
13
+ /** Extra extensions informational; pantry's php build is fixed. */
25
14
  extensions?: string[];
26
- /** Install + enable nginx. @default true */
15
+ /** Install the nginx binary (the vhost/service is wired separately). @default true */
27
16
  installNginx?: boolean;
28
- /** Install Composer to `/usr/local/bin/composer`. @default true */
17
+ /** Install Composer. @default true */
29
18
  installComposer?: boolean;
30
19
  }
31
- /** Per-version apt package names for the given extension suffixes. */
32
- export declare function phpPackagesForVersion(version: string, extensions: readonly string[]): string[];
33
- /** Absolute php-fpm unix socket path for a version (matches ondrej's layout). */
34
- export declare function phpFpmSocketPath(version: string): string;
20
+ /** PHP-FPM listen address for nginx `fastcgi_pass` (pantry's php-fpm is TCP). */
21
+ export declare const PHP_FPM_LISTEN = "127.0.0.1:9074";
22
+ /**
23
+ * php-fpm `fastcgi_pass` target. The `version` arg is accepted for API
24
+ * compatibility with the old per-version unix sockets; pantry runs a single
25
+ * php-fpm on {@link PHP_FPM_LISTEN}.
26
+ */
27
+ export declare function phpFpmSocketPath(_version?: string): string;
28
+ /** Resolve the default PHP version from the requested set. */
29
+ export declare function resolveDefaultPhpVersion(options?: PhpProvisionOptions): string;
35
30
  /**
36
- * Build the shell command lines that provision PHP-FPM, nginx, and Composer.
31
+ * Build the shell command lines that install PHP-FPM + Composer (+ the nginx
32
+ * binary) via pantry and start php-fpm as a system service. Assumes the pantry
33
+ * CLI is already bootstrapped (see
34
+ * {@link import('./package-manager').buildPantryBootstrapScript}).
37
35
  */
38
36
  export declare function buildPhpProvisionScript(options?: PhpProvisionOptions): string[];
package/dist/index.d.ts CHANGED
@@ -9,8 +9,8 @@ export type { ObjectStorageConfig, ObjectStorageCredentials, ObjectStorageProvid
9
9
  export { keyMatchesFilters, migrateObjectStorage, remapKey, } from './object-storage/migrate';
10
10
  export type { MigrateEndpoint, MigrateError, MigrateOptions, MigratePlanItem, MigrateProgress, MigrateResult, MigrateVerification, } from './object-storage/migrate';
11
11
  export * from './ssl';
12
- export { deployStaticSite, deployStaticSiteFull, uploadStaticFiles, invalidateCache, deleteStaticSite, generateStaticSiteTemplate, deployStaticSiteWithExternalDns, deployStaticSiteWithExternalDnsFull, generateExternalDnsStaticSiteTemplate, deploySite, resolveSiteDeployTarget, resolveSiteKind, validateDeploymentConfig, } from './deploy';
13
- export type { StaticSiteConfig, DeployResult, UploadOptions, ExternalDnsStaticSiteConfig, ExternalDnsDeployResult, DeploySiteConfig, DeploySiteResult, StaticSiteDnsProvider, SiteDeployKind, DeploymentValidationResult, } from './deploy';
12
+ export { deployStaticSite, deployStaticSiteFull, uploadStaticFiles, invalidateCache, deleteStaticSite, generateStaticSiteTemplate, deployStaticSiteWithExternalDns, deployStaticSiteWithExternalDnsFull, generateExternalDnsStaticSiteTemplate, deploySite, resolveSiteDeployTarget, resolveSiteKind, validateDeploymentConfig, buildAndPushServerlessImage, buildFunctionEnv, deployServerlessApp, infraEnvFromOutputs, redeployServerlessApp, rollbackServerlessApp, runRemoteCommand, setMaintenance, } from './deploy';
13
+ export type { StaticSiteConfig, DeployResult, UploadOptions, ExternalDnsStaticSiteConfig, ExternalDnsDeployResult, DeploySiteConfig, DeploySiteResult, StaticSiteDnsProvider, SiteDeployKind, DeploymentValidationResult, BuildImageOptions, BuiltImage, CodeSource, DeployServerlessOptions, ResolvedContext, } from './deploy';
14
14
  export { createCloudDriver, CloudDriverFactory, cloudDrivers, AwsDriver, HetznerDriver, HetznerClient, resolveHetznerApiToken, generateUbuntuAppCloudInit, wrapCloudInitUserData, buildSiteDeployScript, buildStaticSiteDeployScript, resolveExecStart, deployAllComputeSites, deploySiteRelease, } from './drivers';
15
15
  export type { CreateCloudDriverOptions } from './drivers/factory';
16
16
  export { createDnsProvider, detectDnsProvider, DnsProviderFactory, dnsProviders, PorkbunProvider, GoDaddyProvider, Route53Provider, UnifiedDnsValidator, createPorkbunValidator, createGoDaddyValidator, createRoute53Validator, } from './dns';