Contoh Nyata#
Kumpulan template siap pakai untuk berbagai stack. Tinggal copy ke lokio/templates/ dan sesuaikan.
React / Next.js — Component#
configs.yaml#
- name: component
description: React functional component dengan TypeScript
path: component.lokio
output: src/components/<%= pascalCase(name) %>/<%= pascalCase(name) %>.tsx
parameters:
- name: name
type: string
required: true
prompt: "Nama component:"
- name: withProps
type: boolean
required: true
prompt: "Butuh props interface?"
default: truecomponent.lokio#
<%# @lokio required danger "Harus export default" export default %>
<% if (withProps === 'TRUE') { %>
interface <%= pascalCase(name) %>Props {
// tambahkan props di sini
}
export default function <%= pascalCase(name) %>({ }: <%= pascalCase(name) %>Props) {
<% } else { %>
export default function <%= pascalCase(name) %>() {
<% } %>
return (
<div>
<h1><%= titleCase(name) %></h1>
</div>
);
}Generate:
lokio g component UserCardHasil src/components/UserCard/UserCard.tsx:
interface UserCardProps {
// tambahkan props di sini
}
export default function UserCard({ }: UserCardProps) {
return (
<div>
<h1>User Card</h1>
</div>
);
}React / Next.js — Page + Hook (Multi-file)#
configs.yaml#
- name: page
description: Next.js page dengan custom hook
files:
- path: page/index.lokio
output: src/app/<%= kebabCase(name) %>/page.tsx
- path: page/hook.lokio
output: src/hooks/use<%= pascalCase(name) %>.ts
parameters:
- name: name
type: string
required: true
prompt: "Nama halaman:"page/index.lokio#
'use client';
import { use<%= pascalCase(name) %> } from '@/hooks/use<%= pascalCase(name) %>';
export default function <%= pascalCase(name) %>Page() {
const { data, isLoading } = use<%= pascalCase(name) %>();
if (isLoading) return <p>Loading...</p>;
return (
<main>
<h1><%= titleCase(name) %></h1>
</main>
);
}page/hook.lokio#
import { useState, useEffect } from 'react';
export function use<%= pascalCase(name) %>() {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
// fetch data here
setIsLoading(false);
}, []);
return { data, isLoading };
}Generate:
lokio g page dashboardNestJS — Service + Controller (Multi-file)#
configs.yaml#
- name: module
description: NestJS module lengkap (controller + service)
files:
- path: nestjs/service.lokio
output: src/<%= kebabCase(name) %>/<%= kebabCase(name) %>.service.ts
- path: nestjs/controller.lokio
output: src/<%= kebabCase(name) %>/<%= kebabCase(name) %>.controller.ts
parameters:
- name: name
type: string
required: true
prompt: "Nama module:"
- name: type
type: options
required: true
prompt: "Tipe endpoint:"
options:
- REST
- GraphQL
default: REST
hooks:
after_gen:
- bun run build:checknestjs/service.lokio#
import { Injectable } from '@nestjs/common';
@Injectable()
export class <%= pascalCase(name) %>Service {
async findAll(): Promise<<%= pascalCase(name) %>[]> {
return [];
}
async findOne(id: number): Promise<<%= pascalCase(name) %> | null> {
return null;
}
async create(data: Partial<<%= pascalCase(name) %>>): Promise<<%= pascalCase(name) %>> {
return data as <%= pascalCase(name) %>;
}
async update(id: number, data: Partial<<%= pascalCase(name) %>>): Promise<<%= pascalCase(name) %>> {
return { id, ...data } as <%= pascalCase(name) %>;
}
async remove(id: number): Promise<void> {
// delete logic here
}
}nestjs/controller.lokio#
<% if (type === 'REST') { %>
import { Controller, Get, Post, Put, Delete, Param, Body } from '@nestjs/common';
import { <%= pascalCase(name) %>Service } from './<%= kebabCase(name) %>.service';
@Controller('<%= kebabCase(name) %>')
export class <%= pascalCase(name) %>Controller {
constructor(private readonly service: <%= pascalCase(name) %>Service) {}
@Get()
findAll() {
return this.service.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.service.findOne(+id);
}
@Post()
create(@Body() body: any) {
return this.service.create(body);
}
@Put(':id')
update(@Param('id') id: string, @Body() body: any) {
return this.service.update(+id, body);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.service.remove(+id);
}
}
<% } else { %>
import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
import { <%= pascalCase(name) %>Service } from './<%= kebabCase(name) %>.service';
@Resolver()
export class <%= pascalCase(name) %>Resolver {
constructor(private readonly service: <%= pascalCase(name) %>Service) {}
@Query(() => [String])
<%= camelCase(plural(name)) %>() {
return this.service.findAll();
}
@Mutation(() => String)
create<%= pascalCase(name) %>() {
return this.service.create({});
}
}
<% } %>Go — HTTP Handler#
configs.yaml#
- name: handler
description: Go HTTP handler
path: go/handler.lokio
output: internal/handler/<%= snakeCase(name) %>_handler.go
parameters:
- name: name
type: string
required: true
prompt: "Nama handler:"
- name: withMiddleware
type: boolean
required: false
prompt: "Butuh middleware auth?"
default: falsego/handler.lokio#
package handler
import (
"encoding/json"
"net/http"
)
type <%= pascalCase(name) %>Handler struct {
// dependencies
}
func New<%= pascalCase(name) %>Handler() *<%= pascalCase(name) %>Handler {
return &<%= pascalCase(name) %>Handler{}
}
func (h *<%= pascalCase(name) %>Handler) GetAll(w http.ResponseWriter, r *http.Request) {
<% if (withMiddleware === 'TRUE') { %>
// auth check
if r.Header.Get("Authorization") == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
<% } %>
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]any{
"data": []any{},
})
}
func (h *<%= pascalCase(name) %>Handler) RegisterRoutes(mux *http.ServeMux) {
mux.HandleFunc("GET /<%= kebabCase(name) %>", h.GetAll)
}Flutter — Screen + ViewModel#
configs.yaml#
- name: screen
description: Flutter screen dengan ChangeNotifier ViewModel
files:
- path: flutter/screen.lokio
output: lib/features/<%= snakeCase(name) %>/view/<%= snakeCase(name) %>_screen.dart
- path: flutter/viewmodel.lokio
output: lib/features/<%= snakeCase(name) %>/viewmodel/<%= snakeCase(name) %>_viewmodel.dart
parameters:
- name: name
type: string
required: true
prompt: "Nama screen:"
hooks:
after_gen:
- flutter pub getflutter/screen.lokio#
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../viewmodel/<%= snakeCase(name) %>_viewmodel.dart';
class <%= pascalCase(name) %>Screen extends StatelessWidget {
const <%= pascalCase(name) %>Screen({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => <%= pascalCase(name) %>ViewModel(),
child: Scaffold(
appBar: AppBar(title: const Text('<%= titleCase(name) %>')),
body: Consumer<<%= pascalCase(name) %>ViewModel>(
builder: (context, vm, _) {
if (vm.isLoading) {
return const Center(child: CircularProgressIndicator());
}
return const Center(child: Text('<%= titleCase(name) %>'));
},
),
),
);
}
}flutter/viewmodel.lokio#
import 'package:flutter/foundation.dart';
class <%= pascalCase(name) %>ViewModel extends ChangeNotifier {
bool _isLoading = false;
bool get isLoading => _isLoading;
<%= pascalCase(name) %>ViewModel() {
_init();
}
Future<void> _init() async {
_isLoading = true;
notifyListeners();
// load data here
_isLoading = false;
notifyListeners();
}
}Batch Generate — Buat Banyak Service Sekaligus#
Buat file services.json:
[
{ "name": "User" },
{ "name": "Product" },
{ "name": "Order" },
{ "name": "Payment" },
{ "name": "Notification" }
]Generate semua:
lokio gen service --batch services.json✓ [1] name=User → src/services/UserService.ts
✓ [2] name=Product → src/services/ProductService.ts
✓ [3] name=Order → src/services/OrderService.ts
✓ [4] name=Payment → src/services/PaymentService.ts
✓ [5] name=Notification → src/services/NotificationService.ts
Batch complete! (5 succeeded, 0 failed)
lokio.yaml — Referensi Konfigurasi Lengkap#
project:
name: my-awesome-project
version: 1.0.0
# Opsional: Enterprise Hub
enterprise:
enabled: true
code: ENT-xxxxxx
repo: my-awesome-project
# Opsional: konfigurasi lokio check
check:
danger_mode: warn # "warn" atau "block"
templates: # opsional: hanya validasi template ini
- service
- controllerlokio/configs.yaml — Referensi Template Lengkap#
templates:
# Single-file template
- name: service
description: NestJS service class
path: service.lokio # file blueprint
output: src/services/<%= pascalCase(name) %>Service.ts # output path
parameters:
- name: name
type: string
required: true
prompt: "Nama service:"
- name: type
type: options
required: true
prompt: "Tipe:"
options: [basic, repository]
default: basic
hooks:
after_gen:
- bun run format
# Multi-file template
- name: module
description: NestJS module lengkap
files:
- path: module/service.lokio
output: src/<%= kebabCase(name) %>/<%= kebabCase(name) %>.service.ts
- path: module/controller.lokio
output: src/<%= kebabCase(name) %>/<%= kebabCase(name) %>.controller.ts
parameters:
- name: name
type: string
required: true
prompt: "Nama module:"