diff --git a/src/backend/src/Kernel.js b/src/backend/src/Kernel.js
index 1f7a5ecb7..023211653 100644
--- a/src/backend/src/Kernel.js
+++ b/src/backend/src/Kernel.js
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-const { AdvancedBase } = require("@heyputer/putility");
+const { AdvancedBase, libs } = require("@heyputer/putility");
const { Context } = require('./util/context');
const BaseService = require("./services/BaseService");
const useapi = require('useapi');
@@ -25,7 +25,8 @@ const { hideBin } = require('yargs/helpers');
const { Extension } = require("./Extension");
const { ExtensionModule } = require("./ExtensionModule");
const { spawn } = require("node:child_process");
-const { quot } = require("./util/strutil");
+
+const { quot } = libs.string;
class Kernel extends AdvancedBase {
constructor ({ entry_path } = {}) {
diff --git a/src/backend/src/api/APIError.js b/src/backend/src/api/APIError.js
index d8c678dc9..892a69b61 100644
--- a/src/backend/src/api/APIError.js
+++ b/src/backend/src/api/APIError.js
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
const { URLSearchParams } = require("node:url");
-const { quot } = require("../util/strutil");
+const { quot } = require('@heyputer/putility').libs.string;
/**
* APIError represents an error that can be sent to the client.
diff --git a/src/backend/src/boot/RuntimeEnvironment.js b/src/backend/src/boot/RuntimeEnvironment.js
index 4d30eb131..a99e94ea4 100644
--- a/src/backend/src/boot/RuntimeEnvironment.js
+++ b/src/backend/src/boot/RuntimeEnvironment.js
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
const { AdvancedBase } = require("@heyputer/putility");
-const { quot } = require("../util/strutil");
+const { quot } = require('@heyputer/putility').libs.string;
const { TechnicalError } = require("../errors/TechnicalError");
const { print_error_help } = require("../errors/error_help_details");
const default_config = require("./default_config");
diff --git a/src/backend/src/config/ConfigLoader.js b/src/backend/src/config/ConfigLoader.js
index 0bb2bd76c..516a13e3f 100644
--- a/src/backend/src/config/ConfigLoader.js
+++ b/src/backend/src/config/ConfigLoader.js
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
const { AdvancedBase } = require("@heyputer/putility");
-const { quot } = require("../util/strutil");
+const { quot } = require('@heyputer/putility').libs.string;
class ConfigLoader extends AdvancedBase {
static MODULES = {
diff --git a/src/backend/src/errors/error_help_details.js b/src/backend/src/errors/error_help_details.js
index 0a37b4861..d9e0e0dfc 100644
--- a/src/backend/src/errors/error_help_details.js
+++ b/src/backend/src/errors/error_help_details.js
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-const { quot, osclink } = require("../util/strutil");
+const { quot, osclink } = require('@heyputer/putility').libs.string;
const reused = {
runtime_env_references: [
diff --git a/src/backend/src/modules/core/lib/__lib__.js b/src/backend/src/modules/core/lib/__lib__.js
index c5c389e06..30829984c 100644
--- a/src/backend/src/modules/core/lib/__lib__.js
+++ b/src/backend/src/modules/core/lib/__lib__.js
@@ -1,6 +1,5 @@
module.exports = {
util: {
- strutil: require('./string.js'),
logutil: require('./log.js'),
identutil: require('./identifier.js'),
stdioutil: require('./stdio.js'),
diff --git a/src/backend/src/modules/selfhosted/DefaultUserService.js b/src/backend/src/modules/selfhosted/DefaultUserService.js
index 4d032dcec..a0de195f4 100644
--- a/src/backend/src/modules/selfhosted/DefaultUserService.js
+++ b/src/backend/src/modules/selfhosted/DefaultUserService.js
@@ -27,7 +27,7 @@ const { buffer_to_stream } = require("../../util/streamutil");
const BaseService = require("../../services/BaseService");
const { Actor, UserActorType } = require("../../services/auth/Actor");
const { DB_WRITE } = require("../../services/database/consts");
-const { quot } = require("../../util/strutil");
+const { quot } = require('@heyputer/putility').libs.string;
const USERNAME = 'admin';
diff --git a/src/backend/src/modules/web/WebServerService.js b/src/backend/src/modules/web/WebServerService.js
index 448bcc940..be6fa4362 100644
--- a/src/backend/src/modules/web/WebServerService.js
+++ b/src/backend/src/modules/web/WebServerService.js
@@ -30,6 +30,7 @@ const auth = require('../../middleware/auth.js');
const { surrounding_box, es_import_promise } = require('../../fun/dev-console-ui-utils.js');
const relative_require = require;
+const strutil = require('@heyputer/putility').libs.string;
/**
* This class, WebServerService, is responsible for starting and managing the Puter web server.
@@ -37,10 +38,6 @@ const relative_require = require;
* It also validates the host header and IP addresses to prevent security vulnerabilities.
*/
class WebServerService extends BaseService {
- static USE = {
- strutil: 'core.util.strutil',
- }
-
static MODULES = {
https: require('https'),
http: require('http'),
@@ -201,7 +198,7 @@ class WebServerService extends BaseService {
*/
this.startup_widget = () => {
- const link = `\x1B[34;1m${this.strutil.osclink(url)}\x1B[0m`;
+ const link = `\x1B[34;1m${strutil.osclink(url)}\x1B[0m`;
const lines = [
`Puter is now live at: ${link}`,
`Type web:dismiss to un-stick this message`,
diff --git a/src/backend/src/services/AppInformationService.js b/src/backend/src/services/AppInformationService.js
index 8da8d78d9..c38be268c 100644
--- a/src/backend/src/services/AppInformationService.js
+++ b/src/backend/src/services/AppInformationService.js
@@ -18,7 +18,7 @@
* along with this program. If not, see .
*/
const { asyncSafeSetInterval } = require("../util/promise");
-const { MINUTE, SECOND } = require("../util/time");
+const { MINUTE, SECOND } = require("@heyputer/putility").libs.time;
const { origin_from_url } = require("../util/urlutil");
const { DB_READ } = require("./database/consts");
diff --git a/src/backend/src/services/SessionService.js b/src/backend/src/services/SessionService.js
index 873bfd7e3..a083426ba 100644
--- a/src/backend/src/services/SessionService.js
+++ b/src/backend/src/services/SessionService.js
@@ -19,7 +19,7 @@
*/
const { invalidate_cached_user, get_user } = require("../helpers");
const { asyncSafeSetInterval } = require("../util/promise");
-const { MINUTE, SECOND } = require("../util/time");
+const { MINUTE, SECOND } = require("@heyputer/putility").libs.time;
const BaseService = require("./BaseService");
const { DB_WRITE } = require("./database/consts");
diff --git a/src/backend/src/services/StrategizedService.js b/src/backend/src/services/StrategizedService.js
index d2e757404..72c3381f3 100644
--- a/src/backend/src/services/StrategizedService.js
+++ b/src/backend/src/services/StrategizedService.js
@@ -18,7 +18,7 @@
* along with this program. If not, see .
*/
const { TechnicalError } = require("../errors/TechnicalError");
-const { quot } = require("../util/strutil");
+const { quot } = require('@heyputer/putility').libs.string;
/**
diff --git a/src/backend/src/services/TrackSpendingService.js b/src/backend/src/services/TrackSpendingService.js
index d91463467..3c8e32af7 100644
--- a/src/backend/src/services/TrackSpendingService.js
+++ b/src/backend/src/services/TrackSpendingService.js
@@ -19,8 +19,8 @@
*/
const { TimeWindow } = require("../util/opmath");
const SmolUtil = require("../util/smolutil");
-const { format_as_usd } = require("../util/strutil");
-const { MINUTE, SECOND } = require("../util/time");
+const { format_as_usd } = require('@heyputer/putility').libs.string;
+const { MINUTE, SECOND } = require("@heyputer/putility").libs.time;
const BaseService = require("./BaseService");
diff --git a/src/backend/src/services/abuse-prevention/EdgeRateLimitService.js b/src/backend/src/services/abuse-prevention/EdgeRateLimitService.js
index 7e118cca5..bb4809950 100644
--- a/src/backend/src/services/abuse-prevention/EdgeRateLimitService.js
+++ b/src/backend/src/services/abuse-prevention/EdgeRateLimitService.js
@@ -19,9 +19,9 @@
*/
const { Context } = require("../../util/context");
const { asyncSafeSetInterval } = require("../../util/promise");
-const { quot } = require("../../util/strutil");
+const { quot } = require('@heyputer/putility').libs.string;
-const { MINUTE, HOUR } = require('../../util/time.js');
+const { MINUTE, HOUR } = require('@heyputer/putility').libs.time;
const BaseService = require("../BaseService");
/* INCREMENTAL CHANGES
diff --git a/src/backend/src/services/runtime-analysis/ServerHealthService.js b/src/backend/src/services/runtime-analysis/ServerHealthService.js
index 9366f6b1e..c64dbbd17 100644
--- a/src/backend/src/services/runtime-analysis/ServerHealthService.js
+++ b/src/backend/src/services/runtime-analysis/ServerHealthService.js
@@ -18,7 +18,7 @@
* along with this program. If not, see .
*/
const BaseService = require("../BaseService");
-const { SECOND } = require("../../util/time");
+const { SECOND } = require("@heyputer/putility").libs.time;
const { parse_meminfo } = require("../../util/linux");
const { asyncSafeSetInterval, TeePromise } = require("../../util/promise");
diff --git a/src/backend/src/structured/sequence/share.js b/src/backend/src/structured/sequence/share.js
index 68391c6c1..38c3cb8c8 100644
--- a/src/backend/src/structured/sequence/share.js
+++ b/src/backend/src/structured/sequence/share.js
@@ -27,7 +27,7 @@ const { PermissionUtil } = require("../../services/auth/PermissionService");
const FSNodeParam = require("../../api/filesystem/FSNodeParam");
const { TYPE_DIRECTORY } = require("../../filesystem/FSNodeContext");
const { UsernameNotifSelector } = require("../../services/NotificationService");
-const { quot } = require("../../util/strutil");
+const { quot } = require('@heyputer/putility').libs.string;
const { whatis } = require("../../util/langutil");
/*
diff --git a/src/backend/src/util/hl_types.js b/src/backend/src/util/hl_types.js
index 6f0abd5a2..7110f6fe3 100644
--- a/src/backend/src/util/hl_types.js
+++ b/src/backend/src/util/hl_types.js
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-const { quot } = require("./strutil");
+const { quot } = require('@heyputer/putility').libs.string;
const hl_type_definitions = {
flag: {
diff --git a/src/backend/src/util/strutil.js b/src/backend/src/util/strutil.js
deleted file mode 100644
index 2388e63c0..000000000
--- a/src/backend/src/util/strutil.js
+++ /dev/null
@@ -1,2 +0,0 @@
-// This file is a legacy alias
-module.exports = require('../modules/core/lib/string.js');
diff --git a/src/putility/index.js b/src/putility/index.js
index 16ca0b749..95e1deaeb 100644
--- a/src/putility/index.js
+++ b/src/putility/index.js
@@ -31,6 +31,8 @@ module.exports = {
context: require('./src/libs/context'),
listener: require('./src/libs/listener'),
log: require('./src/libs/log'),
+ string: require('./src/libs/string'),
+ time: require('./src/libs/time'),
},
concepts: {
Service,
diff --git a/src/backend/src/modules/core/lib/string.js b/src/putility/src/libs/string.js
similarity index 99%
rename from src/backend/src/modules/core/lib/string.js
rename to src/putility/src/libs/string.js
index 7691ca5dd..c871fc480 100644
--- a/src/backend/src/modules/core/lib/string.js
+++ b/src/putility/src/libs/string.js
@@ -73,3 +73,4 @@ module.exports = {
osclink,
format_as_usd,
};
+
diff --git a/src/backend/src/util/time.js b/src/putility/src/libs/time.js
similarity index 99%
rename from src/backend/src/util/time.js
rename to src/putility/src/libs/time.js
index 17f670141..a24b4f097 100644
--- a/src/backend/src/util/time.js
+++ b/src/putility/src/libs/time.js
@@ -49,3 +49,4 @@ module.exports = {
HOUR,
DAY,
};
+