| 
 | 1 | +import { execSync } from "child_process";  | 
 | 2 | + | 
 | 3 | +/**  | 
 | 4 | + * This is a custom Serverless Framework Plugin that allows you to  | 
 | 5 | + * define and run custom scripts in your serverless.yml file, similar to npm scripts.  | 
 | 6 | + * For more information on creating custom plugins, see the documentation:  | 
 | 7 | + * https://www.serverless.com/framework/docs/guides/plugins/creating-plugins  | 
 | 8 | + *  | 
 | 9 | + * In this AI example, we need to run vite build script before deploying the website service.  | 
 | 10 | + * So we built this quick plugin, and loaded it in the serverless.yml file.  | 
 | 11 | + */  | 
 | 12 | + | 
 | 13 | +class Scripts {  | 
 | 14 | +  constructor(serverless, options, utils) {  | 
 | 15 | +    this.serverless = serverless;  | 
 | 16 | +    this.options = options; // CLI options are passed to the plugin  | 
 | 17 | +    this.utils = utils; // Helper logging functions are passed to the plugin  | 
 | 18 | + | 
 | 19 | +    this.commands = {};  | 
 | 20 | +    this.hooks = {};  | 
 | 21 | + | 
 | 22 | +    this.defineCommands();  | 
 | 23 | +    this.defineHooks();  | 
 | 24 | +  }  | 
 | 25 | + | 
 | 26 | +  getConfig() {  | 
 | 27 | +    const service = this.serverless.service;  | 
 | 28 | +    return service.custom && service.custom.scripts;  | 
 | 29 | +  }  | 
 | 30 | + | 
 | 31 | +  defineCommands() {  | 
 | 32 | +    const config = this.getConfig();  | 
 | 33 | +    const commands = config && config.commands;  | 
 | 34 | +    if (!commands) return;  | 
 | 35 | + | 
 | 36 | +    for (const name of Object.keys(commands)) {  | 
 | 37 | +      if (!this.commands[name]) {  | 
 | 38 | +        this.commands[name] = { lifecycleEvents: [] };  | 
 | 39 | +      }  | 
 | 40 | +      this.commands[name].lifecycleEvents.push(name);  | 
 | 41 | + | 
 | 42 | +      this.hooks[`${name}:${name}`] = this.runCommand.bind(this, name);  | 
 | 43 | +    }  | 
 | 44 | +  }  | 
 | 45 | + | 
 | 46 | +  defineHooks() {  | 
 | 47 | +    const config = this.getConfig();  | 
 | 48 | +    const hooks = config && config.hooks;  | 
 | 49 | +    if (!hooks) return;  | 
 | 50 | + | 
 | 51 | +    for (const name of Object.keys(hooks)) {  | 
 | 52 | +      this.hooks[name] = this.runHook.bind(this, name);  | 
 | 53 | +    }  | 
 | 54 | +  }  | 
 | 55 | + | 
 | 56 | +  runCommand(name) {  | 
 | 57 | +    const commands = this.getConfig().commands;  | 
 | 58 | +    const command = commands[name];  | 
 | 59 | +    this.execute(command);  | 
 | 60 | +  }  | 
 | 61 | + | 
 | 62 | +  runHook(name) {  | 
 | 63 | +    const hooks = this.getConfig().hooks;  | 
 | 64 | +    const hook = hooks[name];  | 
 | 65 | +    this.execute(hook);  | 
 | 66 | +  }  | 
 | 67 | + | 
 | 68 | +  execute(command) {  | 
 | 69 | +    // By default, only show stderr in the terminal  | 
 | 70 | +    // So that you can see any build errors that may occur  | 
 | 71 | +    let stdio = ["ignore", "ignore", "inherit"];  | 
 | 72 | + | 
 | 73 | +    // But in verbose or debug mode, we show all output  | 
 | 74 | +    if (this.options.verbose || this.options.debug) {  | 
 | 75 | +      stdio = "inherit";  | 
 | 76 | +    }  | 
 | 77 | + | 
 | 78 | +    // Execute the command/script in a child service  | 
 | 79 | +    execSync(command, { stdio });  | 
 | 80 | +  }  | 
 | 81 | +}  | 
 | 82 | + | 
 | 83 | +export default Scripts;  | 
0 commit comments