mirror of
https://github.com/HeyPuter/puter.git
synced 2026-05-04 00:20:45 +00:00
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:
@@ -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',
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Generated
-13
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
@@ -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 +0,0 @@
|
||||
export * as validation from './pdim/validation.js';
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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];
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
Reference in New Issue
Block a user