diff --git a/packages/osd-babel-preset/node_preset.js b/packages/osd-babel-preset/node_preset.js index 43915e239c38..2925c1b76826 100644 --- a/packages/osd-babel-preset/node_preset.js +++ b/packages/osd-babel-preset/node_preset.js @@ -28,6 +28,8 @@ * under the License. */ +const path = require('path'); + module.exports = (_, options = {}) => { return { presets: [ @@ -60,5 +62,17 @@ module.exports = (_, options = {}) => { ], require('./common_preset'), ], + plugins: [ + [ + require.resolve('babel-plugin-module-resolver'), + { + root: [path.resolve(__dirname, '../..')], + alias: { + 'opensearch-dashboards/server': './src/core/server', + 'opensearch-dashboards/public': './src/core/public', + }, + }, + ], + ], }; }; diff --git a/packages/osd-babel-preset/package.json b/packages/osd-babel-preset/package.json index 676afffe7cdc..919b865fa0f3 100644 --- a/packages/osd-babel-preset/package.json +++ b/packages/osd-babel-preset/package.json @@ -15,6 +15,7 @@ "@babel/preset-react": "^7.22.9", "@babel/preset-typescript": "^7.22.9", "babel-plugin-add-module-exports": "^1.0.4", + "babel-plugin-module-resolver": "^5.0.1", "babel-plugin-styled-components": "^2.0.2", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "browserslist": "^4.21.10", diff --git a/packages/osd-optimizer/src/worker/bundle_refs_plugin.ts b/packages/osd-optimizer/src/worker/bundle_refs_plugin.ts index 1eb2cd55eeb5..3fec24ed7114 100644 --- a/packages/osd-optimizer/src/worker/bundle_refs_plugin.ts +++ b/packages/osd-optimizer/src/worker/bundle_refs_plugin.ts @@ -20,7 +20,6 @@ */ import Path from 'path'; -import Fs from 'fs'; import webpack from 'webpack'; @@ -29,20 +28,6 @@ import { BundleRefModule } from './bundle_ref_module'; const RESOLVE_EXTENSIONS = ['.js', '.ts', '.tsx']; -function safeStat(path: string): Promise { - return new Promise((resolve, reject) => { - Fs.stat(path, (error, stat) => { - if (error?.code === 'ENOENT') { - resolve(undefined); - } else if (error) { - reject(error); - } else { - resolve(stat); - } - }); - }); -} - interface RequestData { context: string; dependencies: Array<{ request: string }>; @@ -80,7 +65,7 @@ export class BundleRefsPlugin { const context = data.context; const dep = data.dependencies[0]; - this.maybeReplaceImport(context, dep.request).then( + this.maybeReplaceImport(context, dep.request, compiler).then( (module) => { if (!module) { wrappedFactory(data, callback); @@ -134,64 +119,17 @@ export class BundleRefsPlugin { }); } - private cachedResolveRefEntry(ref: BundleRef) { - const cached = this.resolvedRefEntryCache.get(ref); - - if (cached) { - return cached; - } - - const absoluteRequest = Path.resolve(ref.contextDir, ref.entry); - const promise = this.cachedResolveRequest(absoluteRequest).then((resolved) => { - if (!resolved) { - throw new Error(`Unable to resolve request [${ref.entry}] relative to [${ref.contextDir}]`); - } - - return resolved; - }); - this.resolvedRefEntryCache.set(ref, promise); - return promise; - } - - private cachedResolveRequest(absoluteRequest: string) { - const cached = this.resolvedRequestCache.get(absoluteRequest); - - if (cached) { - return cached; - } - - const promise = this.resolveRequest(absoluteRequest); - this.resolvedRequestCache.set(absoluteRequest, promise); - return promise; - } - - private async resolveRequest(absoluteRequest: string) { - const stats = await safeStat(absoluteRequest); - if (stats && stats.isFile()) { - return absoluteRequest; - } - - // look for an index file in directories - if (stats?.isDirectory()) { - for (const ext of RESOLVE_EXTENSIONS) { - const indexPath = Path.resolve(absoluteRequest, `index${ext}`); - const indexStats = await safeStat(indexPath); - if (indexStats?.isFile()) { - return indexPath; + private async resolve(request: string, startPath: string, compiler: webpack.Compiler) { + const resolver = compiler.resolverFactory.get('normal'); + return new Promise((resolve, reject) => { + resolver.resolve({}, startPath, request, {}, (err: unknown | null, resolvedPath: string) => { + if (err) { + reject(err); + } else { + resolve(resolvedPath); } - } - } - - // look for a file with one of the supported extensions - for (const ext of RESOLVE_EXTENSIONS) { - const filePath = `${absoluteRequest}${ext}`; - const fileStats = await safeStat(filePath); - if (fileStats?.isFile()) { - return filePath; - } - } - - return; + }); + }); } /** @@ -200,9 +138,12 @@ export class BundleRefsPlugin { * then an error is thrown. If the request does not resolve to a bundleRef then * undefined is returned. Otherwise it returns the referenced bundleRef. */ - private async maybeReplaceImport(context: string, request: string) { - // ignore imports that have loaders defined or are not relative seeming - if (request.includes('!') || !request.startsWith('.')) { + private async maybeReplaceImport(context: string, request: string, compiler: webpack.Compiler) { + const alias = Object.keys(compiler.options.resolve?.alias ?? {}); + const isAliasRequest = alias.some((a) => request.startsWith(a)); + + // For non-alias import path, ignore imports that have loaders defined or are not relative seeming + if (!isAliasRequest && (request.includes('!') || !request.startsWith('.'))) { return; } @@ -211,13 +152,12 @@ export class BundleRefsPlugin { return; } - const absoluteRequest = Path.resolve(context, request); - if (absoluteRequest.startsWith(this.ignorePrefix)) { + const resolved = await this.resolve(request, context, compiler); + if (!resolved) { return; } - const resolved = await this.cachedResolveRequest(absoluteRequest); - if (!resolved) { + if (resolved.startsWith(this.ignorePrefix)) { return; } @@ -228,7 +168,7 @@ export class BundleRefsPlugin { } for (const ref of possibleRefs) { - const resolvedEntry = await this.cachedResolveRefEntry(ref); + const resolvedEntry = await this.resolve(`./${ref.entry}`, ref.contextDir, compiler); if (resolved !== resolvedEntry) { continue; } diff --git a/packages/osd-optimizer/src/worker/webpack.config.ts b/packages/osd-optimizer/src/worker/webpack.config.ts index 1917b145a712..e78b0395b5aa 100644 --- a/packages/osd-optimizer/src/worker/webpack.config.ts +++ b/packages/osd-optimizer/src/worker/webpack.config.ts @@ -274,6 +274,7 @@ export function getWebpackConfig(bundle: Bundle, bundleRefs: BundleRefs, worker: mainFields: ['browser', 'main'], alias: { core_app_image_assets: Path.resolve(worker.repoRoot, 'src/core/public/core_app/images'), + 'opensearch-dashboards/public': Path.resolve(worker.repoRoot, 'src/core/public'), }, }, diff --git a/src/plugins/workspace/public/plugin.test.ts b/src/plugins/workspace/public/plugin.test.ts index 75959a3bde98..6894e6d9ccb8 100644 --- a/src/plugins/workspace/public/plugin.test.ts +++ b/src/plugins/workspace/public/plugin.test.ts @@ -6,7 +6,11 @@ import { BehaviorSubject, Observable, Subscriber } from 'rxjs'; import { waitFor } from '@testing-library/dom'; import { first } from 'rxjs/operators'; -import { applicationServiceMock, chromeServiceMock, coreMock } from '../../../core/public/mocks'; +import { + applicationServiceMock, + chromeServiceMock, + coreMock, +} from 'opensearch-dashboards/public/mocks'; import { ChromeBreadcrumb, NavGroupStatus, @@ -14,7 +18,7 @@ import { AppNavLinkStatus, WorkspaceAvailability, AppStatus, -} from '../../../core/public'; +} from 'opensearch-dashboards/public'; import { WORKSPACE_FATAL_ERROR_APP_ID, WORKSPACE_DETAIL_APP_ID } from '../common/constants'; import { savedObjectsManagementPluginMock } from '../../saved_objects_management/public/mocks'; import { managementPluginMock } from '../../management/public/mocks'; diff --git a/src/plugins/workspace/public/plugin.ts b/src/plugins/workspace/public/plugin.ts index 5407be985d0d..03b6ccce2eae 100644 --- a/src/plugins/workspace/public/plugin.ts +++ b/src/plugins/workspace/public/plugin.ts @@ -22,7 +22,8 @@ import { DEFAULT_NAV_GROUPS, NavGroupType, ALL_USE_CASE_ID, -} from '../../../core/public'; +} from 'opensearch-dashboards/public'; +import { getWorkspaceIdFromUrl } from 'opensearch-dashboards/public/utils'; import { WORKSPACE_FATAL_ERROR_APP_ID, WORKSPACE_DETAIL_APP_ID, @@ -32,7 +33,6 @@ import { WORKSPACE_NAVIGATION_APP_ID, WORKSPACE_COLLABORATORS_APP_ID, } from '../common/constants'; -import { getWorkspaceIdFromUrl } from '../../../core/public/utils'; import { Services, WorkspaceUseCase, WorkspacePluginSetup } from './types'; import { WorkspaceClient } from './workspace_client'; import { SavedObjectsManagementPluginSetup } from '../../../plugins/saved_objects_management/public'; diff --git a/src/plugins/workspace/server/plugin.test.ts b/src/plugins/workspace/server/plugin.test.ts index 530f62571dec..040fb013028f 100644 --- a/src/plugins/workspace/server/plugin.test.ts +++ b/src/plugins/workspace/server/plugin.test.ts @@ -4,15 +4,19 @@ */ import { OnPostAuthHandler, OnPreRoutingHandler } from 'src/core/server'; -import { coreMock, httpServerMock, uiSettingsServiceMock } from '../../../core/server/mocks'; +import { + coreMock, + httpServerMock, + uiSettingsServiceMock, +} from 'opensearch-dashboards/server/mocks'; import { WorkspacePlugin, WorkspacePluginDependencies } from './plugin'; import { getACLAuditor, getClientCallAuditor, getWorkspaceState, updateWorkspaceState, -} from '../../../core/server/utils'; -import * as serverUtils from '../../../core/server/utils/auth_info'; +} from 'opensearch-dashboards/server/utils'; +import * as serverUtils from 'opensearch-dashboards/server/utils/auth_info'; import { SavedObjectsPermissionControl } from './permission_control/client'; import { DataSourcePluginSetup } from '../../data_source/server'; import { DataSourceError } from '../../data_source/common/data_sources'; diff --git a/src/plugins/workspace/server/plugin.ts b/src/plugins/workspace/server/plugin.ts index 142976509dc8..7ce3f368a9f2 100644 --- a/src/plugins/workspace/server/plugin.ts +++ b/src/plugins/workspace/server/plugin.ts @@ -13,7 +13,18 @@ import { Logger, CoreStart, SharedGlobalConfig, -} from '../../../core/server'; +} from 'opensearch-dashboards/server'; +import { + cleanWorkspaceId, + cleanUpACLAuditor, + cleanUpClientCallAuditor, + getACLAuditor, + getWorkspaceIdFromUrl, + getWorkspaceState, + initializeACLAuditor, + initializeClientCallAuditor, + updateWorkspaceState, +} from 'opensearch-dashboards/server/utils'; import { WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID, WORKSPACE_CONFLICT_CONTROL_SAVED_OBJECTS_CLIENT_WRAPPER_ID, @@ -33,17 +44,6 @@ import { IWorkspaceClientImpl, WorkspacePluginSetup, WorkspacePluginStart } from import { WorkspaceClient } from './workspace_client'; import { registerRoutes } from './routes'; import { WorkspaceSavedObjectsClientWrapper } from './saved_objects'; -import { - cleanWorkspaceId, - cleanUpACLAuditor, - cleanUpClientCallAuditor, - getACLAuditor, - getWorkspaceIdFromUrl, - getWorkspaceState, - initializeACLAuditor, - initializeClientCallAuditor, - updateWorkspaceState, -} from '../../../core/server/utils'; import { WorkspaceConflictSavedObjectsClientWrapper } from './saved_objects/saved_objects_wrapper_for_check_workspace_conflict'; import { SavedObjectsPermissionControl, diff --git a/tsconfig.base.json b/tsconfig.base.json index b28ec6114012..d122bd79a5de 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -5,11 +5,11 @@ // Allows for importing from `opensearch-dashboards` package for the exported types. "opensearch-dashboards": ["./opensearch_dashboards"], "opensearch-dashboards/public": ["src/core/public"], + "opensearch-dashboards/public/*": ["src/core/public/*"], "opensearch-dashboards/server": ["src/core/server"], + "opensearch-dashboards/server/*": ["src/core/server/*"], "plugins/*": ["src/legacy/core_plugins/*/public/"], - "test_utils/*": [ - "src/test_utils/public/*" - ], + "test_utils/*": ["src/test_utils/public/*"], "fixtures/*": ["src/fixtures/*"], "@opensearch-project/opensearch": ["node_modules/@opensearch-project/opensearch/api/new"], "@opensearch-project/opensearch/lib/*": ["node_modules/@opensearch-project/opensearch/lib/*"], diff --git a/yarn.lock b/yarn.lock index ab362f6380fb..ac3d812a6e3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5612,6 +5612,17 @@ babel-plugin-jest-hoist@^28.1.3: "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" +babel-plugin-module-resolver@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz#cdeac5d4aaa3b08dd1ac23ddbf516660ed2d293e" + integrity sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg== + dependencies: + find-babel-config "^2.1.1" + glob "^9.3.3" + pkg-up "^3.1.0" + reselect "^4.1.7" + resolve "^1.22.8" + babel-plugin-polyfill-corejs2@^0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" @@ -9632,6 +9643,13 @@ finalhandler@1.3.1: statuses "2.0.1" unpipe "~1.0.0" +find-babel-config@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-2.1.2.tgz#2841b1bfbbbcdb971e1e39df8cbc43dafa901716" + integrity sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg== + dependencies: + json5 "^2.2.3" + find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" @@ -10226,6 +10244,16 @@ glob@^8.1.0: minimatch "^5.0.1" once "^1.3.0" +glob@^9.3.3: + version "9.3.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" + integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== + dependencies: + fs.realpath "^1.0.0" + minimatch "^8.0.2" + minipass "^4.2.4" + path-scurry "^1.6.1" + glob@~5.0.0: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" @@ -14010,6 +14038,13 @@ minimatch@^5.0.1, minimatch@^5.1.6: dependencies: brace-expansion "^2.0.1" +minimatch@^8.0.2: + version "8.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229" + integrity sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA== + dependencies: + brace-expansion "^2.0.1" + minimatch@^9.0.4: version "9.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" @@ -14071,6 +14106,11 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" +minipass@^4.2.4: + version "4.2.8" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" + integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== + minipass@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" @@ -15265,7 +15305,7 @@ path-root@^0.1.1: dependencies: path-root-regex "^0.1.0" -path-scurry@^1.11.1: +path-scurry@^1.11.1, path-scurry@^1.6.1: version "1.11.1" resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== @@ -16784,6 +16824,11 @@ reselect@^4.0.0, reselect@^4.1.5: resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.6.tgz#19ca2d3d0b35373a74dc1c98692cdaffb6602656" integrity sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ== +reselect@^4.1.7: + version "4.1.8" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" + integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== + resize-observer-polyfill@^1.5.1: version "1.5.2" resolved "https://registry.yarnpkg.com/@4lolo/resize-observer-polyfill/-/resize-observer-polyfill-1.5.2.tgz#58868fc7224506236b5550d0c68357f0a874b84b"