Getting Started
Custom JS lets you create your own Lamuki operation by writing a JavaScript function. Lamuki runs your function separately for every file in the workspace and provides the current file through the file parameter. Use the file's documented structures to read its data, modify its content, or provide operation output, then return the file when your operation is complete.
function customJavascript(file : ActiveFileState){
// write code here
return file
}
Understand the Structures
file.content
{
value : string | Blob
}
file.operation.output
[
{
name : string,
type : "c" | "c" | "c",
value : string | boolean | number,
}
]
What to Modify and What to Avoid
A Custom JS function receives a file object that contains the file data and operation information. You can read the file object freely, but only supported properties should be modified. Lamuki applies changes to the file content and operation output; changes to other properties are not applied and may produce unexpected results.
Modify file.content when you want to change the actual file.
Modify file.operation.output when you want to provide output from the operation.
You can modify both file.content and file.operation.output when an operation needs to change the file and produce output.
Return the file object after making the required changes.
Do not modify other properties of the file object. Changes to properties other than file.content and file.operation.output are not applied by Lamuki and may produce unexpected results.
Examples
File Changer Examples
kebab-case Converter
export default function kebabcaseConverter(file : ActiveFileState): ActiveFileState {
if(file.content == undefined) return file
const text = file.content.value as string;
const words = text
.trim()
.replace(/[^\p{L}\p{N}]+/gu, " ")
.split(/\s+/)
.filter(Boolean);
if (words.length === 0) return file;
const newText = words
.map((word) => word.toLowerCase())
.join("-");
file.content.value = newText
return file;
}SCREAMING_SNAKE_CASE Converter
export default function screamingsnakecaseConverter(file : ActiveFileState) : ActiveFileState {
if(file.content == undefined) return file
const text = file.content.value as string;
const words = text
.trim()
.replace(/[^\p{L}\p{N}]+/gu, " ")
.split(/\s+/)
.filter(Boolean);
if (words.length === 0) return file
const newText = words
.map((word) => word.toUpperCase())
.join("_");
file.content.value = newText
return file
}PascalCase Converter
export default function pascalcaseConverter(file : ActiveFileState) : ActiveFileState {
if(file.content == undefined) return file
const text = file.content.value as string;
const words = text
.trim()
.replace(/[^\p{L}\p{N}]+/gu, " ")
.split(/\s+/)
.filter(Boolean);
if (words.length === 0) return file;
const newText = words
.map(
(word) =>
word.charAt(0).toUpperCase() +
word.slice(1).toLowerCase(),
)
.join("");
file.content.value = newText
return file
}Sentence case Converter
export default function sentenceCaseConverte(file : ActiveFileState) : ActiveFileState {
if(file.content == undefined) return file
const text = file.content.value as string;
const newText = text
.toLowerCase()
.replace(/(^\s*[a-z])|([.!?]\s+[a-z])/g, (match) =>
match.toUpperCase()
);
file.content.value = newText
return file
}TextCase Converter
export default function textcaseConverter(file : ActiveFileState) : ActiveFileState {
if(file.content == undefined) return file
const text = file.content.value as string;
const textCaseConfig = file.operation.input.find(
(c) => c.name.toLowerCase() == "case"
)!;
const caseType = textCaseConfig.value;
if (caseType == "UPPERCASE") return uppercaseConverter(file)
else if (caseType == "lowercase") return lowercaseConverter(file)
else if (caseType == "Title Case") return titleCaseConverter(file)
else if (caseType == "Sentence case") return sentenceCaseConverter(file)
else if (caseType == "camelCase") return camelcaseConverter(file)
else if (caseType == "snake_case") return snakecaseConverter(file)
else if (caseType == "kebab-case") return kebabcaseConverter(file)
else if (caseType == "PascalCase") return pascalcaseConverter(file)
else if (caseType == "SCREAMING_SNAKE_CASE") return screamingsnakecaseConverter(file)
return file
}Non File Changer Examples
Line Counter
export default function lineCounter(file : ActiveFileState): ActiveFileState {
if(file.content == undefined) return file
const text = file.content.value as string;
const lines = text === "" ? 0 : text.split(/\r?\n/).length;
file.operation.output = [
{
name: "Lines",
value: lines,
type: "number",
},
];
return file
}Word Counter
export default function wordCounter(file : ActiveFileState): ActiveFileState {
if(file.content == undefined) return file
const text = file.content.value as string;
const trimmedText = text.trim();
const words =
trimmedText === ""
? 0
: trimmedText.split(/\s+/).length;
const sentences =
trimmedText === ""
? 0
: trimmedText.split(/[.!?]+(?=\s|$)/).filter(Boolean).length;
const characters = text.length;
const paragraphs =
trimmedText === ""
? 0
: trimmedText.split(/\n\s*\n/).filter(Boolean).length;
file.operation.output = [
{
name: "Words",
value: words,
type: "number",
},
{
name: "Sentences",
value: sentences,
type: "number",
},
{
name: "Characters",
value: characters,
type: "number",
},
{
name: "Paragraphs",
value: paragraphs,
type: "number",
},
];
return file
}Character Counter
export default function characterCounter(file : ActiveFileState): ActiveFileState {
if(file.content == undefined) return file
const text = file.content.value as string;
const trimmedText = text.trim();
const words =
trimmedText === ""
? 0
: trimmedText.split(/\s+/).length;
const sentences =
trimmedText === ""
? 0
: trimmedText.split(/[.!?]+(?=\s|$)/).filter(Boolean).length;
const characters = text.length;
const paragraphs =
trimmedText === ""
? 0
: trimmedText.split(/\n\s*\n/).filter(Boolean).length;
file.operation.output = [
{
name: "Characters",
value: characters,
type: "number",
},
{
name: "Words",
value: words,
type: "number",
},
{
name: "Sentences",
value: sentences,
type: "number",
},
{
name: "Paragraphs",
value: paragraphs,
type: "number",
},
];
return file
}