Files
puter/src/phoenix/webpack-resolve-extensions-plugin.js
T
Daniel Salazar 11e057557d
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test (20.x) (push) Has been cancelled
test / test (22.x) (push) Has been cancelled
test / backend (node env, api-test) (22.x) (push) Has been cancelled
test / puterjs (browser env, playwright) (22.x) (push) Has been cancelled
test / puterjs (node env, vitest) (22.x) (push) Has been cancelled
fix: eslint autofixable errors (#2002)
2025-11-21 13:22:19 -08:00

84 lines
3.6 KiB
JavaScript

/*
* 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/>.
*/
import fs from 'node:fs';
import path from 'node:path';
class ResolveExtensionsPlugin {
apply (compiler) {
compiler.hooks.normalModuleFactory.tap('ResolveExtensionsPlugin', (nmf) => {
nmf.hooks.beforeResolve.tap('ResolveExtensionsPlugin', (data) => {
if ( ! data ) return;
// Skip if already has an extension
if ( data.request.match(/\.(js|mjs|json|ts|tsx|css|html)$/) ) {
return;
}
const context = data.context || compiler.options.context || process.cwd();
let requestPath;
// Handle relative imports (starting with ./ or ../)
if ( data.request.startsWith('.') ) {
requestPath = path.resolve(context, data.request);
}
// Handle package subpath imports (like @heyputer/putility/src/libs/promise)
// Only add .js if there's a subpath (more than just the package name)
else if ( data.request.includes('/') && !data.request.startsWith('/') && !data.request.startsWith('.') ) {
const parts = data.request.split('/');
// If there are more than 2 parts (e.g., @scope/pkg/path/to/file), it's a subpath
// Scoped packages like @heyputer/putility have 2 parts for the name
if ( data.request.startsWith('@') ) {
// Scoped package: @scope/pkg/path -> needs 3+ parts for subpath
if ( parts.length > 2 ) {
data.request = `${data.request }.js`;
return;
}
} else {
// Non-scoped package: pkg/path -> needs 2+ parts for subpath
if ( parts.length > 1 ) {
data.request = `${data.request }.js`;
return;
}
}
return; // Top-level package import, don't modify
} else {
return; // Not a relative or package subpath import
}
// Check if .js file exists (for relative imports)
const jsPath = `${requestPath }.js`;
if ( fs.existsSync(jsPath) ) {
data.request = `${data.request }.js`;
return;
}
// Check if it's a directory with index.js
if ( fs.existsSync(requestPath) && fs.statSync(requestPath).isDirectory() ) {
const indexPath = path.join(requestPath, 'index.js');
if ( fs.existsSync(indexPath) ) {
data.request = `${data.request }/index.js`;
}
}
});
});
}
}
export default ResolveExtensionsPlugin;