Remove backend-core-0 and inline validation helpers (#2138)

Deleted the src/backend-core-0 package and moved its validation helpers directly into src/backend/src/validation.js. Updated references in CoreModule.js and helpers.js to use the new local validation module. Adjusted ESLint configs to remove backend-core-0 references.
This commit is contained in:
Nariman Jelveh
2025-12-11 13:22:32 -08:00
committed by GitHub
parent 907d0db328
commit 7524933ca1
11 changed files with 63 additions and 223 deletions
-2
View File
@@ -111,7 +111,6 @@ const backendConfig = {
...recommendedJsConfig,
files: [
'src/backend/**/*.{js,mjs,cjs,ts}',
'src/backend-core-0/**/*.{js,mjs,cjs,ts}',
'src/putility/**/*.{js,mjs,cjs,ts}',
],
ignores: [
@@ -151,7 +150,6 @@ const frontendConfig = {
ignores: [
'src/backend/**/*.{js,mjs,cjs,ts}',
'extensions/**/*.{js,mjs,cjs,ts}',
'src/backend-core-0/**/*.{js,mjs,cjs,ts}',
'submodules/**',
'**/*.test.{js,ts,mts,mjs}',
'**/*.min.js',
-2
View File
@@ -49,7 +49,6 @@ export default defineConfig([
files: [
'src/backend/**/*.{js,mjc,cjs}',
'extensions/**/*.{js,mjc,cjs}',
'src/backend-core-0/**/*.{js,mjc,cjs}',
],
ignores: [
'src/backend/src/services/database/sqlite_setup/**/*.js',
@@ -77,7 +76,6 @@ export default defineConfig([
files: [
'src/backend/**/*.{ts}',
'extensions/**/*.{ts}',
'src/backend-core-0/**/*.{ts}',
],
rules: mandatoryRules,
languageOptions: {
-13
View File
@@ -2257,10 +2257,6 @@
"resolved": "src/backend",
"link": true
},
"node_modules/@heyputer/backend-core-0": {
"resolved": "src/backend-core-0",
"link": true
},
"node_modules/@heyputer/gui": {
"resolved": "src/gui",
"link": true
@@ -15997,15 +15993,6 @@
"vitest": "^4.0.14"
}
},
"src/backend-core-0": {
"name": "@heyputer/backend-core-0",
"version": "1.0.0",
"license": "AGPL-3.0-only",
"devDependencies": {
"webpack": "^5.88.2",
"webpack-cli": "^5.1.1"
}
},
"src/backend/node_modules/@opentelemetry/api": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz",
-50
View File
@@ -1,50 +0,0 @@
# What is `backend-core-0`?
The ugly name is intentional. We prefer to refactor incrementally which
means we need a way to "re-core" the backend, and we may do this more
than once simultaneously (hence it's `0` right now).
"re-core" is a term I just made up, and it means this:
> To find the utility code that is not dependent on other utility code,
> move that into a new package, and then continue this process in multiple
> iterations until the problem being solved is solved.
The purpose of `backend-core-0` is to move common dependencies for driver
implementations into a new core so that existing driver implementations
can be moved from backend modules (part of the `backend` package) to
extensions (packages added to Puter at runtime).
What will follow is a log of what was moved here and why.
## 2025-03-31
The AI/LLM driver module depends on constructs related to driver
interfaces. The actual mechanism that facilitates these interfaces,
as well as the interface format, both don't really have a name yet;
I'll call it the "PDIM" (Puter Driver Interface Mechanism) in this log.
The PDIM depends on some class definitions currently in
`src/backend/src/services/drivers/meta` which are split into the categories
of "Constructs" and "Runtime Entities". A construct is the class
representation of something defined in an interface, including
**Interface** itself, and a RuntimeEntity - well there's only one;
it's a wrapper for runtime-typed values such as "jpeg stream".
A construct called **Parameter**, which is the class represerntation
of a parameter of an interface that a driver may implement, depends on
a file called `types.js`. This file defines high-level types like String,
URL, File, etc that can be used in Puter drivers.
Some types depend on utilities in Puter's backend:
- **File**
- filesystem/validation
- `is_valid_uuidv4` from helpers.js
- **URL**
- `is_valid_url` from helpers.js
These utilities do not have dependencies so they are good candidates
to be moved into this package. Afterwards, it currently apperas that
everything in `drivers/meta` can be moved here, allowing DriverService
to finally be moved to a backend module (right now it's part of backend
core), and driver modules like `puterai` will be closer to being able
to be moved to extensions.
-24
View File
@@ -1,24 +0,0 @@
{
"name": "@heyputer/backend-core-0",
"version": "1.0.0",
"description": "The ugly name is intentional. We prefer to refactor incrementally which means we need a way to \"re-core\" the backend, and we may do this more than once simultaneously (hence it's `0` right now).",
"type": "module",
"scripts": {
"build": "webpack",
"prepare": "npm run build",
"test": "echo \"Error: no test specified\" && exit 1"
},
"exports": {
".": {
"require": "./dist/cjs/exports.cjs",
"import": "./dist/esm/exports.js"
}
},
"devDependencies": {
"webpack": "^5.88.2",
"webpack-cli": "^5.1.1"
},
"keywords": [],
"author": "",
"license": "AGPL-3.0-only"
}
-1
View File
@@ -1 +0,0 @@
export * as validation from './pdim/validation.js';
-75
View File
@@ -1,75 +0,0 @@
export const is_valid_uuid = ( uuid ) => {
let s = `${ uuid}`;
s = s.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i);
return !!s;
};
export const is_valid_uuid4 = ( uuid ) => {
return is_valid_uuid(uuid);
};
export const is_specifically_uuidv4 = ( uuid ) => {
let s = `${ uuid}`;
s = s.match(/^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i);
if ( ! s ) {
return false;
}
return true;
};
export const is_valid_url = ( url ) => {
let s = `${ url}`;
try {
new URL(s);
return true;
} catch (e) {
return false;
}
};
const path_excludes = () => /[\x00-\x1F]/g;
// this characters are not allowed in path names because
// they might be used to trick the user into thinking
// a filename is different from what it actually is.
const safety_excludes = [
/[\u202A-\u202E]/, // RTL and LTR override
/[\u200E-\u200F]/, // RTL and LTR mark
/[\u2066-\u2069]/, // RTL and LTR isolate
/[\u2028-\u2029]/, // line and paragraph separator
/[\uFF01-\uFF5E]/, // fullwidth ASCII
/[\u2060]/, // word joiner
/[\uFEFF]/, // zero width no-break space
/[\uFFFE-\uFFFF]/, // non-characters
];
export const is_valid_path = (path, {
no_relative_components,
allow_path_fragment,
} = {}) => {
if ( typeof path !== 'string' ) return false;
if ( path.length < 1 ) false;
if ( path_excludes().test(path) ) return false;
for ( const exclude of safety_excludes ) {
if ( exclude.test(path) ) return false;
}
if ( ! allow_path_fragment ) {
if ( path[0] !== '/' && path[0] !== '.' ) {
return false;
}
}
if ( no_relative_components ) {
const components = path.split('/');
for ( const component of components ) {
if ( component === '' ) continue;
const name_without_dots = component.replace(/\./g, '');
if ( name_without_dots.length < 1 ) return false;
}
}
return true;
};
-53
View File
@@ -1,53 +0,0 @@
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// ESM build
const esmConfig = {
mode: 'production',
entry: './src/exports.js',
experiments: {
outputModule: true,
},
output: {
path: path.resolve(__dirname, 'dist/esm'),
filename: 'exports.js',
module: true,
library: {
type: 'module',
},
},
optimization: {
minimize: false,
},
resolve: {
extensions: ['.js', '.mjs'],
fullySpecified: false,
},
target: 'node',
};
// CJS build
const cjsConfig = {
mode: 'production',
entry: './src/exports.js',
output: {
path: path.resolve(__dirname, 'dist/cjs'),
filename: 'exports.cjs',
library: {
type: 'commonjs2',
},
},
optimization: {
minimize: false,
},
resolve: {
extensions: ['.js', '.mjs'],
fullySpecified: false,
},
target: 'node',
};
export default [esmConfig, cjsConfig];
+2 -2
View File
@@ -74,7 +74,7 @@ const install = async ({ context, services, app, useapi, modapi }) => {
def('core.fs.selectors', require('./filesystem/node/selectors'));
def('core.util.stream', require('./util/streamutil'));
def('web', require('./util/expressutil'));
def('core.validation', require('@heyputer/backend-core-0').validation);
def('core.validation', require('./validation'));
def('core.database', require('./services/database/consts.js'));
@@ -453,4 +453,4 @@ class CoreModule extends AdvancedBase {
}
}
module.exports = CoreModule;
module.exports = CoreModule;
+1 -1
View File
@@ -1713,7 +1713,7 @@ module.exports = {
is_empty,
is_shared_with,
is_shared_with_anyone,
...require('@heyputer/backend-core-0').validation,
...require('./validation'),
is_temp_users_disabled,
is_user_signup_disabled,
jwt_auth,
+60
View File
@@ -0,0 +1,60 @@
/*
* Copyright (C) 2024-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/>.
*/
// Shared validation helpers formerly provided by backend-core-0.
const { is_valid_path } = require('./filesystem/validation');
const is_valid_uuid = (uuid) => {
let s = `${ uuid }`;
s = s.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i);
return !!s;
};
const is_valid_uuid4 = (uuid) => {
return is_valid_uuid(uuid);
};
const is_specifically_uuidv4 = (uuid) => {
let s = `${ uuid }`;
s = s.match(/^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i);
if ( ! s ) {
return false;
}
return true;
};
const is_valid_url = (url) => {
let s = `${ url }`;
try {
new URL(s);
return true;
} catch (e) {
return false;
}
};
module.exports = {
is_valid_uuid,
is_valid_uuid4,
is_specifically_uuidv4,
is_valid_url,
is_valid_path,
};