ninepm 0.69.0 → 0.72.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.
- package/README.md +63 -10
- package/dist/cli-types.d.ts +2 -0
- package/dist/dns-host.d.ts +7 -0
- package/dist/dns-host.js +27 -0
- package/dist/index.d.ts +182 -6
- package/dist/index.js +686 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,6 +71,19 @@ Check this before printing a link or QR code. The live URL is `<slug>-<suffix>.9
|
|
|
71
71
|
- There is no rename: a different address means a different app.
|
|
72
72
|
- A custom domain you own, added on the dashboard's Domains page, gives the app an address of your own. Not every plan includes custom domains.
|
|
73
73
|
|
|
74
|
+
### Pages that do not exist
|
|
75
|
+
|
|
76
|
+
A static site or `--entry` worker app answers a path that has no file in one of two ways. Every deploy prints which, as a `Missing pages:` line.
|
|
77
|
+
|
|
78
|
+
- `--no-spa` (the default for new apps): the path returns status 404, with the deploy's own `404.html` when it has one. `/` still serves `index.html`, and extensionless links work: `/menu` serves `menu.html`, or redirects to `/menu/` when only `menu/index.html` exists, and `/menu/` serves `menu/index.html`. Right for a multi-page site, where a removed or mistyped page should say "not found" rather than show the homepage.
|
|
79
|
+
- `--spa`: every path with no file serves `index.html`, so a single-page app that routes in the browser loads on a deep link or a refresh. That includes dotted paths such as `/users/jane.smith` and missing files such as `/missing.json`, which get the app's shell rather than a 404.
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
9pm deploy ./dist --name my-spa --spa
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The app remembers the choice: a deploy without either flag keeps it, and a deploy that fails to publish leaves the previous choice in place. Apps created before this choice existed keep serving `index.html` for every unmatched path until a deploy passes one of the flags. A worker app's own `Response`, a 404 included, is always returned as it is. The flags do not apply to `--bundle` or container apps.
|
|
86
|
+
|
|
74
87
|
Deploy a built framework output directory:
|
|
75
88
|
|
|
76
89
|
```sh
|
|
@@ -152,12 +165,14 @@ The app's address goes with it: creating an app again under the same slug gives
|
|
|
152
165
|
|
|
153
166
|
Apps are public by default.
|
|
154
167
|
|
|
168
|
+
Changing an app's access mode needs `--switch-mode`. Without it the command changes nothing and prints what the change would do (who loses access, what happens to the app's custom domains) and the command to re-run. Service-token mode locks every person out and removes the app's custom domains; leaving it sets them up again with new DNS records to publish. Creating another service token on an app already in service-token mode needs no flag.
|
|
169
|
+
|
|
155
170
|
One-time PIN with email/domain allowlist:
|
|
156
171
|
|
|
157
172
|
```sh
|
|
158
173
|
9pm access allow email my-app dev@example.com
|
|
159
174
|
9pm access allow domain my-app example.com
|
|
160
|
-
9pm access otp my-app
|
|
175
|
+
9pm access otp my-app --switch-mode
|
|
161
176
|
9pm access revoke email my-app dev@example.com
|
|
162
177
|
9pm access revoke domain my-app example.com
|
|
163
178
|
```
|
|
@@ -165,19 +180,19 @@ One-time PIN with email/domain allowlist:
|
|
|
165
180
|
Identity provider access:
|
|
166
181
|
|
|
167
182
|
```sh
|
|
168
|
-
9pm access idp my-app --provider google
|
|
183
|
+
9pm access idp my-app --provider google --switch-mode
|
|
169
184
|
```
|
|
170
185
|
|
|
171
186
|
Machine access:
|
|
172
187
|
|
|
173
188
|
```sh
|
|
174
|
-
9pm access service create my-app --name backend
|
|
189
|
+
9pm access service create my-app --name backend --switch-mode
|
|
175
190
|
```
|
|
176
191
|
|
|
177
192
|
Return to public:
|
|
178
193
|
|
|
179
194
|
```sh
|
|
180
|
-
9pm access public my-app
|
|
195
|
+
9pm access public my-app --switch-mode
|
|
181
196
|
```
|
|
182
197
|
|
|
183
198
|
Create an app-scoped runtime token for server-side allowlist management:
|
|
@@ -189,11 +204,40 @@ Create an app-scoped runtime token for server-side allowlist management:
|
|
|
189
204
|
Use `9pm_app_...` runtime tokens only from server-side code. They can list, add, and remove email/domain grants for one app. They cannot deploy, create databases, create API keys, or manage another app.
|
|
190
205
|
Service token secrets returned by `access service create` are also server-side secrets.
|
|
191
206
|
|
|
207
|
+
## Custom Domains
|
|
208
|
+
|
|
209
|
+
Connect a domain you own to an app:
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
9pm domains add my-app www.example.com
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
This prints the DNS records to publish at your DNS provider, with names relative to your
|
|
216
|
+
domain (`www`, `_acme-challenge.www`) and what DNS shows for each right now. When a TXT value
|
|
217
|
+
is missing, add it as its own TXT record; other TXT values on that name can stay. The root of
|
|
218
|
+
your domain (`@`) cannot hold a CNAME, so a root domain is shown as an `ALIAS` record: add it as
|
|
219
|
+
ALIAS or ANAME (or a CNAME your provider flattens). A correct ALIAS answers with addresses, which
|
|
220
|
+
cannot be compared from outside, so that row follows the platform's own routing check. Then:
|
|
221
|
+
|
|
222
|
+
```sh
|
|
223
|
+
9pm domains wait my-app www.example.com
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
`wait` exits `0` once the domain is live, `10` if it timed out while a record is missing or could
|
|
227
|
+
not be checked, `11` if it timed out with every record checked and found (the platform is still
|
|
228
|
+
finishing; wait again), `20` if the domain failed or expired, and `1` on a usage, sign-in or API
|
|
229
|
+
error. `9pm domains status <app> <hostname> --json` prints `{hostname, app, state, routing, tls,
|
|
230
|
+
provider, nameservers, records, error, expiresAt, checkedAt}`, where `state` is `live`,
|
|
231
|
+
`waiting_for_dns`, `dns_unverified` (routing is active but the records could not be checked),
|
|
232
|
+
`issuing_certificate`, `failed` or `expired`. Each record's `ok` is `null` when the check cannot
|
|
233
|
+
say, and its `check` says why (`not_checked`, or `apex_addresses`). `list`, `status` and `wait`
|
|
234
|
+
only read; `add`, `check`, `restart` and `remove` need permission to configure the app.
|
|
235
|
+
|
|
192
236
|
## Commands
|
|
193
237
|
|
|
194
238
|
```sh
|
|
195
239
|
9pm --version
|
|
196
|
-
9pm deploy [directory] --name <name> [--slug <slug>] [--with-db]
|
|
240
|
+
9pm deploy [directory] --name <name> [--slug <slug>] [--spa | --no-spa] [--with-db]
|
|
197
241
|
9pm deploy [directory] --check [--runtime worker --entry <path> (--assets <dir> | --no-assets)]
|
|
198
242
|
9pm deploy [directory] --runtime container --port 8080 [--health-path /health] [--region auto] [--with-db]
|
|
199
243
|
9pm signup
|
|
@@ -208,17 +252,24 @@ Service token secrets returned by `access service create` are also server-side s
|
|
|
208
252
|
9pm files get <file-id> [--output <path>] [--project <site>]
|
|
209
253
|
9pm files share <file-id> [--expires 24h] [--public] [--project <site>]
|
|
210
254
|
9pm files delete <file-id> [--project <site>]
|
|
211
|
-
9pm deploy [directory] --runtime worker --entry <path> (--assets <dir> | --no-assets) [--with-db]
|
|
255
|
+
9pm deploy [directory] --runtime worker --entry <path> (--assets <dir> | --no-assets) [--spa | --no-spa] [--with-db]
|
|
212
256
|
9pm delete <site> --confirm <slug>
|
|
257
|
+
9pm domains list [<app>] [--owner <organisation>] [--json]
|
|
258
|
+
9pm domains add <app> <hostname> [--json]
|
|
259
|
+
9pm domains status <app> <hostname> [--json]
|
|
260
|
+
9pm domains check <app> <hostname> [--json]
|
|
261
|
+
9pm domains wait <app> <hostname> [--timeout 30m] [--interval 20s] [--json]
|
|
262
|
+
9pm domains restart <app> <hostname>
|
|
263
|
+
9pm domains remove <app> <hostname> --confirm <hostname>
|
|
213
264
|
9pm access show <site>
|
|
214
|
-
9pm access public <site>
|
|
215
|
-
9pm access otp <site>
|
|
216
|
-
9pm access idp <site> [--provider google|github|entra]
|
|
265
|
+
9pm access public <site> [--switch-mode]
|
|
266
|
+
9pm access otp <site> [--switch-mode]
|
|
267
|
+
9pm access idp <site> [--provider google|github|entra] [--switch-mode]
|
|
217
268
|
9pm access allow email <site> <email>
|
|
218
269
|
9pm access allow domain <site> <domain>
|
|
219
270
|
9pm access revoke email <site> <email>
|
|
220
271
|
9pm access revoke domain <site> <domain>
|
|
221
|
-
9pm access service create <site> [--name <name>] [--duration 8760h]
|
|
272
|
+
9pm access service create <site> [--name <name>] [--duration 8760h] [--switch-mode]
|
|
222
273
|
9pm access service revoke <site> <service-token-id>
|
|
223
274
|
9pm access token create <site> [--name <name>]
|
|
224
275
|
9pm access token revoke <site> <token-id>
|
|
@@ -240,6 +291,8 @@ Options:
|
|
|
240
291
|
- `--entry <path>` selects the Worker runtime server entry file
|
|
241
292
|
- `--assets <dir>` makes only that directory of a worker deploy public (remembered for later deploys)
|
|
242
293
|
- `--no-assets` makes no file of a worker deploy public (remembered for later deploys)
|
|
294
|
+
- `--spa` serves `index.html` for every path that has no file, for single-page apps (remembered for later deploys)
|
|
295
|
+
- `--no-spa` returns 404 for a path that has no file, with the deploy's `404.html` when present; the default for new apps (remembered for later deploys)
|
|
243
296
|
- `--port <port>` selects the HTTP port exposed by a container app
|
|
244
297
|
- `--health-path <path>` optionally lets 9pm.ai check container health before marking it healthy
|
|
245
298
|
- `--region <region>` optionally selects provider-neutral container placement
|
package/dist/cli-types.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type AppRuntime = "static" | "worker" | "container";
|
|
|
8
8
|
export type ContainerRegion = "auto" | "us-east" | "us-west" | "europe" | "asia" | "south-america" | "middle-east" | "oceania" | "africa";
|
|
9
9
|
export type ManagedFileScope = "user" | "project";
|
|
10
10
|
export type ManagedFileShareMode = "public" | "login_required";
|
|
11
|
+
export type MissingPagesMode = "legacy" | "spa" | "404";
|
|
11
12
|
export interface Project {
|
|
12
13
|
id: string;
|
|
13
14
|
name: string;
|
|
@@ -16,6 +17,7 @@ export interface Project {
|
|
|
16
17
|
createdAt: string;
|
|
17
18
|
updatedAt: string;
|
|
18
19
|
workerPublicAssets?: string | null;
|
|
20
|
+
missingPages?: MissingPagesMode;
|
|
19
21
|
}
|
|
20
22
|
export interface AppUserFilesUsage {
|
|
21
23
|
usedBytes: number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** A best guess at the zone a custom hostname lives in: `www.tmrwtitans.com` -> `tmrwtitans.com`. */
|
|
2
|
+
export declare function guessZoneApex(hostname: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* The record name the way most registrars' Host field wants it, relative to the zone:
|
|
5
|
+
* `www.tmrwtitans.com` -> `www`, the apex itself -> `@`. A name outside the zone stays whole.
|
|
6
|
+
*/
|
|
7
|
+
export declare function relativeRecordName(recordHost: string, apex: string): string;
|
package/dist/dns-host.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// AUTO-GENERATED by scripts/generate-cli-package.mjs from the in-repo CLI source -- do not edit.
|
|
2
|
+
// Edit src/cli or src/shared instead; this is regenerated on typecheck/test/build/pack.
|
|
3
|
+
// Record names for a custom domain's DNS instructions, written the way a registrar's Host
|
|
4
|
+
// field wants them. Read by the dashboard's DNS table and by `9pm domains`, and copied into
|
|
5
|
+
// the CLI tarball by scripts/generate-cli-package.mjs, so it must import nothing.
|
|
6
|
+
// Second-level labels that sit under a two-letter country code as part of the public suffix
|
|
7
|
+
// (example.co.uk, example.com.au). Not a public suffix list: it covers the common shapes, and
|
|
8
|
+
// the full name is always shown beside the short one for the cases it misses.
|
|
9
|
+
const SECOND_LEVEL = new Set(["co", "com", "net", "org", "gov", "ac", "edu", "ne", "or", "go"]);
|
|
10
|
+
/** A best guess at the zone a custom hostname lives in: `www.tmrwtitans.com` -> `tmrwtitans.com`. */
|
|
11
|
+
export function guessZoneApex(hostname) {
|
|
12
|
+
const labels = hostname.toLowerCase().replace(/\.$/, "").split(".");
|
|
13
|
+
if (labels.length >= 3 && SECOND_LEVEL.has(labels[labels.length - 2]) && labels[labels.length - 1].length === 2) {
|
|
14
|
+
return labels.slice(-3).join(".");
|
|
15
|
+
}
|
|
16
|
+
return labels.slice(-2).join(".");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The record name the way most registrars' Host field wants it, relative to the zone:
|
|
20
|
+
* `www.tmrwtitans.com` -> `www`, the apex itself -> `@`. A name outside the zone stays whole.
|
|
21
|
+
*/
|
|
22
|
+
export function relativeRecordName(recordHost, apex) {
|
|
23
|
+
const host = recordHost.toLowerCase().replace(/\.$/, "");
|
|
24
|
+
if (host === apex)
|
|
25
|
+
return "@";
|
|
26
|
+
return host.endsWith(`.${apex}`) ? host.slice(0, -(apex.length + 1)) : host;
|
|
27
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export interface DeployOptions {
|
|
|
18
18
|
runtime?: AppRuntime;
|
|
19
19
|
entry?: string;
|
|
20
20
|
publicAssets?: string;
|
|
21
|
+
missingPages?: "spa" | "404";
|
|
21
22
|
port?: number;
|
|
22
23
|
healthPath?: string;
|
|
23
24
|
region?: ContainerRegion;
|
|
@@ -124,7 +125,7 @@ export interface CreatedServiceToken {
|
|
|
124
125
|
clientSecret: string;
|
|
125
126
|
}
|
|
126
127
|
export type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
127
|
-
export declare const CLI_VERSION = "0.
|
|
128
|
+
export declare const CLI_VERSION = "0.72.0";
|
|
128
129
|
type CredentialBackend = "macos-keychain" | "windows-dpapi" | "linux-secret-service" | "file-plaintext" | "none";
|
|
129
130
|
export interface StoredCredentialEntry {
|
|
130
131
|
token: string;
|
|
@@ -225,7 +226,8 @@ export declare class DeployError extends Error {
|
|
|
225
226
|
* prevent (#1061).
|
|
226
227
|
*/
|
|
227
228
|
export declare class DeliberateRefusalError extends Error {
|
|
228
|
-
|
|
229
|
+
readonly code: string | undefined;
|
|
230
|
+
constructor(message: string, code?: string);
|
|
229
231
|
}
|
|
230
232
|
export declare function isDeliberateRefusal(error: unknown): boolean;
|
|
231
233
|
export declare function deployDirectory(initialOptions: DeployOptions): Promise<DeployResult>;
|
|
@@ -271,12 +273,16 @@ export type LogoutSummary = {
|
|
|
271
273
|
};
|
|
272
274
|
export declare function summarizeRevocations(attempts: RevocationAttempt[]): LogoutSummary;
|
|
273
275
|
export declare function getSiteAccess(options: SiteAccessOptions): Promise<AccessState>;
|
|
274
|
-
export declare
|
|
275
|
-
export
|
|
276
|
-
|
|
276
|
+
export declare const ACCESS_MODE_CHANGE_UNCONFIRMED = "access_mode_change_unconfirmed";
|
|
277
|
+
export interface AccessModeChangeOptions extends SiteAccessOptions {
|
|
278
|
+
switchMode?: boolean;
|
|
279
|
+
}
|
|
280
|
+
export declare function setSiteAccessPublic(options: AccessModeChangeOptions): Promise<AccessState["access"]>;
|
|
281
|
+
export declare function setSiteAccessOtp(options: AccessModeChangeOptions): Promise<AccessState["access"]>;
|
|
282
|
+
export declare function setSiteAccessIdp(options: AccessModeChangeOptions & {
|
|
277
283
|
providers?: AccessProviderKey[];
|
|
278
284
|
}): Promise<AccessState["access"]>;
|
|
279
|
-
export declare function createAccessServiceToken(options:
|
|
285
|
+
export declare function createAccessServiceToken(options: AccessModeChangeOptions & {
|
|
280
286
|
name?: string;
|
|
281
287
|
duration?: string;
|
|
282
288
|
}): Promise<CreatedServiceToken>;
|
|
@@ -612,6 +618,36 @@ type CliCommand = {
|
|
|
612
618
|
};
|
|
613
619
|
apiUrl: string;
|
|
614
620
|
token: string;
|
|
621
|
+
} | {
|
|
622
|
+
kind: "domains";
|
|
623
|
+
owner?: string;
|
|
624
|
+
action: {
|
|
625
|
+
kind: "list";
|
|
626
|
+
site?: string;
|
|
627
|
+
json: boolean;
|
|
628
|
+
} | {
|
|
629
|
+
kind: "add" | "status" | "check";
|
|
630
|
+
site: string;
|
|
631
|
+
hostname: string;
|
|
632
|
+
json: boolean;
|
|
633
|
+
} | {
|
|
634
|
+
kind: "wait";
|
|
635
|
+
site: string;
|
|
636
|
+
hostname: string;
|
|
637
|
+
json: boolean;
|
|
638
|
+
timeoutSeconds: number;
|
|
639
|
+
intervalSeconds: number;
|
|
640
|
+
} | {
|
|
641
|
+
kind: "restart";
|
|
642
|
+
site: string;
|
|
643
|
+
hostname: string;
|
|
644
|
+
} | {
|
|
645
|
+
kind: "remove";
|
|
646
|
+
site: string;
|
|
647
|
+
hostname: string;
|
|
648
|
+
};
|
|
649
|
+
apiUrl: string;
|
|
650
|
+
token: string;
|
|
615
651
|
} | {
|
|
616
652
|
kind: "deployments";
|
|
617
653
|
action: {
|
|
@@ -632,13 +668,16 @@ type CliCommand = {
|
|
|
632
668
|
} | {
|
|
633
669
|
kind: "public";
|
|
634
670
|
site: string;
|
|
671
|
+
switchMode?: true;
|
|
635
672
|
} | {
|
|
636
673
|
kind: "otp";
|
|
637
674
|
site: string;
|
|
675
|
+
switchMode?: true;
|
|
638
676
|
} | {
|
|
639
677
|
kind: "idp";
|
|
640
678
|
site: string;
|
|
641
679
|
providers?: AccessProviderKey[];
|
|
680
|
+
switchMode?: true;
|
|
642
681
|
} | {
|
|
643
682
|
kind: "allow";
|
|
644
683
|
site: string;
|
|
@@ -654,6 +693,7 @@ type CliCommand = {
|
|
|
654
693
|
site: string;
|
|
655
694
|
name?: string;
|
|
656
695
|
duration?: string;
|
|
696
|
+
switchMode?: true;
|
|
657
697
|
} | {
|
|
658
698
|
kind: "service-revoke";
|
|
659
699
|
site: string;
|
|
@@ -669,6 +709,7 @@ type CliCommand = {
|
|
|
669
709
|
tokenId: string;
|
|
670
710
|
};
|
|
671
711
|
apiUrl: string;
|
|
712
|
+
apiUrlFrom: ApiUrlSource;
|
|
672
713
|
token: string;
|
|
673
714
|
};
|
|
674
715
|
export declare function parseArgs(argv: string[]): CliCommand;
|
|
@@ -688,7 +729,131 @@ export declare function deploymentsListJson<T extends ListedDeployment>(deployme
|
|
|
688
729
|
serving: boolean;
|
|
689
730
|
}>;
|
|
690
731
|
};
|
|
732
|
+
export interface CliDnsInstruction {
|
|
733
|
+
type: string;
|
|
734
|
+
host: string;
|
|
735
|
+
value: string;
|
|
736
|
+
optional?: boolean;
|
|
737
|
+
}
|
|
738
|
+
export interface CliDomainDnsCheck {
|
|
739
|
+
provider: string | null;
|
|
740
|
+
nameservers: string[];
|
|
741
|
+
records: Array<{
|
|
742
|
+
type: string;
|
|
743
|
+
host: string;
|
|
744
|
+
expected: string;
|
|
745
|
+
current: string[];
|
|
746
|
+
matches: boolean;
|
|
747
|
+
}>;
|
|
748
|
+
}
|
|
749
|
+
export interface CliDomain {
|
|
750
|
+
hostname: string;
|
|
751
|
+
routingStatus: string;
|
|
752
|
+
tlsStatus: string;
|
|
753
|
+
dnsInstructions: CliDnsInstruction[];
|
|
754
|
+
provisioningError: string | null;
|
|
755
|
+
expireAfter?: string | null;
|
|
756
|
+
expiresAt?: string | null;
|
|
757
|
+
dnsCheck?: CliDomainDnsCheck;
|
|
758
|
+
app?: {
|
|
759
|
+
id: string;
|
|
760
|
+
slug: string;
|
|
761
|
+
name: string;
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
export type DomainState = "live" | "waiting_for_dns" | "dns_unverified" | "issuing_certificate" | "failed" | "expired";
|
|
765
|
+
export declare const CUSTOM_DOMAIN_EXPIRED_TEXT = "This domain was removed because its DNS verification was never completed. Add the domain again to retry.";
|
|
766
|
+
export interface DomainRecordStatus {
|
|
767
|
+
type: string;
|
|
768
|
+
name: string;
|
|
769
|
+
fqdn: string;
|
|
770
|
+
expected: string;
|
|
771
|
+
current: string[] | null;
|
|
772
|
+
ok: boolean | null;
|
|
773
|
+
check: DomainRecordCheck;
|
|
774
|
+
apex: boolean;
|
|
775
|
+
optional: boolean;
|
|
776
|
+
}
|
|
777
|
+
export type DomainRecordCheck = "found" | "missing" | "different" | "not_checked" | "apex_addresses";
|
|
778
|
+
export interface DomainStatusJson {
|
|
779
|
+
hostname: string;
|
|
780
|
+
app: string;
|
|
781
|
+
state: DomainState;
|
|
782
|
+
routing: string;
|
|
783
|
+
tls: string;
|
|
784
|
+
provider: string | null;
|
|
785
|
+
nameservers: string[];
|
|
786
|
+
records: DomainRecordStatus[];
|
|
787
|
+
error: string | null;
|
|
788
|
+
expiresAt: string | null;
|
|
789
|
+
checkedAt: string;
|
|
790
|
+
}
|
|
791
|
+
export declare const DOMAIN_WAIT_EXIT: {
|
|
792
|
+
readonly live: 0;
|
|
793
|
+
readonly ownerAction: 10;
|
|
794
|
+
readonly platform: 11;
|
|
795
|
+
readonly failed: 20;
|
|
796
|
+
};
|
|
797
|
+
export declare function domainRecordStatuses(domain: CliDomain): DomainRecordStatus[];
|
|
798
|
+
export declare function deriveDomainState(domain: CliDomain, records?: DomainRecordStatus[]): DomainState;
|
|
799
|
+
export declare function domainStatusJson(domain: CliDomain, app: string, checkedAt: string): DomainStatusJson;
|
|
800
|
+
export declare function domainStateLabel(state: DomainState): string;
|
|
801
|
+
export declare function formatDomainStatus(status: DomainStatusJson, options?: {
|
|
802
|
+
owner?: string;
|
|
803
|
+
}): string[];
|
|
804
|
+
export declare function domainWaitTimeoutMessage(status: DomainStatusJson): string;
|
|
805
|
+
export declare function formatDomainsList(statuses: DomainStatusJson[]): string[];
|
|
806
|
+
export declare class DomainsApiError extends Error {
|
|
807
|
+
readonly status: number;
|
|
808
|
+
readonly code: string | null;
|
|
809
|
+
constructor(message: string, status: number, code: string | null);
|
|
810
|
+
}
|
|
811
|
+
export declare function domainsApiError(status: number, text: string): DomainsApiError;
|
|
812
|
+
export interface DomainCommandOptions extends ApiOptions {
|
|
813
|
+
site: string;
|
|
814
|
+
owner?: string;
|
|
815
|
+
}
|
|
816
|
+
export declare function normalizeDomainArg(value: string): string;
|
|
817
|
+
export declare function listDomainStatuses(options: ApiOptions & {
|
|
818
|
+
site?: string;
|
|
819
|
+
owner?: string;
|
|
820
|
+
now?: () => Date;
|
|
821
|
+
}): Promise<DomainStatusJson[]>;
|
|
822
|
+
export declare function getDomainStatus(options: DomainCommandOptions & {
|
|
823
|
+
hostname: string;
|
|
824
|
+
now?: () => Date;
|
|
825
|
+
}): Promise<DomainStatusJson>;
|
|
826
|
+
export declare function addDomain(options: DomainCommandOptions & {
|
|
827
|
+
hostname: string;
|
|
828
|
+
}): Promise<CliDomain | null>;
|
|
829
|
+
export declare function recheckDomain(options: DomainCommandOptions & {
|
|
830
|
+
hostname: string;
|
|
831
|
+
}): Promise<void>;
|
|
832
|
+
export declare function restartDomain(options: DomainCommandOptions & {
|
|
833
|
+
hostname: string;
|
|
834
|
+
}): Promise<{
|
|
835
|
+
domain: CliDomain;
|
|
836
|
+
replacedInstructions: CliDnsInstruction[];
|
|
837
|
+
}>;
|
|
838
|
+
export declare function removeDomain(options: DomainCommandOptions & {
|
|
839
|
+
hostname: string;
|
|
840
|
+
}): Promise<CliDomain | null>;
|
|
841
|
+
export interface DomainWaitResult {
|
|
842
|
+
status: DomainStatusJson;
|
|
843
|
+
exitCode: number;
|
|
844
|
+
timedOut: boolean;
|
|
845
|
+
}
|
|
846
|
+
export declare function waitForDomain(options: DomainCommandOptions & {
|
|
847
|
+
hostname: string;
|
|
848
|
+
timeoutMs: number;
|
|
849
|
+
intervalMs: number;
|
|
850
|
+
nowMs?: () => number;
|
|
851
|
+
sleepFn?: (ms: number) => Promise<void>;
|
|
852
|
+
onStatus?: (status: DomainStatusJson) => void;
|
|
853
|
+
onRetry?: (error: unknown) => void;
|
|
854
|
+
}): Promise<DomainWaitResult>;
|
|
691
855
|
export declare function healthWithReason(status: string | null | undefined, reason: string | null | undefined): string;
|
|
856
|
+
export type ApiUrlSource = "flag" | "env" | "default";
|
|
692
857
|
export declare function workerPublicFiles(paths: readonly string[], serverEntry: string, selection: string | null): Array<{
|
|
693
858
|
path: string;
|
|
694
859
|
url: string;
|
|
@@ -723,4 +888,15 @@ export declare function hasNoGraphicalDisplay(platform: string, env: Record<stri
|
|
|
723
888
|
export declare function formatAppUserFilesUsageLine(slug: string, usage: AppUserFilesUsage): string;
|
|
724
889
|
export declare class UsageError extends Error {
|
|
725
890
|
}
|
|
891
|
+
export declare function missingPagesLine(deployment: Deployment): string | null;
|
|
892
|
+
type AccessModeChangeAction = Extract<Extract<CliCommand, {
|
|
893
|
+
kind: "access";
|
|
894
|
+
}>["action"], {
|
|
895
|
+
kind: "public" | "otp" | "idp" | "service-create";
|
|
896
|
+
}>;
|
|
897
|
+
export interface AccessApiTarget {
|
|
898
|
+
apiUrl: string;
|
|
899
|
+
apiUrlFrom: ApiUrlSource;
|
|
900
|
+
}
|
|
901
|
+
export declare function accessSwitchModeCommand(action: AccessModeChangeAction, target?: AccessApiTarget): string;
|
|
726
902
|
export {};
|