Skip to content
Open
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
6 changes: 6 additions & 0 deletions .github/workflows/_test-units.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ jobs:
- name: Test code
run: npm run test

- name: Test code v2 (incl. CLI)
run: npm run test-v2

run-tests-without-optional-dependencies:
name: Tests Without Optional Dependencies
strategy:
Expand Down Expand Up @@ -74,3 +77,6 @@ jobs:

- name: Test code
run: npm run test-light

- name: Test code v2 (incl. CLI)
run: npm run test-v2
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Mindee Node.js API Library Changelog

## Unreleased
### Changes
* :sparkles: :boom: unify CLI into a single `mindee` binary (replaces
`mindeeV1` / `mindeeV2`); V2 product commands are top-level
(`extraction`, `classification`, `crop`, `ocr`, `split`) and V1 product
commands live under the `v1` group, mirroring the canonical .NET CLI shape
* :sparkles: add `--output {summary,full,raw}`, `--rag/-g`, `--raw-text/-r`,
`--confidence/-c`, `--polygon/-p`, `--text-context/-t`, `--alias/-a`
options to V2 extraction; add `--full-text/-f`, `--async`, `--output`
options to V1 commands
* :sparkles: add `Client.searchModels()` to list models available to the
current API key, with optional `name` / `modelType` filters; add the
matching `search-models` CLI command


## v5.4.0 - 2026-06-22
### Fixes
* :bug: :boom: harmonize Crop and Split extraction (now ready for public use)
Expand Down
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,69 @@ Consult the
Copyright © Mindee

Available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).

## Command Line Interface

A `mindee` command line interface is shipped with the library:

```bash
npm install -g mindee
mindee -h
```

Or, from a checkout:

```bash
node ./dist/bin/mindee.js -h
```

### Authentication

Provide an API key via `--api-key`:

- V2: `mindee --verbose <command> --api-key <V2_API_KEY> ...`
- V1: `mindee v1 <product> --api-key <V1_API_KEY> ...`

### V2 commands (top-level)

```
mindee <command> --api-key <V2_API_KEY> --model-id <MODEL_ID> [options] <path-or-url>
```

Available commands: `extraction`, `classification`, `crop`, `ocr`, `split`.

Extraction-only options: `--rag/-g`, `--raw-text/-r`, `--confidence/-c`,
`--polygon/-p`, `--text-context/-t`.
Common options: `--output/-o {summary,full,raw}`, `--alias/-a`.

### Search models

List models available to the current API key:

```
mindee search-models --api-key <V2_API_KEY> [--name <partial>] [--model-type <type>] [--raw-json]
```

Filter by partial name match (case-insensitive) and / or by exact model
type (one of `extraction`, `crop`, `classification`, `ocr`, `split`).

### V1 commands (under `v1`)

```
mindee v1 <product> --api-key <V1_API_KEY> [options] <path>
```

Where `<product>` is one of `barcode-reader`, `cropper`, `driver-license`,
`financial-document`, `fr-bank-account-details`, `fr-carte-grise`,
`fr-carte-nationale-d-identite`, `generated`, `international-id`, `invoice`,
`invoice-splitter`, `multi-receipts-detector`, `passport`, `receipt`,
`resume`, `us-bank-check`.

Common options: `--output/-o {summary,full,raw}`. Depending on the product:
`--all-words/-w`, `--full-text/-f`, `--async`.

### Output modes

- `summary` (default): brief prediction summary.
- `full`: detailed result including raw text / OCR sections when applicable.
- `raw`: full JSON response.
5 changes: 5 additions & 0 deletions bin/mindee.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env node

import { cli } from "@/cli/index.js";

cli();
5 changes: 0 additions & 5 deletions bin/mindeeV1.ts

This file was deleted.

5 changes: 0 additions & 5 deletions bin/mindeeV2.ts

This file was deleted.

28 changes: 28 additions & 0 deletions docs/code_samples/v2_search_models.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as mindee from "mindee";
// If you're on CommonJS:
// const mindee = require("mindee");

const apiKey = "MY_API_KEY";

// Init a new client
const mindeeClient = new mindee.Client(
{ apiKey: apiKey }
);

// Search models, optionally filtered by name partial match
// (case-insensitive) and / or by exact model type
// ("extraction", "crop", "classification", "ocr", "split").
const response = await mindeeClient.searchModels(
// name partial match (optional)
undefined,
// model type (optional)
undefined,
);

// print a string summary
console.log(response.toString());

// Access individual models
for (const model of response.models) {
console.log(`${model.id} - ${model.name}`);
}
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
"type": "module",
"main": "src/index.js",
"bin": {
"mindeeV1": "bin/mindeeV1.js",
"mindeeV2": "bin/mindeeV2.js"
"mindee": "bin/mindee.js"
},
"scripts": {
"build": "tsc --build && tsc-alias",
Expand All @@ -30,7 +29,7 @@
"test-light": "mocha --grep '#OptionalDepsRequired' --invert 'tests/**/*.spec.ts'",
"test-integration": "mocha --grep '#OptionalDepsRemoved' --invert 'tests/**/*.integration.ts'",
"test-integration-light": "mocha --grep '#OptionalDepsRequired' --invert 'tests/**/*.integration.ts'",
"test-v2": "tsc --noEmit && node --import tsx --test 'tests/v2/**/*.spec.ts'",
"test-v2": "tsc --noEmit && node --import tsx --test 'tests/v2/**/*.spec.ts' 'tests/cli/**/*.spec.ts'",
"lint": "tsc --noEmit && eslint --report-unused-disable-directives './src/**/*.ts' './tests/**/*.ts'",
"lint-fix": "tsc --noEmit && eslint --fix --report-unused-disable-directives './src/**/*.ts' './tests/**/*.ts'",
"docs": "typedoc --out docs/_build ./src/index.ts",
Expand Down
51 changes: 51 additions & 0 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { buildV1Command } from "@/cli/v1/buildV1Command.js";
import { Command } from "commander";
import { ExtractionCommand } from "./v2/extractionCommand.js";
import { ClassificationCommand } from "./v2/classificationCommand.js";
import { CropCommand } from "./v2/cropCommand.js";
import { OcrCommand } from "./v2/ocrCommand.js";
import { SplitCommand } from "./v2/splitCommand.js";
import { SearchModelsCommand } from "./v2/searchModelsCommand.js";

/**
* Build the root `mindee` command line.
*
* The shape mirrors the canonical `.NET` CLI
* (`mindee-api-dotnet/src/Mindee.Cli`):
* - V2 product commands are top-level (`extraction`, `classification`,
* `crop`, `ocr`, `split`), plus the `search-models` tool.
* - V1 product commands live under the `v1` sub-command.
*/
export function buildCli(): Command {
const program = new Command();
program
.name("mindee")
.description("Command line interface for Mindee products.")
.option("--verbose", "Enables diagnostics output.");

// V2 top-level commands
program.addCommand(new ExtractionCommand());
program.addCommand(new ClassificationCommand());
program.addCommand(new CropCommand());
program.addCommand(new OcrCommand());
program.addCommand(new SplitCommand());
program.addCommand(new SearchModelsCommand());

// V1 commands grouped under `v1`
const v1 = buildV1Command();
program.addCommand(v1);

return program;
}

/**
* Entry point for the `mindee` binary.
*
* Parses `process.argv` and dispatches to the matching command.
*
* @param argv command-line arguments to parse (defaults to `process.argv`).
* @returns a Promise resolving to the root command once parsing completes.
*/
export function cli(argv: string[] = process.argv): Promise<Command> {
return buildCli().parseAsync(argv);
}
35 changes: 35 additions & 0 deletions src/cli/output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* How to output a CLI response.
*/
export enum OutputType {
/** Document-level summary, in rST format. (Default) */
summary = "summary",
/** Complete response in rST format. */
full = "full",
/** Raw JSON. */
raw = "raw",
}

export const OUTPUT_CHOICES: readonly OutputType[] = [
OutputType.summary,
OutputType.full,
OutputType.raw,
] as const;

export const OUTPUT_DESCRIPTION =
"Specify how to output the data:\n" +
"- summary: a basic summary (default)\n" +
"- full: detailed extraction results, including options\n" +
"- raw: full JSON response";

export function parseOutput(value: string): OutputType {
const normalized = value.toLowerCase();
for (const choice of OUTPUT_CHOICES) {
if (choice === normalized) {
return choice;
}
}
throw new Error(
`Invalid output type '${value}'. Valid values are: ${OUTPUT_CHOICES.join(", ")}.`
);
}
21 changes: 10 additions & 11 deletions src/v1/cli.ts → src/cli/v1/buildV1Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ import {
} from "@/v1/parsing/common/index.js";
import {
Client, PredictOptions,
} from "./client.js";
} from "@/v1/client.js";
import {
PageOptions, PageOptionsOperation, PathInput,
} from "@/input/index.js";
import * as console from "console";
import {
CLI_COMMAND_CONFIG, COMMAND_GENERATED, ProductConfig,
} from "./product/cliProducts.js";
import { Endpoint } from "./http/index.js";

const program = new Command();
} from "./cliProducts.js";
import { Endpoint } from "@/v1/http/index.js";


//
Expand Down Expand Up @@ -209,6 +207,7 @@ function addPredictAction(prog: Command) {
command: Command
) {
const allOptions = {
...prog.parent?.parent?.parent?.opts(),
...prog.parent?.parent?.opts(),
...prog.parent?.opts(),
...prog.opts(),
Expand All @@ -233,13 +232,13 @@ function addPredictAction(prog: Command) {
}
}

export function cli() {
program.name("mindee")
.description("Command line interface for Mindee products.")
export function buildV1Command(): Command {
const v1Program = new Command("v1")
.description("Mindee V1 product commands.")
.option("-d, --debug", "high verbosity mode");

CLI_COMMAND_CONFIG.forEach((info, name) => {
const productCmd: Command = program.command(name)
const productCmd: Command = v1Program.command(name)
.description(info.displayName);

if (info.async) {
Expand All @@ -251,7 +250,7 @@ export function cli() {
await callGetDocument(
docClass,
documentId,
{ ...options, ...productCmd.opts(), ...program.opts() }
{ ...options, ...productCmd.opts(), ...v1Program.opts() }
);
});
addMainOptions(getDocProductCmd);
Expand Down Expand Up @@ -279,5 +278,5 @@ export function cli() {
addPostOptions(predictProductCmd, info);
addPredictAction(predictProductCmd);
});
program.parse(process.argv);
return v1Program;
}
File renamed without changes.
26 changes: 26 additions & 0 deletions src/cli/v2/classificationCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { OptionValues } from "commander";
import { InferenceCommand } from "./inferenceCommand.js";
import { Classification } from "@/v2/product/classification/classification.js";
import { BaseProduct } from "@/v2/product/baseProduct.js";

/** CLI command for the V2 `classification` product. */
export class ClassificationCommand extends InferenceCommand {
constructor() {
super("classification", "Classification utility.");
}

protected get productSlug(): string {
return Classification.slug;
}

protected get productClass(): typeof BaseProduct {
return Classification;
}

protected buildParameters(options: OptionValues) {
return {
modelId: options.modelId as string,
alias: options.alias as string | undefined,
};
}
}
26 changes: 26 additions & 0 deletions src/cli/v2/cropCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { OptionValues } from "commander";
import { InferenceCommand } from "./inferenceCommand.js";
import { Crop } from "@/v2/product/crop/index.js";
import { BaseProduct } from "@/v2/product/baseProduct.js";

/** CLI command for the V2 `crop` product. */
export class CropCommand extends InferenceCommand {
constructor() {
super("crop", "Crop utility.");
}

protected get productSlug(): string {
return Crop.slug;
}

protected get productClass(): typeof BaseProduct {
return Crop;
}

protected buildParameters(options: OptionValues) {
return {
modelId: options.modelId as string,
alias: options.alias as string | undefined,
};
}
}
Loading
Loading