src/backend/doc/contributors/coding-style.md
All files should begin with the standard copyright notice:
/*
* Copyright (C) 2025-present Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const express = require('express');
const passport = require('passport');
const { get_user } = require("../../helpers");
const BaseService = require("../../services/BaseService");
const config = require("../../config");
const path = require('path');
const fs = require('fs');
Import order is generally:
const fn = async () => {
const a = 5; // Spaces between operators
// Note: "=" in for loop initializer does not require space around
// Note: operators in condition part have space around
for ( let i=0; i < 10; i++ ) {
console.log('hello');
}
// Control structures have space inside parenthesis
for ( const thing of stuff ) {
// NOOP
}
// Function calls do not have space inside parenthesis
await something(1, 2);
}
=, +, etc.); not required in
for loop initializer.if, for, while, etc.
return [1,2,3]; // Sure
return[1,2,4]; // Definitely not
if ( a === b ) {
return null;
}
// NOOP within braces// This is great
{
"apple",
"banana",
"cactus", // <-- Good!
}
// This is also fine
[
1, 2, 3,
4, 5, 6,
7, 8, 9,
]
[
something(),
another_thing(),
the_last_thing() // <-- Nope, please add trailing comma!
]
We use trailing commas where applicable because it's easier to re-order lines, especially when using vim motions.
if ( a === b ) return null; // Sure
if ( a === b )
return null; // Please no 🤮
if ( a === b ) {
return null; // Nice
}
const svc_systemData = this.services.get('system-data');
const svc_su = this.services.get('su');
effective_policy = await svc_su.sudo(async () => {
return await svc_systemData.interpret(effective_policy.data);
});
In the example above we see the svc_ prefix is used to indicate a
reference to a backend service. The name of the service is system-data
which is not a valid identifier, so we use svc_systemData for our
variable name.
snake_case because it's easier to
read. camelCase is acceptable too.trailing_underscore_ even if in camelCase_. We avoid using
#privateProperties because it unnecessarily inhibits debugging
and patching.UserService.js)auth-helper.js)BaseService) should have JSDoc comments/**
* @class UserService
* @description Service for managing user operations
*/
/**
* Get a user by their ID
* @param {string} id - The user ID
* @returns {Promise<Object>} The user object
* @throws {Error} If user not found
*/
async function getUserById(id) {
// ...
}
track: to indicate specific purposes// track: slice a prefix
const uid = uid_part.slice('uid#'.length);