Tiny CLI

repository·dev·Indexed 41 days ago

https://github.com/opentiny/tiny-cli

A front-end engineering command line tool designed to streamline development workflows through toolkits and plugins. Version 1.0.0 provides a primary `tiny` entry point for initializing projects, managing modules, and executing task flows. It includes the `@opentiny/cli-devkit` for developers to integrate utilities for caching, logging, configuration, and Git metadata extraction into their own plugins and toolkits.

Tokens
29.8K
Snippets
121
Records
144
Agent score
49%

What's inside Tiny CLI

  1. Overview of tiny CLI base commands

    dev

    The tiny CLI provides three categories of commands:

    1. Base commands: Core functionality for initialization, installation, and management.
    2. Toolkit-specific commands: Commands fixed to a specific toolkit.
    3. Plugin extension commands: Commands provided by installed plugins.

    You can view the help information by running tiny -h.

    $ tiny -h
  2. Key features of tiny-cli

    dev

    tiny-cli provides several advanced capabilities for frontend workflows:

    • Cross-platform compatibility: Works on Windows, macOS, and Linux.
    • Advanced Task Execution: Offers a more powerful task flow execution mechanism than standard npm scripts, providing better control over synchronous and asynchronous task execution.
    • Automated Module Installation: Supports automatic installation of modules. If you run a module command that is not currently installed locally, tiny-cli will automatically install it before executing the command.
    • Flexible Upgrade Strategies: Modules can be configured for automatic upgrades, manual upgrades, or 'last-digit automatic upgrades' (where the user is automatically upgraded when the module's version number changes in the last digit/z-position).
    • Improved Error Handling: Provides human-readable error messages to make debugging easier.
  3. What is tiny-cli and how does it work

    dev

    tiny-cli is a core frontend engineering tool designed to provide a robust set of tools, suites, plugins, and workflows. It operates on a unified development environment to ensure consistency and reproducibility across teams.

    Core Mental Model: Tiny follows a design philosophy similar to npm. Just as npm is primarily a package manager rather than a build tool, tiny itself does not possess inherent engineering capabilities. Instead, it serves as a platform for installing, managing, and running specialized suites (scaffolding tools) and plugins (task runners).

    It provides:

    • Scaffolding functionality (similar to Yeoman) to quickly set up local development environments.
    • A plugin mechanism (similar to Gulp) to solve various frontend development challenges.
  4. Implement the plugin interface and command mapping

    dev

    A tiny plugin is a standard npm package that exports a single object. The keys of this exported object map directly to commands used in the CLI.

    Command Syntax: tiny <plugin-name> <command>

    If your plugin is named tiny-plugin-abc, the exported object keys become the subcommands. For example, an object with a go key allows the user to run tiny abc go.

    // Example implementation for tiny-plugin-abc
    module.exports = {
      go: function() { console.log('go') },
      help: function() { /* help logic */ }
    };
    
    // CLI Usage:
    // $ tiny abc go
  5. Understand the Tiny Toolkit lifecycle

    dev
    The Tiny Toolkit provides a standardized, full-link development solution for specific business scenarios. It abstracts the frontend development lifecycle into six distinct stages, each supported by a consistent set of subcommands. This ensures a uniform development experience regardless of the specific business logic being implemented, reducing the need to memorize complex or lengthy commands.
  6. How @opentiny/cli-devkit works

    dev

    The devkit is an object collection that integrates all Tiny dependencies. It exposes several sub-objects, each providing a specific category of operations (e.g., cache for data storage, logs for console output, config for file manipulation). You can destructure the specific utilities you need directly from the package.

    import { cache, logs } from '@opentiny/cli-devkit';
    
    const log = logs('my-logger');
    log.info('message');
    cache.set('key', 'value');
  7. How Tiny CLI architecture works: Toolkits, Plugins, and Task Flows

    dev

    Tiny CLI is designed as a platform rather than a standalone tool. It provides a framework to manage three core abstractions:

    1. Toolkits (套件): These handle project-level concerns like project initialization (scaffolding) and build/compile processes. They are extensible, allowing developers to contribute new templates to the ecosystem.
    2. Plugins (插件): These address cross-project commonalities. While toolkits focus on the project structure, plugins focus on specific capabilities like ESLint integration, Mock services, Git hooks, or CDN publishing. A plugin can be injected into any project to provide standardized functionality.
    3. Task Flows (任务流): Instead of relying solely on uncontrolled npm scripts, Tiny CLI uses a structured task flow defined in a configuration file. This allows for complex, multi-step execution sequences that can include both CLI plugins and Node.js scripts, providing better control and observability (e.g., enforcing linting before a dev server starts).
  8. Manage API access with @Public and @Permission decorators

    dev

    TinyPro uses decorators to control access to controller endpoints. The auth/auth.guard.ts guard intercepts requests by default.

    • Default Behavior: Any endpoint NOT marked with @Public() requires a valid, non-expired token.
    • @Public(): Use this decorator to allow unauthenticated (guest) access to an endpoint.
    • @Permission(permissionName): Use this to restrict access to users with a specific permission string (e.g., policy::get::list). Users without this permission receive a 403 Forbidden error.
    • Superuser: The admin user has the (*) permission, allowing access to any authenticated endpoint regardless of specific permissions.

    Usage Patterns:

    • Protect a specific method: Apply @Permission to the method.
    • Make a whole controller public: Apply @Public() to the class.
    • Mixed access: A controller can have some methods protected by @Permission and others made public via @Public().
    @Controller('/policy')
    export class PolicyController {
      // Requires login AND 'policy::get::list' permission
      @Get('/list')
      @Permission('policy::get::list')
      async getPolicies(){}
    
      // Allows anyone (even unauthenticated) to access
      @Get('/')
      @Public()
      async getPolicy(){}
    }
  9. Configure task flows

    dev

    You can define custom tasks in the tasks object. If a task name matches an existing toolkit command, the user-defined tasks will execute before the toolkit's native command.

    Tasks can be defined as an array of command objects. Each object can include an async boolean: if set to true, the CLI will not wait for that specific command to complete before proceeding to the next one in the sequence.

    {
       tasks: {
            // Commands executed before 'start'
            start: [{
                command: 'echo test1'
            },{            
                command: 'tiny server',
                // Set async to true to not wait for this command to finish before the next one
                async: true
            }],
            // Commands executed before 'build'
            build: [{
                command: 'gulp clean'
            }]
       }
    }
  10. How the toolkit invocation mechanism works

    dev

    Tiny toolkits are standard npm packages that can run independently. The connection between the tiny CLI and your toolkit is established via the toolkit field in the project's tiny.config.js file.

    When a user runs a command like tiny <command>, the tiny CLI looks up the toolkit specified in tiny.config.js and executes the function corresponding to <command> within that toolkit's exported object.

    // In tiny.config.js
    module.exports = {
      toolkit : "@opentiny/tiny-toolkit-abc"
    }