Skip to content

Migrating to v5 ​

v5.0.0 breaks the public surface on purpose. The old spellings are gone rather than deprecated: carrying both for a release line would leave Atlas with two vocabularies, which is the thing this release exists to end.

Nothing about stored data changes. Snapshots, manifests, blobs and delta cursors written by v4 are read by v5 unchanged, and a v5 restore of a v4 snapshot needs no migration step. What changes is the SDK's field names, the CLI's flags, and the exit codes.

SDK: one convention ​

Every option and result field on the public surface is camelCase. Methods and config already were.

typescript
// v4
const result = await atlas.outlook.backup(mailboxId, { force_full: true, page_size: 25 });
console.log(result.summary.attachments_stored, result.graph_cost?.requests_total);

// v5
const result = await atlas.outlook.backup(mailboxId, { forceFull: true, pageSize: 25 });
console.log(result.summary.attachmentsStored, result.graphCost?.requestsTotal);

The compiler is your migration tool. The option and result types are exported, so a TypeScript build fails at every renamed field and the completion list offers the new name. There is deliberately no codemod: a transform would only help JavaScript consumers, who are also the ones it is riskiest for.

The rule is mechanical, so the table below is a spot check rather than a dictionary: snake_case becomes camelCase, one field at a time, at every depth.

v4v5
force_fullforceFull
page_sizepageSize
folder_filterfolderFilter
file_filterfileFilter
folder_namefolderName
message_refmessageRef
snapshot_idsnapshotId
target_mailboxtargetMailbox
output_pathoutputPath
skip_integrity_checkskipIntegrityCheck
include_recoverable_itemsincludeRecoverableItems
include_subsitesincludeSubsites
object_lock_requestobjectLockRequest
retention_daysretentionDays
retain_untilretainUntil
start_date / end_datestartDate / endDate
restored_countrestoredCount
saved_countsavedCount
attachments_storedattachmentsStored
integrity_failuresintegrityFailures
verification_warningsverificationWarnings
total_checkedtotalChecked
manifests_in_chainmanifestsInChain
graph_costgraphCost
requests_totalrequestsTotal
elapsed_mselapsedMs
last_backup_atlastBackupAt
total_size_bytestotalSizeBytes

Three things that deliberately did not change ​

Map keys Atlas did not choose. deltaLinks is keyed by Graph folder id, requestsByType by request label, byService by pool name. The field names became camelCase; the keys inside are data and are untouched. byService.sharepoint_onedrive is still spelled that way, because the same identifier appears in GRAPH_SERVICE_LIMITS and renaming it in one place only would be worse than leaving it.

The raw Graph payload. readMessage() returns message exactly as Graph produced it, including @odata.etag and internetMessageHeaders. Renaming inside it would hand back a message that no longer matches the stored blob.

StorageTarget. The value createStorageTarget() returns is a handle you pass straight back, not data you author, so it is unchanged. Its config is camelCase, and now camelCase only:

typescript
// v4 accepted either spelling
createStorageTarget({ s3_endpoint: '...', encryption_passphrase: '...' });

// v5 accepts the documented one
createStorageTarget({ s3Endpoint: '...', encryptionPassphrase: '...' });

Exports are now enumerated ​

v4's entry point re-exported all of @wisecom/atlas-types, which published every internal port, DI token and service interface as public API. v5 exports a named list: the instance and its three workload APIs, their option and result types, the progress and error types, and the two value exports. If you imported an internal port, a token, or a use-case interface, it is no longer public. Those were never intended as API and had no stability guarantee; open an issue if you were relying on one and it will be considered on its merits.

create_container and create_container_from_config are no longer exported, as completed in PR #323. The former discovered .env and atlas.config.json, contradicting the SDK's explicit-configuration contract; the latter was an internal DI factory. Pass every credential to createAtlasInstance instead. The unused environment-loading factory has also been removed from the SDK source.

Eager configuration validation ​

createAtlasInstance now throws ConfigError synchronously for missing or blank required fields, passphrases shorter than 14 UTF-8 bytes, and malformed S3 endpoints. Endpoints must be absolute HTTP(S) URLs without embedded credentials, a query or a fragment. Previously some invalid values survived construction and failed only during an operation.

Existing short-passphrase backups need care. Do not pad or replace the passphrase to satisfy the new check: that changes the key and makes existing data unreadable. Keep the original passphrase and use the previous SDK release or the CLI to recover those backups. This change does not rotate keys or rewrite stored data; the CLI's existing passphrase handling is unchanged.

The optional await atlas.validate() checks an existing tenant bucket, unwraps _meta/dek.enc with the configured passphrase when that object exists, then acquires a Graph token. It creates no storage. A fresh tenant with no wrapped key passes; a wrong passphrase for existing backups raises WrongPassphraseError before Graph is probed. This passphrase check was added in v5.2.0; v5.0.0 and v5.1.0 validated only HeadBucket and Graph token acquisition. The method still does not verify workload permissions. S3-stage failures are StorageError; Graph-token failures are AuthError. See Configuration validation for prerequisites and error codes.

Together with the camelCase surface and enumerated exports in PR #323, this completes issue #45. The error classes were already available from v4.4.0; this change uses them at construction and in the explicit connectivity probe.

CLI failure exit codes ​

v4 returned 1 for every fatal exception. v5 uses the typed error categories introduced in v4.4.0, with the original Graph, AWS or Node failure reported separately on stderr.

Failurev4v5
Throttle exhaustion or recognized network/transient HTTP failure13
Authentication, permission or mailbox-license failure14
Wrong encryption passphrase15
Typed configuration failure or failure to load CLI configuration16
Missing resource17
Typed Object Lock retention refusal18
Unexpected or unclassified failure, usage error, command-reported failure without a typed exception11
Complete operation00
Partial operation or soft interrupt22

Replace checks that only recognize 1 as failure. A script using if [ "$status" -eq 1 ] would miss the new failure categories; test for nonzero first, then branch on the documented category when deciding whether to retry. Codes 4 through 8 require operator action rather than an unchanged retry. Code 3 permits scheduling a later attempt, but a timed-out write may already have committed.

Atlas code: now identifies the Atlas category; Transport code:, HTTP status:, Error name: and Body: describe its underlying cause. Fatal details that previously went to stdout now go to stderr. Update log collectors accordingly, and use exit codes rather than parsing message wording. The CLI reference lists the full mapping, precedence and command-reported exceptions.

CLI: one vocabulary for flags and verbs ​

-s is the snapshot on every command that has one, and -o is the owner on every command that has one. Two commands spelled those letters differently, so the flags they collided with give up their short form rather than keep a second meaning: --site and --output now have no short spelling anywhere, and nothing can shadow -s or -o again.

Short flags whose meaning changed ​

A retired short flag is rejected rather than reinterpreted. Silently resolving atlas stats -s <site> as a snapshot id would report on the wrong scope, and atlas outlook save -o <path> as an owner would put the archive somewhere else. That is a data bug wearing a breaking change's clothes, so the old spelling fails and names its replacement.

v4v5Using the old form
atlas stats -s <site>atlas stats --site <site>error naming -s, exit 1
atlas outlook save -o <path>atlas outlook save --output <path>error naming -o, exit 1
atlas onedrive save -O <path>atlas onedrive save --output <path>error naming -O, exit 1
atlas sharepoint save -O <path>atlas sharepoint save --output <path>error naming -O, exit 1
console
$ atlas stats -s https://contoso.sharepoint.com/sites/finance
error: option '-s <value>' argument 'https://contoso.sharepoint.com/sites/finance' is invalid. -s no longer means --site in v5.0.0. Pass --site instead.

The retired spellings are hidden from --help, because they are not flags you can use. They exist only so a script that still passes one stops instead of doing the wrong thing.

-f takes one folder and repeats ​

atlas outlook backup took a variadic -f <name...> while restore and save took a single value, so one command group carried two arities and a variadic -f swallowed the next flag's argument. Every Outlook command now takes one folder per flag, repeated:

v4v5
atlas outlook backup -f Inbox "Sent Items"atlas outlook backup -f Inbox -f "Sent Items"

A single-folder invocation is unchanged. The old multi-folder form fails with error: too many arguments for 'backup'. Expected 0 arguments but got 1: Sent Items. and exit 1; the first folder is still read from -f, so the command does not quietly back up less than you asked for.

Verbs that replaced flags and positionals ​

A flag that changes what a command does is a verb wearing the wrong clothes, and a positional that accepts either a key or the word list cannot document itself in --help.

v4v5Using the old form
atlas replicate --statusatlas replicate statuserror: unknown option '--status'
atlas config <key> <value>atlas config set <key> <value>error: unknown command '<key>'
atlas config <key>atlas config get <key>error: unknown command '<key>'
atlas config list | unset | validateunchangedstill works

list, unset and validate were already spelled as words, and are now real subcommands rather than magic values in a positional, so atlas config list --help documents itself. The replication scope flags are declared on both replicate and replicate status, so each --help is complete.

Validation moved to the flag boundary ​

--lock-mode and --service are validated by the argument parser instead of by hand, so a typo fails before Atlas opens a Graph or S3 connection rather than after:

console
$ atlas sharepoint backup --site <site> --lock-mode bogus
error: option '--lock-mode <mode>' argument 'bogus' is invalid. Allowed choices are governance, compliance.

A script that matched the old wording needs the new strings. The v4 messages were Invalid object lock mode "bogus". Expected "governance" or "compliance". from the policy layer and Unknown --service "x"; expected outlook, onedrive, sharepoint, or all from the stats command.

Defaults are declared to the parser too, so --help shows --top as (default: "20") and --conflict as (default: "rename") instead of repeating the value in prose. The values themselves are unchanged.

SDK: exports can stream ​

Additive, not breaking. save() and saveMailbox() now accept output, a Node Writable, so an export can go straight to an HTTP response or an upload instead of a local file. Existing outputPath callers are unaffected.

typescript
// v5, no local file involved
await atlas.outlook.save(snapshotId, { output: res });

Passing both output and outputPath throws ConfigError. For a stream export the result reports outputPath: '', and a failed run destroys the stream rather than ending it. See Exporting to a Stream, which closes issue #44.

Next ​

Two v5.0.0 items are still in flight and are documented here as they merge: --fast for drive verification, and the --json rollout across the remaining commands (issue #94).

Released under the Apache-2.0 License.