ProcessorsReference
Project Structure
Standard file layout for processor projects
Project Structure
A processor project follows a standard layout for consistency and ease of development.
Basic Structure
index.ts
package.json
bun.lockb
Dockerfile
cyan.yaml
tsconfig.json
File Descriptions
index.ts
The main entry point using StartProcessorWithLambda:
index.ts
import { StartProcessorWithLambda } from '@atomicloud/cyan-sdk';StartProcessorWithLambda(async (input, fileHelper) => {const files = fileHelper.resolveAll();files.forEach(file => {// Transform file contentfile.content = transform(file.content);file.writeFile();});return { directory: input.writeDirectory };});
main.py
from atomicloud_cyan_sdk import start_processor_with_lambdaasync def handler(input, file_helper):files = file_helper.resolve_all()for file in files:# Transform file contentfile.content = transform(file.content)file.write_file()return {"directory": input.write_directory}start_processor_with_lambda(handler)
Program.cs
using AtomiLoud.CyanSdk;await Processor.StartAsync(async (input, fileHelper) =>{var files = fileHelper.ResolveAll();foreach (var file in files){// Transform file contentfile.Content = Transform(file.Content);file.WriteFile();}return new ProcessorOutput { Directory = input.WriteDirectory };});
package.json
Define dependencies and scripts:
package.json
{"name": "my-processor","version": "1.0.0","type": "module","scripts": {"start": "bun run index.ts","build": "bun build index.ts --outdir=dist"},"dependencies": {"@atomicloud/cyan-sdk": "^1.0.0"},"devDependencies": {"@types/bun": "latest"}}
Dockerfile
Container definition for the processor:
Dockerfile
FROM oven/bun:1.1.31WORKDIR /app# Required: Mark as CyanPrint processorLABEL cyanprint.dev=true# Install dependenciesCOPY package.json bun.lockb* ./RUN bun install --frozen-lockfile# Copy processor codeCOPY . .# Run processorCMD ["bun", "run", "index.ts"]
The LABEL cyanprint.dev=true line is required for the container to be recognized as a CyanPrint processor.
cyan.yaml
Metadata and documentation:
cyan.yaml
name: myorg/my-processorversion: 1.0.0description: Description of what the processor doesauthor: Your Namelicense: MITprocessor:inputs:- name: option1type: stringdefault: "value"description: Description of the option
tsconfig.json
TypeScript configuration:
tsconfig.json
{"compilerOptions": {"target": "ES2022","module": "ESNext","moduleResolution": "bundler","strict": true,"skipLibCheck": true,"esModuleInterop": true},"include": ["*.ts", "src/**/*.ts"]}
Optional Directories
src/
Organize larger processors into modules:
index.ts
tests/
Unit tests for processor logic:
transforms.test.ts
utils.test.ts
Multi-File Example
For complex processors, split logic into modules:
index.ts
// index.tsimport { StartProcessorWithLambda } from '@atomicloud/cyan-sdk';import { transformMarkdown } from './src/transforms/markdown';import { transformCode } from './src/transforms/code';StartProcessorWithLambda(async (input, fileHelper) => {const files = fileHelper.resolveAll();const config = input.config as ProcessorConfig;files.forEach(file => {if (file.relative.endsWith('.md')) {file.content = transformMarkdown(file.content, config);} else if (file.relative.endsWith('.ts')) {file.content = transformCode(file.content, config);}file.writeFile();});return { directory: input.writeDirectory };});
main.py
# main.pyfrom atomicloud_cyan_sdk import start_processor_with_lambdafrom .transforms.markdown import transform_markdownfrom .transforms.code import transform_codeasync def handler(input, file_helper):files = file_helper.resolve_all()config = input.config # Cast to your config typefor file in files:if file.relative.endswith('.md'):file.content = transform_markdown(file.content, config)elif file.relative.endswith('.ts'):file.content = transform_code(file.content, config)file.write_file()return {"directory": input.write_directory}start_processor_with_lambda(handler)
Program.cs
// Program.csusing AtomiLoud.CyanSdk;using MyProcessor.Transforms;await Processor.StartAsync(async (input, fileHelper) =>{var files = fileHelper.ResolveAll();var config = input.Config; // Cast to your config typeforeach (var file in files){if (file.Relative.EndsWith(".md")){file.Content = MarkdownTransform.Transform(file.Content, config);}else if (file.Relative.EndsWith(".ts")){file.Content = CodeTransform.Transform(file.Content, config);}file.WriteFile();}return new ProcessorOutput { Directory = input.WriteDirectory };});