Skip to content

Recipes - Super client

You can generate a super-client with Eicrud's CLI, it comes with all your DTO/Entity types and provides powerful auto-completion to access your services and commands.

How to export the super-client

Generating the super-client is a two-step process.

1.

eicrud export dtos
This command copies all your .dto.ts and .entity.ts files to the eicrud_exports directory and strips them of their decorators.

2.

eicrud export superclient
This command builds a typed class for each of your CRUD services and instantiates them in a main SuperClient class.
eicrud_exports/super_client.ts
import { ProfileClient } from './user-profile/user-profile.client';
import { UserClient } from './my-user/my-user.client';
import { SuperClientConfig } from "@eicrud/client";

export class SuperClient {

    constructor(config: SuperClientConfig) {
        // GENERATED START 1
        this.profile = new ProfileClient(config);
        this.user = new UserClient(config);
    }

    // GENERATED START 2
    profile: ProfileClient;
    user: UserClient;
}

Note

This command requires the @eicrud/core package to be present in your node_modules directories.

eicrud-cli.json
{
    "export": {
        "modulesDir": "./node_modules",
        // ...
    }
}

At this point, all you need to do is copy the eicrud_exports directory and you can enjoy the SuperClient's autocompletion into your front-end or anywhere else.

import { SuperClient } from "./eicrud_exports/super_client";
import { Profile } from "./eicrud_exports/profile/user-profile.entity";

const sp = new SuperClient({url: 'http://localhost:3000'});

// Get typing tailored to your service's entity
const profile: Profile = await sp.profile.findOne({userName: "Jon Doe"});

// Directly call your services' commands
const helloWorld = await sp.profile.say_hello({arg: 'world'});

Exclude files from the export

There are several ways to keep parts of your DTOs private.

Global exclusion

You can remove a service entirely (entity + commands) from the export by including it in the excludeServices option of the CLI's config.

eicrud-cli.json
{
    "export": {
        "excludeServices": ["profile", "secret-data"],
        // ...
    }
}
Alternatively, you can use the @eicrud:cli:export:exclude directive by commenting the entity file.
secret-data.entity.ts
@Entity()
//@eicrud:cli:export:exclude
export class SecretData implements CrudEntity {
  @PrimaryKey({ name: '_id' })
  id: string;
// ...

Partial exclusion

You use the @eicrud:cli:export:hide directive to hide entities.

secret-data.entity.ts
@Entity()
//@eicrud:cli:export:hide
export class HiddenData implements CrudEntity {
  @PrimaryKey({ name: '_id' })
  id: string;
// ...
The above gets converted to:
secret-data.entity.ts
export type HiddenData = any;

Note

This allows for hiding the entity's content while keeping the service's commands exported.

You can also use the hide directive to strip a specific command from a service.

missing_cmd.dto.ts
//@eicrud:cli:export:hide
export class MissingCmdDto {
  @IsString()
  @IsOptional()
  myArg: string;
}
And for finer control, you can use the @eicrud:cli:export:delete directives.
  //@eicrud:cli:export:delete:start
  @Property()
  missingProp1: string;

  @Property()
  missingProp2: number = 1;
  //@eicrud:cli:export:delete:end

  @Property()
  @IsString()
  presentProp: string;

  @Property()
  //@eicrud:cli:export:delete:next-line
  missingProp3: string;

Export additional files

You can export additional files by specifying patterns in your CLI config.

eicrud-cli.json
{
    "export": {
        "includePatterns": ["*shared-dto.ts"],
        "excludePatterns": ["*paths-to-exclude*"],
    }
}

Troubleshooting

File paths and class names are used when generating the superclient. For that reason, they must remain as generated by the CLI.

entities

  • file path: <kebab-case-entity-name>/<kebab-case-entity-name>.entity.ts
    @Entity()
    export class <PascalCaseEntityName> implements CrudEntity {
    //...
    

commands

  • file path: <kebab-case-entity-name>/cmds/<snake_case_cmd_name>/<snake_case_cmd_name>.dto.ts
    export class <PascalCaseCmdName>Dto {
        // ...
    }
    
    //used by super-client, update me here
    export type <PascalCaseCmdName>ReturnDto = string;