UNPKG

telefunc

Version:

Remote functions. Instead of API.

71 lines (70 loc) 3.45 kB
export { assertNamingConvention }; import { assertWarning, isProduction, assertPosixPath } from '../../utils.js'; async function assertNamingConvention(exportValue, exportName, telefuncFilePath, appRootDir) { if (isProduction()) return; assertStartsWithOn(exportName, telefuncFilePath); await assertCollocation(telefuncFilePath, appRootDir, exportValue); } function assertStartsWithOn(exportName, telefuncFilePath) { if (/on[A-Z]/.test(exportName)) return; if (!/on/.test(exportName)) { assertWarning(false, `We recommend the name of your telefunction ${exportName}() (${telefuncFilePath}) to start with "on", see https://telefunc.com/event-based#naming-convention'`, { onlyOnce: true }); } else { assertWarning(/on[A-Z]/.test(exportName), `The name of your telefunction ${exportName}() (${telefuncFilePath}) starts with "on" but isn't followed by a capital letter, see https://telefunc.com/event-based#naming-convention'`, { onlyOnce: true }); } } async function assertCollocation(telefuncFilePath, appRootDir, exportValue) { appRootDir = appRootDir || exportValue._appRootDir || null; if (!appRootDir) return; let fs; let path; try { fs = await import('node:fs'); path = await import('node:path'); } catch { // The environment doesn't seem to have a filesystem API => skip `assertCollocation()`. // - For example, Cloudflare Workers doesn't have a filesystem API. return; } const getBasename = (fileNameOrPath) => { assertPosixPath(fileNameOrPath); let basename = path.posix.basename(fileNameOrPath).split('.')[0]; if (basename.startsWith('+')) basename = basename.slice(1); return basename; }; assertPosixPath(telefuncFilePath); const telefuncFileBasename = getBasename(telefuncFilePath); const telefuncFileDir = path.posix.dirname(telefuncFilePath); const telefuncFileDirAbsolute = path.posix.join(appRootDir, telefuncFileDir); const collocatedFiles = fs.readdirSync(telefuncFileDirAbsolute); const collocatedFilesMatchYes = []; const collocatedFilesMatchNot = []; collocatedFiles.forEach((fileName) => { assertPosixPath(fileName); // fileName isn't a path so it shouldn't contain any backslash windows path separator const fileBasename = getBasename(fileName); fileName = path.posix.join(telefuncFileDir, fileName); if (fileBasename === telefuncFileBasename) { collocatedFilesMatchYes.push(fileName); } else { collocatedFilesMatchNot.push(fileName); } }); /* There seem to be a race condition: https://github.com/brillout/telefunc/issues/61 assert(collocatedFilesMatchYes.length >= 1, { telefuncFilePathAbsolute, collocatedFiles }) */ assertWarning(collocatedFilesMatchYes.length >= 2, [ `We recommend to collocate ${telefuncFilePath} with a UI component file, see https://telefunc.com/event-based#naming-convention`, ' Your telefunction:', ` ${telefuncFilePath} (base name: '${telefuncFileBasename}')`, ' Its collocated files:', ...collocatedFilesMatchNot.map((fileName) => ` ${fileName} (base name: '${getBasename(fileName)}'`), ` None of its collocated files share its base name '${telefuncFileBasename}'.`, ].join('\n'), { onlyOnce: true }); }