enerthya.dev-web-common
v1.1.0
Published
Shared web layer for the Enerthya ecosystem: API routes, response envelopes, URL helpers and validators. Inspired by Loritta's web-common and dashboard-common modules.
Maintainers
Readme
enerthya.dev-web-common
Shared web layer for the Enerthya ecosystem. Inspired by Loritta's
loritta-website:web-common+loritta-dashboard:dashboard-commonmodules.
What's inside
| Export | What it does |
|--------|-------------|
| API_ROUTES | Central source of truth for all API route paths — never type route strings twice |
| HTTP_STATUS | Named HTTP status code constants (no more magic numbers) |
| createSuccess(data) | Wraps a payload in { ok: true, data } |
| createError(status, message, code?) | Wraps an error in { ok: false, status, message, code? } |
| isApiSuccess(value) | Returns true if value is a success envelope |
| isApiError(value) | Returns true if value is an error envelope |
| API_ERRORS | Pre-built common errors: NOT_AUTHENTICATED, FORBIDDEN, NOT_FOUND, INTERNAL, BOT_OFFLINE |
| UrlUtils | Dashboard URL builders + snowflake helpers |
| ParamValidator | Validates route params and request bodies — returns { valid, error? } |
Install
npm install enerthya.dev-web-commonUsage
API_ROUTES
const { API_ROUTES } = require("enerthya.dev-web-common");
// Static routes
API_ROUTES.AUTH.USER // "/auth/user"
API_ROUTES.AUTH.LOGOUT // "/auth/logout"
API_ROUTES.GUILDS // "/guilds"
API_ROUTES.STATUS // "/status"
API_ROUTES.COMMANDS // "/commands"
API_ROUTES.DAILY.STATUS // "/daily"
API_ROUTES.DAILY.CAPTCHA // "/daily/captcha"
API_ROUTES.DAILY.CLAIM // "/daily/claim"
// Dynamic routes
API_ROUTES.GUILD_CONFIG("123456") // "/guilds/123456/config"
API_ROUTES.GUILD_WARNS("123456") // "/guilds/123456/warns"
API_ROUTES.GUILD_WARN("123456", "warn_id") // "/guilds/123456/warns/warn_id"
API_ROUTES.GUILD_COMMAND_SETTINGS("123456") // "/guilds/123456/command-settings"Response envelopes
const { createSuccess, createError, isApiError } = require("enerthya.dev-web-common");
// In an Express route handler:
res.json(createSuccess({ guilds: [...] }));
res.status(403).json(createError(403, "Forbidden", "MISSING_PERMISSION"));
// In a React component:
const { data } = await axios.get(API_ROUTES.GUILD_CONFIG(guildId));
if (isApiError(data)) throw new Error(data.message);
const config = data.data; // strongly typed payloadParamValidator
const { ParamValidator, createError, HTTP_STATUS } = require("enerthya.dev-web-common");
router.get("/guilds/:id/config", CheckAuth, async (req, res) => {
const check = ParamValidator.guildId(req.params.id);
if (!check.valid) {
return res.status(HTTP_STATUS.BAD_REQUEST).json(createError(400, check.error));
}
// ... continue safely
});Available validators:
ParamValidator.guildId(id)— Discord snowflakeParamValidator.objectId(id)— MongoDB ObjectId (24 hex chars)ParamValidator.requiredString(value, fieldName, { minLength?, maxLength? })ParamValidator.optionalString(value, fieldName, { maxLength? })ParamValidator.boolean(value, fieldName)ParamValidator.nonNegativeInt(value, fieldName, { max? })ParamValidator.hexColor(value, fieldName)ParamValidator.snowflake(id, fieldName?)ParamValidator.all(...results)— runs multiple validators, returns first failure
UrlUtils
const { UrlUtils } = require("enerthya.dev-web-common");
UrlUtils.guildBase("123456") // "/dashboard/123456"
UrlUtils.guildModule("123456", "welcome") // "/dashboard/123456/welcome"
UrlUtils.parseGuildId("/dashboard/123456/overview") // "123456"
UrlUtils.isValidSnowflake("123456789012345678") // true
UrlUtils.absolute("https://enerthya.dev", "/dashboard/123456") // full URLTest
node test.js
# 84/84 passing