Skip to content

Commit de9a508

Browse files
authored
feat: Command Line SDK update for version 17.3.0 (#287)
* chore: update Command Line SDK to 17.2.1 * chore: update Command Line SDK to 17.2.1 * chore: update Command Line SDK to 17.2.1 * chore: update Command Line SDK to 17.3.0 * chore: update Command Line SDK to 17.3.0 * chore: update Command Line SDK to 17.3.0
1 parent 9253538 commit de9a508

29 files changed

+5605
-196
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
bun-version: "latest"
3232

3333
- name: Install Node dependencies
34-
run: npm install
34+
run: npm ci
3535

3636
- name: Build project
3737
run: npm run build

.github/workflows/publish.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ jobs:
4343
- name: Setup Node.js
4444
uses: actions/setup-node@v4
4545
with:
46-
node-version: '22'
46+
node-version: '24.14.1'
4747
registry-url: 'https://registry.npmjs.org'
4848

49-
- name: Update npm to latest version for OIDC support
50-
run: npm install -g npm@latest
49+
- name: Pin npm for trusted publishing
50+
run: npm install -g npm@11.10.0
5151

5252
- name: Determine release tag
5353
id: release_tag

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Change Log
22

3+
## 17.3.0
4+
5+
* Added: Automatic update notifications with cached version checks
6+
* Added: `create-json-export` and `create-json-import` migration commands
7+
* Added: `--activate` flag for site push to control deployment activation
8+
* Added: Deployment retention prompt during site initialization
9+
* Updated: Improved `.gitignore` handling with hierarchical ignore support
10+
* Updated: Function and site init now use safe directory names
11+
* Updated: Config writer prunes empty resource arrays and deprecated site fields
12+
* Fixed: Pinned `@appwrite.io/console` dependency to `~8.2.0`
13+
314
## 17.2.1
415

516
* Fixed: Removed `bun.lock` from `.gitignore` so lockfile is tracked in version control

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Once the installation is complete, you can verify the install using
2929

3030
```sh
3131
$ appwrite -v
32-
17.2.1
32+
17.3.0
3333
```
3434

3535
### Install using prebuilt binaries
@@ -60,7 +60,7 @@ $ scoop install https://raw.githubusercontent.com/appwrite/sdk-for-cli/master/sc
6060
Once the installation completes, you can verify your install using
6161
```
6262
$ appwrite -v
63-
17.2.1
63+
17.3.0
6464
```
6565

6666
## Getting Started

bun.lock

Lines changed: 39 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli.ts

Lines changed: 138 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import inquirer from 'inquirer';
1111

1212
import packageJson from './package.json' with { type: 'json' };
1313
import { commandDescriptions, cliConfig } from './lib/parser.js';
14-
import { getLatestVersion, compareVersions } from './lib/utils.js';
14+
import {
15+
getLatestVersion,
16+
compareVersions,
17+
getCachedUpdateNotification,
18+
syncVersionCheckCache,
19+
} from './lib/utils.js';
1520
import inquirerSearchList from 'inquirer-search-list';
1621

1722
import { client } from './lib/commands/generic.js';
@@ -49,6 +54,42 @@ import { webhooks } from './lib/commands/services/webhooks.js';
4954

5055
const { version } = packageJson;
5156
inquirer.registerPrompt('search-list', inquirerSearchList);
57+
const VERSION_CHECK_TIMEOUT_MS = 5000;
58+
59+
function writeUpdateAvailableNotice(currentVersion: string, latestVersion: string, toStderr: boolean = false): void {
60+
const stream = toStderr ? process.stderr : process.stdout;
61+
62+
stream.write(
63+
chalk.yellow(
64+
`\n⚠️ A newer version is available: ${chalk.bold(currentVersion)} ${chalk.bold('→')} ${chalk.bold(
65+
latestVersion
66+
)}`
67+
) + '\n'
68+
);
69+
stream.write(
70+
chalk.cyan(
71+
`💡 Run '${chalk.bold('appwrite update')}' to update to the latest version.`
72+
) + '\n'
73+
);
74+
}
75+
76+
function shouldWriteUpdateNoticeToStderr(): boolean {
77+
return process.argv.some((arg) => ['-j', '--json', '-R', '--raw'].includes(arg));
78+
}
79+
80+
async function maybeShowUpdateNotice(): Promise<void> {
81+
try {
82+
const latestVersion = await getCachedUpdateNotification(version);
83+
84+
if (!latestVersion) {
85+
return;
86+
}
87+
88+
writeUpdateAvailableNotice(version, latestVersion, shouldWriteUpdateNoticeToStderr());
89+
} catch (_error) {
90+
// Update checks should never affect command execution.
91+
}
92+
}
5293

5394
/**
5495
* Check for updates and show version information
@@ -57,19 +98,12 @@ async function checkVersion(): Promise<void> {
5798
process.stdout.write(chalk.bold(`appwrite version ${version}`) + '\n');
5899

59100
try {
60-
const latestVersion = await getLatestVersion();
101+
const latestVersion = await getLatestVersion({ timeoutMs: VERSION_CHECK_TIMEOUT_MS });
102+
syncVersionCheckCache(version, latestVersion);
61103
const comparison = compareVersions(version, latestVersion);
62104

63105
if (comparison > 0) {
64-
// Current version is older than latest
65-
process.stdout.write(
66-
chalk.yellow(`\n⚠️ A newer version is available: ${chalk.bold(latestVersion)}`) + '\n'
67-
);
68-
process.stdout.write(
69-
chalk.cyan(
70-
`💡 Run '${chalk.bold('appwrite update')}' to update to the latest version.`
71-
) + '\n'
72-
);
106+
writeUpdateAvailableNotice(version, latestVersion);
73107
} else if (comparison === 0) {
74108
process.stdout.write(chalk.green('\n✅ You are running the latest version!') + '\n');
75109
} else {
@@ -89,93 +123,97 @@ if (process.argv.includes('-v') || process.argv.includes('--version')) {
89123
process.exit(0);
90124
})();
91125
} else {
92-
program
93-
.description(commandDescriptions['main'])
94-
.configureHelp({
95-
helpWidth: process.stdout.columns || 80,
96-
sortSubcommands: true,
97-
})
98-
.helpOption('-h, --help', 'Display help for command')
99-
.version(version, '-v, --version', 'Output the version number')
100-
.option('-V, --verbose', 'Show complete error log')
101-
.option('-j, --json', 'Output filtered JSON without empty values')
102-
.option('-R, --raw', 'Output full JSON response (secrets still redacted unless --show-secrets is set)')
103-
.option('--show-secrets', 'Display sensitive values like secrets and tokens in output')
104-
.hook('preAction', migrate)
105-
.option('-f,--force', 'Flag to confirm all warnings')
106-
.option('-a,--all', 'Flag to push all resources')
107-
.option('--id [id...]', 'Flag to pass a list of ids for a given action')
108-
.option('--report', 'Enable reporting in case of CLI errors')
109-
.hook('preAction', (_thisCommand, actionCommand) => {
110-
const commandConfig = actionCommand as typeof actionCommand & {
111-
outputFields?: string[];
112-
};
113-
cliConfig.displayFields = Array.isArray(commandConfig.outputFields)
114-
? commandConfig.outputFields
115-
: [];
116-
})
117-
.on('option:json', () => {
118-
cliConfig.json = true;
119-
})
120-
.on('option:raw', () => {
121-
cliConfig.raw = true;
122-
})
123-
.on('option:show-secrets', () => {
124-
cliConfig.showSecrets = true;
125-
})
126-
.on('option:verbose', () => {
127-
cliConfig.verbose = true;
128-
})
129-
.on('option:report', function () {
130-
cliConfig.report = true;
131-
cliConfig.reportData = { data: this };
132-
})
133-
.on('option:force', () => {
134-
cliConfig.force = true;
135-
})
136-
.on('option:all', () => {
137-
cliConfig.all = true;
138-
})
139-
.on('option:id', function () {
140-
cliConfig.ids = (this.opts().id as string[]);
141-
})
142-
.showSuggestionAfterError()
143-
.addCommand(whoami)
144-
.addCommand(register)
145-
.addCommand(login)
146-
.addCommand(init)
147-
.addCommand(pull)
148-
.addCommand(push)
149-
.addCommand(types)
150-
.addCommand(deploy)
151-
.addCommand(run)
152-
.addCommand(update)
153-
.addCommand(generate)
154-
.addCommand(logout)
155-
.addCommand(account)
156-
.addCommand(activities)
157-
.addCommand(backups)
158-
.addCommand(databases)
159-
.addCommand(functions)
160-
.addCommand(graphql)
161-
.addCommand(health)
162-
.addCommand(locale)
163-
.addCommand(messaging)
164-
.addCommand(migrations)
165-
.addCommand(organizations)
166-
.addCommand(project)
167-
.addCommand(projects)
168-
.addCommand(proxy)
169-
.addCommand(sites)
170-
.addCommand(storage)
171-
.addCommand(tablesDB)
172-
.addCommand(teams)
173-
.addCommand(tokens)
174-
.addCommand(users)
175-
.addCommand(vcs)
176-
.addCommand(webhooks)
177-
.addCommand(client)
178-
.parse(process.argv);
179-
180-
process.stdout.columns = oldWidth;
126+
void (async () => {
127+
await maybeShowUpdateNotice();
128+
129+
program
130+
.description(commandDescriptions['main'])
131+
.configureHelp({
132+
helpWidth: process.stdout.columns || 80,
133+
sortSubcommands: true,
134+
})
135+
.helpOption('-h, --help', 'Display help for command')
136+
.version(version, '-v, --version', 'Output the version number')
137+
.option('-V, --verbose', 'Show complete error log')
138+
.option('-j, --json', 'Output filtered JSON without empty values')
139+
.option('-R, --raw', 'Output full JSON response (secrets still redacted unless --show-secrets is set)')
140+
.option('--show-secrets', 'Display sensitive values like secrets and tokens in output')
141+
.hook('preAction', migrate)
142+
.option('-f,--force', 'Flag to confirm all warnings')
143+
.option('-a,--all', 'Flag to push all resources')
144+
.option('--id [id...]', 'Flag to pass a list of ids for a given action')
145+
.option('--report', 'Enable reporting in case of CLI errors')
146+
.hook('preAction', (_thisCommand, actionCommand) => {
147+
const commandConfig = actionCommand as typeof actionCommand & {
148+
outputFields?: string[];
149+
};
150+
cliConfig.displayFields = Array.isArray(commandConfig.outputFields)
151+
? commandConfig.outputFields
152+
: [];
153+
})
154+
.on('option:json', () => {
155+
cliConfig.json = true;
156+
})
157+
.on('option:raw', () => {
158+
cliConfig.raw = true;
159+
})
160+
.on('option:show-secrets', () => {
161+
cliConfig.showSecrets = true;
162+
})
163+
.on('option:verbose', () => {
164+
cliConfig.verbose = true;
165+
})
166+
.on('option:report', function () {
167+
cliConfig.report = true;
168+
cliConfig.reportData = { data: this };
169+
})
170+
.on('option:force', () => {
171+
cliConfig.force = true;
172+
})
173+
.on('option:all', () => {
174+
cliConfig.all = true;
175+
})
176+
.on('option:id', function () {
177+
cliConfig.ids = (this.opts().id as string[]);
178+
})
179+
.showSuggestionAfterError()
180+
.addCommand(whoami)
181+
.addCommand(register)
182+
.addCommand(login)
183+
.addCommand(init)
184+
.addCommand(pull)
185+
.addCommand(push)
186+
.addCommand(types)
187+
.addCommand(deploy)
188+
.addCommand(run)
189+
.addCommand(update)
190+
.addCommand(generate)
191+
.addCommand(logout)
192+
.addCommand(account)
193+
.addCommand(activities)
194+
.addCommand(backups)
195+
.addCommand(databases)
196+
.addCommand(functions)
197+
.addCommand(graphql)
198+
.addCommand(health)
199+
.addCommand(locale)
200+
.addCommand(messaging)
201+
.addCommand(migrations)
202+
.addCommand(organizations)
203+
.addCommand(project)
204+
.addCommand(projects)
205+
.addCommand(proxy)
206+
.addCommand(sites)
207+
.addCommand(storage)
208+
.addCommand(tablesDB)
209+
.addCommand(teams)
210+
.addCommand(tokens)
211+
.addCommand(users)
212+
.addCommand(vcs)
213+
.addCommand(webhooks)
214+
.addCommand(client)
215+
.parse(process.argv);
216+
217+
process.stdout.columns = oldWidth;
218+
})();
181219
}

docs/examples/databases/update-datetime-attribute.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ appwrite databases update-datetime-attribute \
44
--collection-id <COLLECTION_ID> \
55
--key '' \
66
--required false \
7-
--default ''
7+
--default 2020-10-15T06:38:00.000+00:00
88
```
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
```bash
2+
appwrite migrations create-json-export \
3+
--resource-id <ID1:ID2> \
4+
--filename <FILENAME>
5+
```
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
```bash
2+
appwrite migrations create-json-import \
3+
--bucket-id <BUCKET_ID> \
4+
--file-id <FILE_ID> \
5+
--resource-id <ID1:ID2>
6+
```

docs/examples/project/get-usage.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
```bash
22
appwrite project get-usage \
3-
--start-date '' \
4-
--end-date ''
3+
--start-date 2020-10-15T06:38:00.000+00:00 \
4+
--end-date 2020-10-15T06:38:00.000+00:00
55
```

0 commit comments

Comments
 (0)