Skip to content

Commit 682e439

Browse files
Merge branch 'init' into packaging
2 parents 7d5c048 + 7ec5ee8 commit 682e439

20 files changed

Lines changed: 74 additions & 51 deletions

File tree

cli/README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ npx powersync --version
4242
The PowerSync CLI lets you manage PowerSync instances and run commands (generate schemas, tokens, validate config, fetch status, and more). Support is split into two modes:
4343

4444
- **Cloud** – Full support for [PowerSync Cloud](https://powersync.com). You can create new instances, deploy and pull config from the Dashboard, and run all Cloud commands. Authenticate with **`powersync login`** (or the `PS_ADMIN_TOKEN` env var), then use **`powersync init cloud`** / **`powersync link cloud`** or **`powersync pull instance`** to work with projects.
45-
- **Self-hosted** – Limited support for your own PowerSync Service. You link to an existing running instance and can run a subset of commands (e.g. **`powersync fetch status`**, **`powersync generate schema`**, **`powersync validate`**). The CLI does not create, deploy to, or pull config from self-hosted instances; you manage the server and its config yourself. We also expose a [PowerSync Docker topic](../plugins/docker/README.md) for local self-hosted development.
45+
- **Self-hosted** – Limited support for your own PowerSync Service. You link to an existing running instance and can run a subset of commands (e.g. **`powersync status`**, **`powersync generate schema`**, **`powersync validate`**). The CLI does not create, deploy to, or pull config from self-hosted instances; you manage the server and its config yourself. We also expose a [PowerSync Docker topic](../plugins/docker/README.md) for local self-hosted development.
4646

4747
The sections below go into detail for [Cloud](#cloud) and [Self-hosted](#self-hosted).
4848

@@ -126,7 +126,7 @@ To refresh local config after external edits from the cloud when already linked,
126126

127127
## Running commands against externally managed instances
128128

129-
You can run CLI commands (e.g. **`powersync generate schema`**, **`powersync generate token`**, **`powersync fetch status`**) against a Cloud instance whose configuration is managed elsewhere—for example in the PowerSync Dashboard. No local config directory or link file is required.
129+
You can run CLI commands (e.g. **`powersync generate schema`**, **`powersync generate token`**, **`powersync status`**) against a Cloud instance whose configuration is managed elsewhere—for example in the PowerSync Dashboard. No local config directory or link file is required.
130130

131131
Specify the instance using **environment variables** or **CLI flags** (flags take precedence): `--instance-id` and `--project-id` (or `INSTANCE_ID`, `PROJECT_ID`). **`--org-id` is optional**: when omitted, the CLI uses the token’s single organization if the token has access to exactly one; if the token has multiple orgs, you must pass **`--org-id`** (or set `ORG_ID`).
132132

@@ -143,7 +143,7 @@ powersync generate schema --output-path=schema.ts --output=ts
143143

144144
# Self-hosted
145145

146-
The CLI can run a subset of commands against **self-hosted** PowerSync instances (your own API). Self-hosted support is more limited than Cloud: you link to an existing running API and use the same config directory concept, but only certain commands apply (e.g. **`powersync fetch status`**, **`powersync generate schema`**, **`powersync generate token`**, **`powersync validate`**). There is no **deploy** or **pull instance** for self-hosted; you manage config on the server yourself.
146+
The CLI can run a subset of commands against **self-hosted** PowerSync instances (your own API). Self-hosted support is more limited than Cloud: you link to an existing running API and use the same config directory concept, but only certain commands apply (e.g. **`powersync status`**, **`powersync generate schema`**, **`powersync generate token`**, **`powersync validate`**). There is no **deploy** or **pull instance** for self-hosted; you manage config on the server yourself.
147147

148148
## Authentication
149149

@@ -169,13 +169,13 @@ The CLI resolves **`!env PS_ADMIN_TOKEN`** from the `PS_ADMIN_TOKEN` environment
169169

170170
## Creating a self-hosted project and limitations
171171

172-
Run **`powersync init self-hosted`** to scaffold a config directory. Edit **`service.yaml`** with your instance details and use **`!env`** for secrets. This gives you a **partial** project: the CLI does not create or provision a self-hosted instance. You must already have a running PowerSync API. The CLI cannot deploy config to or pull config from a self-hosted instance; you manage **`service.yaml`** and **`sync-config.yaml`** on the server yourself. Use the CLI to link (**`powersync link self-hosted --api-url <url>`**), then run the supported commands (e.g. **`powersync fetch status`**, **`powersync generate schema`**) against that API.
172+
Run **`powersync init self-hosted`** to scaffold a config directory. Edit **`service.yaml`** with your instance details and use **`!env`** for secrets. This gives you a **partial** project: the CLI does not create or provision a self-hosted instance. You must already have a running PowerSync API. The CLI cannot deploy config to or pull config from a self-hosted instance; you manage **`service.yaml`** and **`sync-config.yaml`** on the server yourself. Use the CLI to link (**`powersync link self-hosted --api-url <url>`**), then run the supported commands (e.g. **`powersync status`**, **`powersync generate schema`**) against that API.
173173

174174
```sh
175175
powersync init self-hosted
176176
# then edit powersync/service.yaml
177177
powersync link self-hosted --api-url https://powersync.example.com
178-
powersync fetch status
178+
powersync status
179179
```
180180

181181
Use `--directory` for a different config folder.
@@ -186,7 +186,7 @@ We expose a [PowerSync Docker topic](../plugins/docker/README.md) for running a
186186

187187
## Command support
188188

189-
Only some CLI commands work with self-hosted instances. Supported commands include **`powersync fetch status`**, **`powersync generate schema`**, **`powersync generate token`**, **`powersync validate`**, and **`powersync link self-hosted`**. Cloud-only commands such as **`powersync deploy`**, **`powersync destroy`**, **`powersync pull instance`**, **`powersync fetch config`**, and **`powersync fetch instances`** do not apply to self-hosted.
189+
Only some CLI commands work with self-hosted instances. Supported commands include **`powersync status`**, **`powersync generate schema`**, **`powersync generate token`**, **`powersync validate`**, and **`powersync link self-hosted`**. Cloud-only commands such as **`powersync deploy`**, **`powersync destroy`**, **`powersync pull instance`**, **`powersync fetch config`**, and **`powersync fetch instances`** do not apply to self-hosted.
190190

191191
# Known Limitations
192192

@@ -245,7 +245,7 @@ You can supply instance and auth context via environment variables (useful for C
245245
Example (Cloud):
246246

247247
```sh
248-
PS_ADMIN_TOKEN=your-token PROJECT_ID=456 INSTANCE_ID=789 powersync fetch status
248+
PS_ADMIN_TOKEN=your-token PROJECT_ID=456 INSTANCE_ID=789 powersync status
249249
```
250250

251251
See [docs/usage.md](../docs/usage.md) for full usage and resolution order (flags, env, cli.yaml).
@@ -561,7 +561,7 @@ DESCRIPTION
561561

562562
Run `docker compose down` then `docker compose up -d --wait`: stops and removes containers, then starts the stack and
563563
waits for services (including PowerSync) to be healthy. Use when you want a clean bring-up (e.g. after config
564-
changes). Use `powersync fetch status` to debug running instances.
564+
changes). Use `powersync status` to debug running instances.
565565

566566
EXAMPLES
567567
$ powersync docker reset
@@ -587,7 +587,7 @@ DESCRIPTION
587587
Start the self-hosted PowerSync stack via Docker Compose.
588588

589589
Runs `docker compose up -d --wait` for the project docker/ compose file; waits for services (including PowerSync) to
590-
be healthy. Use `powersync fetch status` to debug running instances.
590+
be healthy. Use `powersync status` to debug running instances.
591591

592592
EXAMPLES
593593
$ powersync docker start

cli/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@
122122
"build": "tsc -b && pnpm prepack",
123123
"lint": "eslint",
124124
"postpack": "shx rm -f oclif.manifest.json",
125-
"posttest": "pnpm run lint",
126125
"pretest": "pnpm run build",
127126
"readme:generate": "oclif readme && pnpm exec prettier --write README.md",
128127
"prepack": "oclif manifest && pnpm run readme:generate",

cli/src/commands/deploy/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ export default class DeployAll extends CloudInstanceCommand {
317317
sync_rules: project.syncRulesContent ?? ''
318318
})
319319
.catch((error) => {
320-
if (retry === 9) {
320+
if (retry === 99) {
321321
this.styledError({
322322
error,
323323
message: `Failed to validate sync config for instance ${project.linked.instance_id} in project ${project.linked.project_id} in org ${project.linked.org_id}. Ensure the sync config is valid before deploying.`,
@@ -342,6 +342,9 @@ export default class DeployAll extends CloudInstanceCommand {
342342
suggestions: ['Check your sync config and try again.']
343343
});
344344
}
345+
346+
// Validation succeeded with no errors
347+
return;
345348
}
346349
}
347350

@@ -381,7 +384,7 @@ export default class DeployAll extends CloudInstanceCommand {
381384
this.log(ux.colorize('green', 'Deployment operation completed successfully!'));
382385
} else {
383386
this.styledError({
384-
message: `Deploy failed. Check instance diagnostics for details, for example: ${ux.colorize('blue', 'powersync fetch status')}`
387+
message: `Deploy failed. Check instance diagnostics for details, for example: ${ux.colorize('blue', 'powersync status')}`
385388
});
386389
}
387390
}

cli/src/commands/deploy/sync-config.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { ux } from '@oclif/core/ux';
22
import { routes } from '@powersync/management-types';
33

4+
import { DEFAULT_DEPLOY_TIMEOUT_MS } from '../../api/cloud/wait-for-operation.js';
45
import DeployAll from './index.js';
56

6-
export class DeploySyncConfig extends DeployAll {
7+
export default class DeploySyncConfig extends DeployAll {
78
static description = 'Deploy only sync config changes.';
89
static examples = [
910
'<%= config.bin %> <%= command.id %>',
@@ -55,7 +56,7 @@ export class DeploySyncConfig extends DeployAll {
5556
}
5657

5758
async run(): Promise<void> {
58-
const { flags } = await this.parse(DeployAll);
59+
const { flags } = await this.parse(DeploySyncConfig);
5960

6061
const project = await this.loadProject(flags, {
6162
// We don't need the config to be managed locally for this
@@ -65,6 +66,8 @@ export class DeploySyncConfig extends DeployAll {
6566
const { linked } = project;
6667
this.parseConfig(project.projectDirectory);
6768

69+
const deployTimeoutMs = (flags['deploy-timeout'] ?? DEFAULT_DEPLOY_TIMEOUT_MS / 1000) * 1000;
70+
6871
// The existing config is required to deploy changes. The instance should have been created already.
6972
const cloudConfigState = await this.loadCloudConfigState();
7073

@@ -97,7 +100,7 @@ export class DeploySyncConfig extends DeployAll {
97100
`\nThe instance is not currently provisioned. Triggering a deploy in order to reprovision. This may take a few minutes.\n`
98101
);
99102
// Don't yet update the sync config since the instance is not provisioned, but deploy to trigger provisioning
100-
await this.deployAll({ cloudConfigState, deployTimeoutMs: flags.timeout, updateSyncConfig: false });
103+
await this.deployAll({ cloudConfigState, deployTimeoutMs, updateSyncConfig: false });
101104
}
102105

103106
// Validate sync config
@@ -106,6 +109,6 @@ export class DeploySyncConfig extends DeployAll {
106109

107110
this.log('Validations completed successfully.\n');
108111

109-
await this.deploySyncConfig({ cloudConfigState, timeout: flags.timeout });
112+
await this.deploySyncConfig({ cloudConfigState, timeout: deployTimeoutMs });
110113
}
111114
}

cli/src/commands/destroy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export default class Destroy extends CloudInstanceCommand {
5656
this.log(ux.colorize('green', 'Instance destroyed successfully.'));
5757
} else {
5858
this.styledError({
59-
message: `Operation failed. Check instance diagnostics for details, for example: ${ux.colorize('blue', 'powersync fetch status')}`
59+
message: `Operation failed. Check instance diagnostics for details, for example: ${ux.colorize('blue', 'powersync status')}`
6060
});
6161
}
6262
} catch (error) {

cli/src/commands/link/cloud.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,14 @@ export default class LinkCloud extends CloudInstanceCommand {
8989
this.styledError({ error, message: 'Failed to create Cloud instance' });
9090
}
9191

92-
const projectDir = this.ensureProjectDirectory({ directory });
9392
ensureServiceTypeMatches({
9493
command: this,
9594
configRequired: false,
9695
directoryLabel: directory,
9796
expectedType: ServiceType.CLOUD,
98-
projectDir
97+
projectDir: projectDirectory
9998
});
100-
writeCloudLink(projectDir, { instanceId: newInstanceId, orgId, projectId });
99+
writeCloudLink(projectDirectory, { instanceId: newInstanceId, orgId, projectId });
101100
this.log(
102101
ux.colorize('green', `Created Cloud instance ${newInstanceId} and updated ${directory}/${CLI_FILENAME}.`)
103102
);

cli/src/commands/logout.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export default class Logout extends PowerSyncCommand {
88
static summary = 'Remove stored auth token.';
99

1010
async run(): Promise<void> {
11+
await this.parse(Logout);
1112
const { authentication } = Services;
1213

1314
const token = await authentication.getToken();

cli/src/commands/stop.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export default class Stop extends CloudInstanceCommand {
5858
this.log(ux.colorize('green', 'Instance stopped successfully.'));
5959
} else {
6060
this.styledError({
61-
message: `Operation failed. Check instance diagnostics for details, for example: ${ux.colorize('blue', 'powersync fetch status')}`
61+
message: `Operation failed. Check instance diagnostics for details, for example: ${ux.colorize('blue', 'powersync status')}`
6262
});
6363
}
6464
} catch (error) {

cli/test/commands/link.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ const accountsClientMock = {
2929
listProjects: vi.fn()
3030
};
3131

32-
vi.spyOn(cliCore, 'createAccountsHubClient').mockImplementation(
33-
async () => accountsClientMock as unknown as Awaited<ReturnType<typeof cliCore.createAccountsHubClient>>
32+
vi.spyOn(cliCore, 'createAccountsHubClient').mockResolvedValue(
33+
accountsClientMock as unknown as Awaited<ReturnType<typeof cliCore.createAccountsHubClient>>
3434
);
3535

3636
function writeServiceYaml(projectDir: string, type: 'cloud' | 'self-hosted') {

docs/usage-docker.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Use **`powersync docker reset`** only when you need to start from a clean state:
6868

6969
All of these use the project name from **cli.yaml** unless you pass **`--project-name`** (e.g. to stop from any directory or to target a specific project).
7070

71-
Use **`powersync fetch status`** to debug a running instance.
71+
Use **`powersync status`** to debug a running instance.
7272

7373
---
7474

@@ -127,7 +127,7 @@ powersync docker start --directory=my-powersync
127127
Configure sets **cli.yaml** with **api_url** and **api_key** for the local stack so you can run **fetch status**, **validate**, **generate schema**, etc. without extra flags:
128128

129129
```bash
130-
powersync fetch status
130+
powersync status
131131
powersync validate
132132
powersync generate schema --output=ts --output-path=./schema.ts
133133
```

0 commit comments

Comments
 (0)