Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changeset/first-version.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
First version of `meili`, the Meilisearch CLI built for coding agents.

- Commands derive from the routes of the Meilisearch API and of the Management API, verb first and resource plural: `meili get health`, `meili get indexes`, `meili get indexes --id movies`.
- `meili get version`, on `GET /version`, returns the version of the instance and the commit it was built from.
- Documents: `meili get documents --index <index>`, narrowed by `--ids` or `--filter`; `meili add documents --index <index> --file <path>` and `meili update documents --index <index> --file <path>`, which read the documents from a file, from stdin with `--file -` or from `--data`; `meili delete documents --index <index> (--ids <ids> | --filter <filter> | --all) --yes`.
- Indexes: `meili get indexes [--id <index>]`; `meili add indexes --id <index> [--primary-key <field>]`, `meili update indexes --id <index> [--primary-key <field>] [--new-id <index>]`, which renames the index, and `meili delete indexes --id <index> --yes`.
- Tasks: `meili get tasks`, narrowed by `--ids`, `--statuses`, `--types`, `--index-ids`, `--batch-ids`, `--canceled-by` and the date filters of the route, paging with `--limit` and `--from` and following the `next` cursor with `--all`; `meili cancel tasks` and `meili delete tasks --yes`, which take the same filters and answer a task.
Expand Down
1 change: 1 addition & 0 deletions docs/contract/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Every API command declares its routes, `static routes = ["GET /indexes", "GET /i
| Routes | Command |
|---|---|
| `GET /health` | `meili get health` |
| `GET /version` | `meili get version` |
| `GET /stats`, `GET /indexes/{index_uid}/stats` | `meili get stats [--index <index>]` |
| `GET /indexes`, `GET /indexes/{index_uid}` | `meili get indexes [--id <index>]` |
| `POST /indexes` | `meili add indexes --id <index> [--primary-key <field>]` |
Expand Down
185 changes: 185 additions & 0 deletions oclif.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4217,6 +4217,191 @@
"tasks.js"
]
},
"get:version": {
"aliases": [],
"args": {},
"description": "Get the version of the Meilisearch instance, with the commit it was built from.",
"examples": [
"<%= config.bin %> <%= command.id %>",
"<%= config.bin %> <%= command.id %> --output json"
],
"flags": {
"output": {
"char": "o",
"description": "json (default): one document, the API body as it is, indented in a terminal, compact when piped. ndjson: one item per line, list commands only, streams with --all.",
"name": "output",
"hasDynamicHelp": false,
"helpValue": "<mode>",
"multiple": false,
"options": [
"json",
"ndjson"
],
"type": "option"
},
"debug": {
"description": "Print every HTTP request and response on stderr, secrets redacted.",
"name": "debug",
"allowNo": false,
"type": "boolean"
},
"project-url": {
"description": "Project URL, the Meilisearch instance to talk to.",
"name": "project-url",
"hasDynamicHelp": false,
"helpValue": "<url>",
"multiple": false,
"type": "option"
},
"project-api-key": {
"description": "Project API key. `-` reads it from stdin.",
"name": "project-api-key",
"hasDynamicHelp": false,
"helpValue": "<key>",
"multiple": false,
"type": "option"
},
"project": {
"description": "A project of the config file. Cannot be combined with --project-url. Required when the file has several projects.",
"name": "project",
"hasDynamicHelp": false,
"helpValue": "<name>",
"multiple": false,
"type": "option"
}
},
"hasDynamicHelp": false,
"hiddenAliases": [],
"id": "get:version",
"pluginAlias": "@meilisearch/cli",
"pluginName": "@meilisearch/cli",
"pluginType": "core",
"strict": true,
"enableJsonFlag": false,
"api": "meilisearch",
"routes": [
"GET /version"
],
"keyActions": [
"version"
],
"connectionFlags": {
"project-url": {
"description": "Project URL, the Meilisearch instance to talk to.",
"helpValue": "<url>",
"input": [],
"multiple": false,
"type": "option"
},
"project-api-key": {
"description": "Project API key. `-` reads it from stdin.",
"helpValue": "<key>",
"input": [],
"multiple": false,
"type": "option"
},
"project": {
"description": "A project of the config file. Cannot be combined with --project-url. Required when the file has several projects.",
"helpValue": "<name>",
"input": [],
"multiple": false,
"type": "option"
}
},
"waitFlags": {
"wait": {
"description": "Poll the task until it reaches a final status, then print the final task.",
"allowNo": false,
"type": "boolean"
},
"timeout": {
"description": "Maximum wait time, for example 30s, 2m. Default 60s. Only with --wait.",
"helpValue": "<duration>",
"dependsOn": [
"wait"
],
"input": [],
"multiple": false,
"type": "option"
}
},
"paginationFlags": {
"limit": {
"description": "Passed to the API.",
"helpValue": "<n>",
"input": [],
"multiple": false,
"type": "option"
},
"offset": {
"description": "Passed to the API.",
"helpValue": "<n>",
"input": [],
"multiple": false,
"type": "option"
},
"all": {
"description": "Fetch every page. Streams with ndjson, buffers into one array with json.",
"allowNo": false,
"type": "boolean"
}
},
"fromPaginationFlags": {
"limit": {
"description": "Passed to the API.",
"helpValue": "<n>",
"input": [],
"multiple": false,
"type": "option"
},
"from": {
"description": "Passed to the API: the uid the page starts at, going down.",
"helpValue": "<uid>",
"input": [],
"multiple": false,
"type": "option"
},
"all": {
"description": "Fetch every page. Streams with ndjson, buffers into one array with json.",
"allowNo": false,
"type": "boolean"
}
},
"bodyInputFlags": {
"file": {
"description": "Read the body from a file. `-` reads from stdin.",
"helpValue": "<path>",
"exclusive": [
"data"
],
"input": [],
"multiple": false,
"type": "option"
},
"data": {
"description": "Inline JSON body.",
"helpValue": "<json>",
"input": [],
"multiple": false,
"type": "option"
}
},
"confirmFlags": {
"yes": {
"required": true,
"description": "Confirm the deletion. Nothing is sent to the API without it.",
"allowNo": false,
"type": "boolean"
}
},
"isESM": true,
"relativePath": [
"dist",
"commands",
"get",
"version.js"
]
},
"multi-search": {
"aliases": [],
"args": {},
Expand Down
23 changes: 23 additions & 0 deletions src/commands/get/version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { type Api, BaseCommand } from "../../lib/base-command.js";

export default class GetVersion extends BaseCommand {
static api: Api = "meilisearch";

static routes = ["GET /version"];

static keyActions = ["version"];

static override description =
"Get the version of the Meilisearch instance, with the commit it was built from.";

static override examples = [
"<%= config.bin %> <%= command.id %>",
"<%= config.bin %> <%= command.id %> --output json",
];

static override flags = { ...BaseCommand.connectionFlags };

async run(): Promise<void> {
await this.output(await this.meilisearch.getVersion());
}
}
51 changes: 51 additions & 0 deletions test/commands/get/__snapshots__/version.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`meili get version > passes the API error of a key the instance refuses through and exits 3 1`] = `
{
"exitCode": 3,
"stderr": "{"error":{"code":"invalid_api_key","type":"auth","message":"The provided API key is invalid.","link":"https://docs.meilisearch.com/errors#invalid_api_key","hint":"Provide an API key with \`--project-api-key <key>\` or \`MEILI_PROJECT_API_KEY\`."}}
",
"stdout": "",
}
`;

exports[`meili get version > prints its help without any network call 1`] = `
"Get the version of the Meilisearch instance, with the commit it was built from.

USAGE
$ meili get version [-o <mode>] [--debug] [--project-url <url>]
[--project-api-key <key>] [--project <name>]

FLAGS
-o, --output=<mode> json (default): one document, the API body as it
is, indented in a terminal, compact when piped.
ndjson: one item per line, list commands only,
streams with --all.
--debug Print every HTTP request and response on stderr,
secrets redacted.
--project=<name> A project of the config file. Cannot be combined
with --project-url. Required when the file has
several projects.
--project-api-key=<key> Project API key. \`-\` reads it from stdin.
--project-url=<url> Project URL, the Meilisearch instance to talk to.

DESCRIPTION
Get the version of the Meilisearch instance, with the commit it was built
from.

EXAMPLES
$ meili get version

$ meili get version --output json

"
`;

exports[`meili get version > prints the version as the API returned it 1`] = `
{
"exitCode": 0,
"stderr": "",
"stdout": "{"commitSha":"b46889b5f0f2f8b91438a08a358ba8f05fc09fc1","commitDate":"2026-09-24T10:00:00.000000Z","pkgVersion":"1.54.0"}
",
}
`;
34 changes: 34 additions & 0 deletions test/commands/get/version.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { describe, expect, it } from "vitest";
import GetVersion from "../../../src/commands/get/version.js";
import {
invalidApiKeyError,
MEILISEARCH_URL,
meilisearchHandlers,
} from "../../helpers/meilisearch-handlers.js";
import { server, useMockServer } from "../../helpers/msw.js";
import { runCli, runCommand } from "../../helpers/run-command.js";

useMockServer();

const env = { MEILI_PROJECT_URL: MEILISEARCH_URL };

describe("meili get version", () => {
it("prints its help without any network call", async () => {
const result = await runCli(["get", "version", "--help"]);
expect(result.exitCode).toBe(0);
expect(result.stderr).toBe("");
expect(result.stdout).toMatchSnapshot();
});

it("prints the version as the API returned it", async () => {
server.use(meilisearchHandlers.version());
const result = await runCommand(GetVersion, ["--output", "json"], { env });
expect(result).toMatchSnapshot();
});

it("passes the API error of a key the instance refuses through and exits 3", async () => {
server.use(meilisearchHandlers.apiError("/version", 403, invalidApiKeyError));
const result = await runCommand(GetVersion, ["--output", "json"], { env });
expect(result).toMatchSnapshot();
});
});
42 changes: 42 additions & 0 deletions test/contract/__snapshots__/commands.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,41 @@ The file holds API keys and decides where every later command goes, for every pr
"GET /tasks",
],
},
{
"api": "meilisearch",
"description": "Get the version of the Meilisearch instance, with the commit it was built from.",
"examples": [
"meili get version",
"meili get version --output json",
],
"flags": [
{
"description": "Project URL, the Meilisearch instance to talk to.",
"helpValue": "<url>",
"name": "project-url",
"type": "option",
},
{
"description": "Project API key. \`-\` reads it from stdin.",
"helpValue": "<key>",
"name": "project-api-key",
"type": "option",
},
{
"description": "A project of the config file. Cannot be combined with --project-url. Required when the file has several projects.",
"helpValue": "<name>",
"name": "project",
"type": "option",
},
],
"id": "get version",
"keyActions": [
"version",
],
"routes": [
"GET /version",
],
},
{
"api": "meilisearch",
"description": "Run several search queries in one request, each naming its index in --queries, returned side by side or merged into one ranked list with --federation.",
Expand Down Expand Up @@ -1989,6 +2024,13 @@ The file holds API keys and decides where every later command goes, for every pr
"GET /tasks",
],
},
{
"description": "Get the version of the Meilisearch instance, with the commit it was built from.",
"id": "get version",
"routes": [
"GET /version",
],
},
{
"description": "Run several search queries in one request, each naming its index in --queries, returned side by side or merged into one ranked list with --federation.",
"id": "multi-search",
Expand Down
2 changes: 2 additions & 0 deletions test/contract/__snapshots__/help.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ COMMANDS
its default.
get tasks List the tasks of the instance, narrowed by --ids, --statuses,
--types and the other filters of the route.
get version Get the version of the Meilisearch instance, with the commit it
was built from.

"
`;
Loading
Loading