├── packages ├── docs │ ├── README.md │ ├── .gitignore │ ├── src │ │ ├── packages │ │ │ ├── index.md │ │ │ ├── vite-plugin-tsc │ │ │ │ └── install.md │ │ │ ├── react-tree │ │ │ │ └── overview.md │ │ │ ├── react-split-view │ │ │ │ ├── overview.md │ │ │ │ └── api.md │ │ │ └── di │ │ │ │ └── integrations │ │ │ │ └── index.md │ │ └── public │ │ │ ├── robots.txt │ │ │ ├── favicon.ico │ │ │ ├── icon.svg │ │ │ └── icon-big.svg │ ├── .vitepress │ │ ├── vue.config.ts │ │ ├── data │ │ │ └── nav.ts │ │ ├── theme │ │ │ ├── index.ts │ │ │ └── playground-links.css │ │ ├── tools │ │ │ └── getGAHeaders.ts │ │ ├── uno.config.ts │ │ └── vite.config.ts │ └── tsconfig.json ├── @wroud │ ├── di-tools-codemod │ │ ├── .gitignore │ │ ├── src │ │ │ ├── constants.ts │ │ │ ├── ITransformerOptions.ts │ │ │ ├── WithDecorators.ts │ │ │ ├── IInjectableDependencyInfo.ts │ │ │ ├── ISupportedPackage.ts │ │ │ ├── isReexportPackage.ts │ │ │ ├── IMigrationOptions.ts │ │ │ ├── findSrcDir.ts │ │ │ ├── isInjectableDecorator.ts │ │ │ ├── isMultipleInjectDecorator.ts │ │ │ ├── isConstructorInjectDecorator.ts │ │ │ ├── getModulePath.ts │ │ │ └── createInjectableDecorator.ts │ │ ├── __testfixtures__ │ │ │ ├── fixture3.input.ts │ │ │ ├── fixture3.output.ts │ │ │ ├── multipleFiles │ │ │ │ ├── fixture3.input.ts │ │ │ │ ├── fixture3.output.ts │ │ │ │ ├── fixture1.module.output.ts │ │ │ │ ├── fixture2.module.output.ts │ │ │ │ ├── fixture4.input.ts │ │ │ │ ├── fixture4.output.ts │ │ │ │ ├── fixture1.input.ts │ │ │ │ ├── fixture1.output.ts │ │ │ │ ├── fixture3.module.output.ts │ │ │ │ ├── fixture2.input.ts │ │ │ │ ├── fixture2.output.ts │ │ │ │ └── fixture4.module.output.ts │ │ │ ├── fixture1.module.output.ts │ │ │ ├── fixture3.module.output.ts │ │ │ ├── esm.module.output.ts │ │ │ ├── fixture4.module.output.ts │ │ │ ├── fixture4.input.ts │ │ │ ├── custom_reexport.input.ts │ │ │ ├── copyright.module.output.ts │ │ │ ├── esm.input.ts │ │ │ ├── copyright.input.ts │ │ │ ├── fixture1.input.ts │ │ │ ├── fixture4.output.ts │ │ │ ├── custom_reexport.output.ts │ │ │ ├── fixture1.output.ts │ │ │ ├── esm.output.ts │ │ │ ├── copyright.output.ts │ │ │ ├── fixture2.input.ts │ │ │ └── fixture2.output.ts │ │ ├── tsconfig.json │ │ └── bin │ │ │ └── di-tools-codemod.cjs │ ├── api-logger │ │ ├── src │ │ │ ├── index.ts │ │ │ └── ILogger.ts │ │ ├── tsconfig.json │ │ └── CHANGELOG.md │ ├── ts-project-linker │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── toPosixPath.ts │ │ │ └── isRootTsConfig.ts │ │ └── tsconfig.json │ ├── flow-middleware │ │ ├── src │ │ │ ├── index.ts │ │ │ └── interfaces │ │ │ │ ├── index.ts │ │ │ │ ├── IMiddlewareRequest.ts │ │ │ │ ├── IMiddlewareSubscribe.ts │ │ │ │ ├── IFlowMiddleware.ts │ │ │ │ ├── IMiddlewareContainer.ts │ │ │ │ ├── IMiddleware.ts │ │ │ │ └── IErrorMiddleware.ts │ │ └── tsconfig.json │ ├── git │ │ ├── src │ │ │ ├── defaultTagPrefix.ts │ │ │ ├── IGitTrailer.ts │ │ │ ├── IGitLink.ts │ │ │ ├── tests │ │ │ │ ├── mockExeca.ts │ │ │ │ └── mockExecaGitChecks.ts │ │ │ ├── getGitPrefixedTag.ts │ │ │ ├── index.ts │ │ │ ├── IGitCommitInfo.ts │ │ │ ├── getGitLastSemverTag.ts │ │ │ └── validateGitEnvironment.ts │ │ ├── __testfixtures__ │ │ │ └── fixture.git-log-path.txt │ │ └── tsconfig.json │ ├── react-tree │ │ ├── src │ │ │ ├── vite.env.d.ts │ │ │ ├── node │ │ │ │ ├── INodeState.ts │ │ │ │ ├── INode.ts │ │ │ │ ├── NodeRenderer.tsx │ │ │ │ └── NodeComponent.ts │ │ │ ├── tree │ │ │ │ ├── TreeContext.ts │ │ │ │ ├── TreeClassesContext.ts │ │ │ │ ├── TreeDataContext.ts │ │ │ │ ├── ITreeData.ts │ │ │ │ └── useClasses.ts │ │ │ ├── viewport │ │ │ │ ├── NodeSizeCacheContext.ts │ │ │ │ └── TreeVirtualizationContext.ts │ │ │ └── controls │ │ │ │ ├── index.ts │ │ │ │ ├── TreeNodeIcon.tsx │ │ │ │ └── TreeNodeName.tsx │ │ └── tsconfig.json │ ├── vite-plugin-playground │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── plugin.ts │ │ │ ├── app │ │ │ │ ├── routes │ │ │ │ │ └── components │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── SearchInput.tsx │ │ │ │ ├── ITheme.ts │ │ │ │ ├── components │ │ │ │ │ ├── Theme.tsx │ │ │ │ │ ├── Isolation.tsx │ │ │ │ │ ├── TopNavLink.tsx │ │ │ │ │ └── LayoutIsolated.tsx │ │ │ │ ├── vite.env.d.ts │ │ │ │ ├── useTheme.ts │ │ │ │ ├── Doc.tsx │ │ │ │ ├── Story.tsx │ │ │ │ ├── Content.tsx │ │ │ │ ├── NodeContent.tsx │ │ │ │ └── Layout.css │ │ │ └── plugin │ │ │ │ └── virtualStoriesModule.ts │ │ ├── vitest.config.ts │ │ └── tsconfig.json │ ├── navigation │ │ ├── src │ │ │ ├── browser.ts │ │ │ ├── IRouteState.ts │ │ │ ├── pattern-matching │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── INavigationState.ts │ │ │ ├── NavigationListener.ts │ │ │ ├── IRouter.ts │ │ │ ├── IRoute.ts │ │ │ └── INavigation.ts │ │ └── tsconfig.json │ ├── react-split-view │ │ ├── src │ │ │ ├── vite.env.d.ts │ │ │ ├── index.ts │ │ │ ├── ISplitViewProps.ts │ │ │ ├── ISplitViewSash.ts │ │ │ ├── ISplitViewSashProps.ts │ │ │ └── ISplitView.ts │ │ └── tsconfig.json │ ├── ci │ │ ├── src │ │ │ ├── defaultChangelogFile.ts │ │ │ └── readPackageJson.ts │ │ └── tsconfig.json │ ├── di-tools-benchmark │ │ ├── src │ │ │ └── benchmark │ │ │ │ ├── IEntry.ts │ │ │ │ ├── buildDeepChain.ts │ │ │ │ └── bundle.ts │ │ ├── tsconfig.common.json │ │ ├── tsconfig.json │ │ ├── tsconfig.modern.json │ │ └── tsconfig.legacy-decorators.json │ ├── conventional-commits-bump │ │ ├── src │ │ │ ├── index.ts │ │ │ └── getConventionalCommitsBump.ts │ │ └── tsconfig.json │ ├── di │ │ ├── src │ │ │ ├── development.ts │ │ │ ├── helpers │ │ │ │ ├── EMPTY_DEPS.ts │ │ │ │ ├── isServiceProvider.ts │ │ │ │ ├── isJsEntityName.ts │ │ │ │ ├── requestPathToArray.ts │ │ │ │ ├── getServiceTypeFromDependency.ts │ │ │ │ ├── resolveGeneratorAsync.ts │ │ │ │ ├── getNameOfDescriptor.ts │ │ │ │ └── resolveGeneratorSync.ts │ │ │ ├── di │ │ │ │ ├── ServiceLifetime.ts │ │ │ │ ├── errors │ │ │ │ │ └── AsyncServiceImplementationError.ts │ │ │ │ ├── createService.ts │ │ │ │ ├── IBaseServiceResolutions.ts │ │ │ │ ├── validation │ │ │ │ │ ├── validateAsyncImplementation.ts │ │ │ │ │ └── validateRequestPath.ts │ │ │ │ ├── createService.test.ts │ │ │ │ ├── ServiceProvider.development.test.ts │ │ │ │ ├── IServiceProvider.ts │ │ │ │ └── ServiceRegistry.ts │ │ │ ├── types │ │ │ │ ├── IRequestPathNode.ts │ │ │ │ ├── IServiceConstructor.ts │ │ │ │ ├── IAbstractServiceConstructor.ts │ │ │ │ ├── IServiceScope.ts │ │ │ │ ├── IServiceFactory.ts │ │ │ │ ├── IAsyncServiceScope.ts │ │ │ │ ├── IServiceCollectionElement.ts │ │ │ │ ├── RequestPath.ts │ │ │ │ ├── IServiceMetadata.ts │ │ │ │ ├── IServiceImplementation.ts │ │ │ │ ├── IResolvedServiceImplementation.ts │ │ │ │ ├── ServiceImplementation.ts │ │ │ │ ├── SingleServiceType.ts │ │ │ │ ├── IServiceDescriptor.ts │ │ │ │ ├── IServiceDescriptorResolver.ts │ │ │ │ ├── IServiceTypeResolver.ts │ │ │ │ ├── ServiceType.ts │ │ │ │ ├── IServiceInstancesStore.ts │ │ │ │ ├── IServiceInstanceInfo.ts │ │ │ │ ├── IServiceImplementationResolver.ts │ │ │ │ └── MapToServicesType.ts │ │ │ ├── module │ │ │ │ ├── IModuleEventListener.ts │ │ │ │ └── IModule.ts │ │ │ ├── implementation-resolvers │ │ │ │ ├── value.ts │ │ │ │ ├── isAsyncServiceImplementation.ts │ │ │ │ ├── proxy.ts │ │ │ │ ├── lazy.ts │ │ │ │ ├── constructor.ts │ │ │ │ ├── ValueServiceImplementationResolver.ts │ │ │ │ ├── ProxyServiceImplementationResolver.ts │ │ │ │ └── AsyncServiceImplementationResolver.development.test.ts │ │ │ ├── Service.ts │ │ │ ├── extras │ │ │ │ ├── index.ts │ │ │ │ ├── service-type-resolvers │ │ │ │ │ └── withExternal.ts │ │ │ │ └── implementation-resolvers │ │ │ │ │ ├── external.ts │ │ │ │ │ └── conditional.ts │ │ │ ├── service-type-resolvers │ │ │ │ ├── all.ts │ │ │ │ ├── single.ts │ │ │ │ └── optional.ts │ │ │ ├── tests │ │ │ │ ├── createSyncMockedService.ts │ │ │ │ └── createAsyncMockedService.ts │ │ │ └── debug.ts │ │ └── tsconfig.json │ ├── vite-plugin-ssg │ │ ├── src │ │ │ ├── utils │ │ │ │ ├── trailingSeparatorRE.ts │ │ │ │ ├── getPageName.ts │ │ │ │ ├── error │ │ │ │ │ ├── ISerializedError.ts │ │ │ │ │ ├── serializeError.ts │ │ │ │ │ └── deserializeError.ts │ │ │ │ ├── withTrailingSlash.ts │ │ │ │ ├── cleanUrl.ts │ │ │ │ ├── isDevServer.ts │ │ │ │ ├── getHrefFromPath.ts │ │ │ │ ├── mapBaseToUrl.ts │ │ │ │ ├── stripBase.ts │ │ │ │ ├── getBaseInHTML.ts │ │ │ │ ├── unescapeHtml.ts │ │ │ │ ├── removeNoInlineQuery.ts │ │ │ │ ├── tryStatSync.ts │ │ │ │ ├── ssgHtmlTags.ts │ │ │ │ ├── withTrailingSlash.test.ts │ │ │ │ ├── getPathsToLookup.ts │ │ │ │ ├── stripBase.test.ts │ │ │ │ ├── getPathsToLookup.test.ts │ │ │ │ ├── cleanUrl.test.ts │ │ │ │ ├── changePathExt.test.ts │ │ │ │ ├── isGitLfsPlaceholder.ts │ │ │ │ ├── removeNoInlineQuery.test.ts │ │ │ │ ├── splitFileAndPostfix.ts │ │ │ │ └── changePathExt.ts │ │ │ ├── app │ │ │ │ └── IAppContext.ts │ │ │ ├── SsgPluginOptions.ts │ │ │ ├── app.ts │ │ │ ├── IEntryDescriptor.ts │ │ │ ├── react │ │ │ │ ├── components │ │ │ │ │ ├── SSGContext.ts │ │ │ │ │ ├── useBase.ts │ │ │ │ │ ├── Html.tsx │ │ │ │ │ ├── AppContext.ts │ │ │ │ │ ├── Link.tsx │ │ │ │ │ ├── Script.tsx │ │ │ │ │ ├── Body.tsx │ │ │ │ │ └── Head.tsx │ │ │ │ ├── components.ts │ │ │ │ ├── mapHtmlTagsToReactTags.ts │ │ │ │ ├── IndexComponent.ts │ │ │ │ ├── pathUrlWithBase.ts │ │ │ │ └── mapHtmlAttributeToReactProps.ts │ │ │ ├── modules │ │ │ │ ├── isVirtualHtmlEntry.ts │ │ │ │ ├── removeUrlQuery.ts │ │ │ │ ├── isSsgAssetId.ts │ │ │ │ ├── isSsgUrl.ts │ │ │ │ ├── isSsgId.ts │ │ │ │ ├── mainQuery.ts │ │ │ │ ├── isSsgPageUrlId.ts │ │ │ │ ├── isSsgServerEntryId.ts │ │ │ │ ├── ssgEntryQuery.ts │ │ │ │ ├── isSsgComponentId.ts │ │ │ │ └── isSsgClientEntryId.ts │ │ │ └── resolveHtmlTags.ts │ │ └── tsconfig.json │ ├── playground │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── PlaygroundRoutes.ts │ │ │ └── IPlaygroundContext.ts │ │ └── tsconfig.json │ ├── preconditions │ │ ├── src │ │ │ ├── index.ts │ │ │ └── IPrecondition.ts │ │ └── tsconfig.json │ ├── ts-template │ │ ├── src │ │ │ ├── getTsWithVersion.ts │ │ │ ├── cli.ts │ │ │ ├── ES_TARGETS.ts │ │ │ ├── templates │ │ │ │ └── project │ │ │ │ │ └── getTsConfigTemplate.ts │ │ │ ├── getDefaultProjectName.ts │ │ │ └── parsePackageName.ts │ │ └── tsconfig.json │ ├── tsconfig │ │ └── package.json │ ├── playground-react │ │ ├── src │ │ │ ├── IDescribe.ts │ │ │ ├── IDoc.ts │ │ │ ├── index.ts │ │ │ ├── hooks │ │ │ │ ├── useNavigation.ts │ │ │ │ ├── useStoriesListener.ts │ │ │ │ ├── useDoc.ts │ │ │ │ ├── useNode.ts │ │ │ │ ├── useStory.ts │ │ │ │ └── useDescribes.ts │ │ │ ├── IStory.ts │ │ │ ├── views.ts │ │ │ ├── doc.ts │ │ │ ├── story.ts │ │ │ ├── views │ │ │ │ └── MarkdownView.tsx │ │ │ ├── registry.ts │ │ │ ├── svg │ │ │ │ └── Loader.tsx │ │ │ └── registry │ │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── tests-runner │ │ ├── vitest.setup.ts │ │ ├── jest-extended.d.ts │ │ ├── tsconfig.json │ │ ├── bin │ │ │ ├── tests-runner.mjs │ │ │ └── benchmark.mjs │ │ └── package.json │ ├── di-tools-analyzer │ │ ├── src │ │ │ ├── IChart.ts │ │ │ ├── index.ts │ │ │ ├── chart │ │ │ │ ├── Layout.ts │ │ │ │ ├── createForceSimulation.ts │ │ │ │ └── getLinkPoints.ts │ │ │ ├── IGraph.ts │ │ │ ├── loadImplementation.ts │ │ │ ├── isOptionalDependency.ts │ │ │ └── isOptionalDependency.test.ts │ │ └── tsconfig.json │ ├── conventional-commits-parser │ │ ├── src │ │ │ ├── gitTrailersConventionalCommits.ts │ │ │ ├── index.ts │ │ │ └── IConventionalCommit.ts │ │ └── tsconfig.json │ ├── github │ │ ├── src │ │ │ ├── IGithubTrailers.ts │ │ │ ├── IGithubCoAuthor.ts │ │ │ ├── gitGithubLinks.ts │ │ │ ├── index.ts │ │ │ ├── GithubURL.ts │ │ │ └── getGithubLink.ts │ │ └── tsconfig.json │ ├── vite-plugin-asset-resolver │ │ ├── src │ │ │ ├── IResolveAssetsOptions.ts │ │ │ └── getPossiblePaths.ts │ │ └── tsconfig.json │ ├── react-reactive-value │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── IReactiveValue.ts │ │ │ └── useCreateReactiveValue.ts │ │ ├── tsconfig.json │ │ └── CHANGELOG.md │ ├── di-react │ │ ├── src │ │ │ ├── tests │ │ │ │ └── testingLibrary.ts │ │ │ ├── ServiceProviderContext.ts │ │ │ ├── index.ts │ │ │ ├── useServices.ts │ │ │ ├── useServiceSync.ts │ │ │ ├── useServicesSync.ts │ │ │ ├── useServiceProvider.ts │ │ │ ├── useService.ts │ │ │ ├── useAbandonedRenderDisposer.ts │ │ │ ├── ServiceProvider.tsx │ │ │ ├── useServiceCreateScope.ts │ │ │ └── useServiceCreateAsyncScope.ts │ │ └── tsconfig.json │ ├── conventional-commits-changelog │ │ ├── src │ │ │ ├── IConventionalCommitCoAuthor.ts │ │ │ ├── IConventionalCommitMetadata.ts │ │ │ ├── conventionalChangelogMarkers.ts │ │ │ ├── index.ts │ │ │ ├── IConventionalCommitWithMetadata.ts │ │ │ ├── createChangelogHeader.ts │ │ │ ├── createChangelogHeader.test.ts │ │ │ └── createConventionalChangelogHeader.test.ts │ │ ├── tsconfig.json │ │ └── __snapshots__ │ │ │ ├── createConventionalChangelogHeader.test.js.snap │ │ │ └── createChangelogHeader.test.js.snap │ └── vite-plugin-tsc │ │ └── tsconfig.json ├── yarn-plugin-ts-project-linker │ ├── README.md │ ├── tsconfig.json │ └── src │ │ └── index.mts ├── graphql-codegen-fragment-masking │ └── tsconfig.json └── graphql-codegen-typed-document-nodes │ └── tsconfig.json ├── .husky └── commit-msg ├── commitlint.config.js ├── .vscode ├── extensions.json └── tasks.json ├── .yarn └── sdks │ ├── integrations.yml │ ├── prettier │ └── package.json │ └── typescript │ └── package.json ├── .gitattributes ├── .editorconfig ├── .yarnrc.yml ├── .gitignore └── .github ├── workflows └── push-main.yml └── FUNDING.yml /packages/docs/README.md: -------------------------------------------------------------------------------- 1 | # docs 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | yarn commitlint --edit $1 2 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/.gitignore: -------------------------------------------------------------------------------- 1 | commonjs -------------------------------------------------------------------------------- /packages/@wroud/api-logger/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ILogger.js"; 2 | -------------------------------------------------------------------------------- /packages/@wroud/ts-project-linker/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./link.js"; 2 | -------------------------------------------------------------------------------- /packages/docs/.gitignore: -------------------------------------------------------------------------------- 1 | .vitepress/dist 2 | .vitepress/cache 3 | components.d.ts -------------------------------------------------------------------------------- /packages/@wroud/flow-middleware/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./FlowMiddleware.js"; 2 | -------------------------------------------------------------------------------- /packages/@wroud/git/src/defaultTagPrefix.ts: -------------------------------------------------------------------------------- 1 | export const defaultTagPrefix = "v"; 2 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/vite.env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./plugin.js"; 2 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | export default { extends: ["@commitlint/config-conventional"] }; 2 | -------------------------------------------------------------------------------- /packages/@wroud/navigation/src/browser.ts: -------------------------------------------------------------------------------- 1 | export * from "./browser/BrowserNavigation.js"; 2 | -------------------------------------------------------------------------------- /packages/@wroud/react-split-view/src/vite.env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/plugin.ts: -------------------------------------------------------------------------------- 1 | export * from "./plugin/plugin.js"; 2 | -------------------------------------------------------------------------------- /packages/docs/src/packages/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # Packages 6 | 7 | -------------------------------------------------------------------------------- /packages/@wroud/ci/src/defaultChangelogFile.ts: -------------------------------------------------------------------------------- 1 | export const defaultChangelogFile = "CHANGELOG.md"; 2 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-benchmark/src/benchmark/IEntry.ts: -------------------------------------------------------------------------------- 1 | export type IEntry = [unknown, unknown]; 2 | -------------------------------------------------------------------------------- /packages/@wroud/conventional-commits-bump/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./getConventionalCommitsBump.js"; 2 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/development.ts: -------------------------------------------------------------------------------- 1 | import "./debugDevelopment.js"; 2 | export * from "./production.js"; 3 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/helpers/EMPTY_DEPS.ts: -------------------------------------------------------------------------------- 1 | export const EMPTY_DEPS: readonly any[] = Object.freeze([]); 2 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/trailingSeparatorRE.ts: -------------------------------------------------------------------------------- 1 | export const trailingSeparatorRE = /[?&]$/; 2 | -------------------------------------------------------------------------------- /packages/docs/src/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | 4 | Sitemap: https://wroud.dev/sitemap.xml -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/app/IAppContext.ts: -------------------------------------------------------------------------------- 1 | export interface IAppContext { 2 | base: string; 3 | } 4 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const CONSTANTS = { 2 | injectable: "injectable", 3 | }; 4 | -------------------------------------------------------------------------------- /packages/@wroud/git/src/IGitTrailer.ts: -------------------------------------------------------------------------------- 1 | export interface IGitTrailer { 2 | token: string; 3 | value: string; 4 | } 5 | -------------------------------------------------------------------------------- /packages/@wroud/react-split-view/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ISplitView.js"; 2 | export * from "./useSplitView.js"; 3 | -------------------------------------------------------------------------------- /packages/@wroud/playground/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./IPlaygroundContext.js"; 2 | export * from "./PlaygroundRoutes.js"; 3 | -------------------------------------------------------------------------------- /packages/@wroud/preconditions/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./IPrecondition.js"; 2 | export * from "./PreconditionManager.js"; 3 | -------------------------------------------------------------------------------- /packages/docs/src/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wroud/foundation/HEAD/packages/docs/src/public/favicon.ico -------------------------------------------------------------------------------- /packages/@wroud/di/src/di/ServiceLifetime.ts: -------------------------------------------------------------------------------- 1 | export enum ServiceLifetime { 2 | Singleton, 3 | Scoped, 4 | Transient, 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/app/routes/components/index.ts: -------------------------------------------------------------------------------- 1 | export { ComponentsGrid } from "./ComponentsGrid.js"; 2 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/SsgPluginOptions.ts: -------------------------------------------------------------------------------- 1 | export interface SsgPluginOptions { 2 | renderTimeout?: number; 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "arcanis.vscode-zipfs", 4 | "esbenp.prettier-vscode" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/ts-template/src/getTsWithVersion.ts: -------------------------------------------------------------------------------- 1 | export function getTsWithVersion(): string { 2 | return `typescript@^5`; 3 | } 4 | -------------------------------------------------------------------------------- /packages/@wroud/git/src/IGitLink.ts: -------------------------------------------------------------------------------- 1 | export interface IGitLink { 2 | token: string; 3 | link: string; 4 | [key: string]: string; 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/node/INodeState.ts: -------------------------------------------------------------------------------- 1 | export interface INodeState { 2 | selected: boolean; 3 | expanded: boolean; 4 | } 5 | -------------------------------------------------------------------------------- /packages/@wroud/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@wroud/tsconfig", 3 | "private": true, 4 | "packageManager": "yarn@4.9.1" 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/react-split-view/src/ISplitViewProps.ts: -------------------------------------------------------------------------------- 1 | export interface ISplitViewProps { 2 | ref: React.Ref; 3 | } 4 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/IRequestPathNode.ts: -------------------------------------------------------------------------------- 1 | export interface IRequestPathNode { 2 | value: T; 3 | next: IRequestPathNode | null; 4 | } 5 | -------------------------------------------------------------------------------- /packages/@wroud/git/src/tests/mockExeca.ts: -------------------------------------------------------------------------------- 1 | import { vi } from "vitest"; 2 | 3 | vi.mock(import("execa"), () => ({ 4 | execa: vi.fn(), 5 | })); 6 | -------------------------------------------------------------------------------- /packages/@wroud/ts-project-linker/src/toPosixPath.ts: -------------------------------------------------------------------------------- 1 | export function toPosixPath(path: string): string { 2 | return path.replace(/\\/g, "/"); 3 | } 4 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/src/ITransformerOptions.ts: -------------------------------------------------------------------------------- 1 | export interface ITransformerOptions { 2 | esm?: boolean; 3 | copyright?: string; 4 | } 5 | -------------------------------------------------------------------------------- /packages/@wroud/playground-react/src/IDescribe.ts: -------------------------------------------------------------------------------- 1 | export interface IDescribe { 2 | id: string; 3 | name: string; 4 | parent: IDescribe | null; 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/app/ITheme.ts: -------------------------------------------------------------------------------- 1 | export interface ITheme { 2 | theme: "light" | "dark"; 3 | switchTheme: () => void; 4 | } 5 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/app.ts: -------------------------------------------------------------------------------- 1 | export * from "./app/IAppContext.js"; 2 | export { AppInstance, createAppConfig } from "./app/AppInstance.js"; 3 | -------------------------------------------------------------------------------- /.yarn/sdks/integrations.yml: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by @yarnpkg/sdks. 2 | # Manual changes might be lost! 3 | 4 | integrations: 5 | - vscode 6 | -------------------------------------------------------------------------------- /packages/@wroud/tests-runner/vitest.setup.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "vitest"; 2 | import * as matchers from "jest-extended"; 3 | 4 | expect.extend(matchers); 5 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/IServiceConstructor.ts: -------------------------------------------------------------------------------- 1 | export type IServiceConstructor = new ( 2 | ...args: TArgs 3 | ) => T; 4 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/node/INode.ts: -------------------------------------------------------------------------------- 1 | export interface INode { 2 | name: string; 3 | tooltip?: string; 4 | icon?: string; 5 | leaf?: boolean; 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/ts-project-linker/src/isRootTsConfig.ts: -------------------------------------------------------------------------------- 1 | export function isRootTsConfig(path: string): boolean { 2 | return path.endsWith("tsconfig.json"); 3 | } 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /.yarn/** linguist-vendored 2 | /.yarn/releases/* binary 3 | /.yarn/plugins/**/* binary 4 | /.pnp.* binary linguist-generated 5 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-analyzer/src/IChart.ts: -------------------------------------------------------------------------------- 1 | import type { IGraph } from "./IGraph.js"; 2 | 3 | export interface IChart { 4 | update(graph: IGraph): void; 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/getPageName.ts: -------------------------------------------------------------------------------- 1 | export function getPageName(id: string) { 2 | return id.replace(/^\//, "").replace(/\/$/, "/index"); 3 | } 4 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/src/WithDecorators.ts: -------------------------------------------------------------------------------- 1 | import type { Decorator } from "jscodeshift"; 2 | 3 | export type WithDecorators = T & { decorators?: Decorator[] | null }; 4 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/module/IModuleEventListener.ts: -------------------------------------------------------------------------------- 1 | import type { IModule } from "./IModule.js"; 2 | 3 | export interface IModuleEventListener { 4 | (module: IModule): void; 5 | } 6 | -------------------------------------------------------------------------------- /.yarn/sdks/prettier/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prettier", 3 | "version": "3.5.3-sdk", 4 | "main": "./index.cjs", 5 | "type": "commonjs", 6 | "bin": "./bin/prettier.cjs" 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/ts-template/src/cli.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { configureYargs } from "./cliConfiguration.js"; 3 | 4 | await configureYargs(process.argv, process.cwd()).parse(); 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | 7 | [*.{js,json,yml}] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /packages/@wroud/conventional-commits-parser/src/gitTrailersConventionalCommits.ts: -------------------------------------------------------------------------------- 1 | export const gitTrailersConventionalCommits = [ 2 | /^(?BREAKING CHANGE):[\s\t]*(?.+)$/, 3 | ]; 4 | -------------------------------------------------------------------------------- /packages/@wroud/github/src/IGithubTrailers.ts: -------------------------------------------------------------------------------- 1 | import type { IGithubCoAuthor } from "./IGithubCoAuthor.js"; 2 | 3 | export interface IGithubTrailers { 4 | coAuthors: IGithubCoAuthor[]; 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-asset-resolver/src/IResolveAssetsOptions.ts: -------------------------------------------------------------------------------- 1 | export interface IResolveAssetsOptions { 2 | dist?: string[]; 3 | src?: string[]; 4 | extensions?: string[]; 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/IAbstractServiceConstructor.ts: -------------------------------------------------------------------------------- 1 | export type IAbstractServiceConstructor< 2 | T, 3 | TArgs extends unknown[] = unknown[], 4 | > = abstract new (...args: TArgs) => T; 5 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/vue.config.ts: -------------------------------------------------------------------------------- 1 | import { Options } from "@vitejs/plugin-vue"; 2 | 3 | export default { 4 | script: { 5 | babelParserPlugins: ["decorators"], 6 | }, 7 | } as Options; 8 | -------------------------------------------------------------------------------- /packages/@wroud/github/src/IGithubCoAuthor.ts: -------------------------------------------------------------------------------- 1 | export interface IGithubCoAuthor { 2 | name: string; 3 | username?: string; 4 | usernameLink?: string; 5 | link?: string; 6 | email?: string; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/conventional-commits-parser/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./IConventionalCommit.js"; 2 | export * from "./parseConventionalCommit.js"; 3 | export * from "./gitTrailersConventionalCommits.js"; 4 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/di/errors/AsyncServiceImplementationError.ts: -------------------------------------------------------------------------------- 1 | export class AsyncServiceImplementationError extends Error { 2 | constructor() { 3 | super("Service is not loaded yet"); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/error/ISerializedError.ts: -------------------------------------------------------------------------------- 1 | export interface ISerializedError { 2 | name?: string; 3 | message?: string; 4 | stack?: string; 5 | [key: string]: unknown; 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/tree/TreeContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | import type { ITree } from "./ITree.js"; 4 | 5 | export const TreeContext = createContext(null); 6 | -------------------------------------------------------------------------------- /packages/@wroud/flow-middleware/src/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./IErrorMiddleware.js"; 2 | export * from "./IMiddleware.js"; 3 | export * from "./IMiddlewareRequest.js"; 4 | export * from "./IFlowMiddleware.js"; 5 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/src/IInjectableDependencyInfo.ts: -------------------------------------------------------------------------------- 1 | import type { Identifier } from "jscodeshift"; 2 | 3 | export interface IInjectableDependencyInfo { 4 | multiple: boolean; 5 | type: Identifier; 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/react-reactive-value/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./useCreateReactiveValue.js"; 2 | export * from "./useReactiveValue.js"; 3 | export * from "./useReactiveValues.js"; 4 | export * from "./IReactiveValue.js"; 5 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/app/components/Theme.tsx: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | import type { ITheme } from "../ITheme.js"; 3 | 4 | export const Theme = createContext(null); 5 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/withTrailingSlash.ts: -------------------------------------------------------------------------------- 1 | export function withTrailingSlash(path: string): string { 2 | if (path[path.length - 1] !== "/") { 3 | return `${path}/`; 4 | } 5 | return path; 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/IServiceScope.ts: -------------------------------------------------------------------------------- 1 | import type { IServiceProvider } from "../di/IServiceProvider.js"; 2 | export interface IServiceScope { 3 | serviceProvider: IServiceProvider; 4 | [Symbol.dispose](): void; 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/git/src/getGitPrefixedTag.ts: -------------------------------------------------------------------------------- 1 | import { defaultTagPrefix } from "./defaultTagPrefix.js"; 2 | 3 | export function getGitPrefixedTag(version: string, prefix = defaultTagPrefix) { 4 | return `${prefix}${version}`; 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/navigation/src/IRouteState.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents the state of a route with its ID and parameters 3 | */ 4 | export interface IRouteState { 5 | id: string; 6 | params: Record; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/react-split-view/src/ISplitViewSash.ts: -------------------------------------------------------------------------------- 1 | import type { ISplitViewSashProps } from "./ISplitViewSashProps.js"; 2 | 3 | export interface ISplitViewSash { 4 | props: ISplitViewSashProps; 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/tree/TreeClassesContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | import type { ITreeClasses } from "./ITreeClasses.js"; 3 | 4 | export const TreeClassesContext = createContext({}); 5 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/tree/TreeDataContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | import type { ITreeData } from "./ITreeData.js"; 4 | 5 | export const TreeDataContext = createContext(null); 6 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config"; 2 | 3 | export default defineConfig({ 4 | test: { 5 | environment: "node", 6 | include: ["**/*.test.ts"], 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /packages/@wroud/di-react/src/tests/testingLibrary.ts: -------------------------------------------------------------------------------- 1 | import { afterEach } from "vitest"; 2 | import { cleanup } from "@testing-library/react"; 3 | import "@testing-library/jest-dom/vitest"; 4 | 5 | afterEach(() => { 6 | cleanup(); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/module/IModule.ts: -------------------------------------------------------------------------------- 1 | import type { IServiceCollection } from "../types/index.js"; 2 | 3 | export interface IModule { 4 | name: string; 5 | configure(serviceCollection: IServiceCollection): Promise | void; 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-analyzer/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./getDependenciesGraph.js"; 2 | export * from "./ServiceCollectionProxy.js"; 3 | export * from "./chart/createChart.js"; 4 | export * from "./IGraph.js"; 5 | export * from "./IChart.js"; 6 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/src/ISupportedPackage.ts: -------------------------------------------------------------------------------- 1 | export interface ISupportedPackage { 2 | name: string; 3 | replace: string; 4 | injectableDecorator?: string; 5 | injectDecorator?: string; 6 | multiInjectDecorator?: string; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/helpers/isServiceProvider.ts: -------------------------------------------------------------------------------- 1 | import { IServiceProvider } from "../di/IServiceProvider.js"; 2 | 3 | export function isServiceProvider(value: unknown): value is IServiceProvider { 4 | return value === IServiceProvider; 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/conventional-commits-changelog/src/IConventionalCommitCoAuthor.ts: -------------------------------------------------------------------------------- 1 | export interface IConventionalCommitCoAuthor { 2 | name: string; 3 | username?: string; 4 | usernameLink?: string; 5 | link?: string; 6 | email?: string; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/di-react/src/ServiceProviderContext.ts: -------------------------------------------------------------------------------- 1 | import type { IServiceProvider } from "@wroud/di"; 2 | import { createContext } from "react"; 3 | 4 | export const ServiceProviderContext = createContext( 5 | null, 6 | ); 7 | -------------------------------------------------------------------------------- /packages/@wroud/di-react/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ServiceProvider.js"; 2 | export * from "./useService.js"; 3 | export * from "./useServiceCreateAsyncScope.js"; 4 | export * from "./useServiceCreateScope.js"; 5 | export * from "./useServices.js"; 6 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/IServiceFactory.ts: -------------------------------------------------------------------------------- 1 | import type { IServiceProvider } from "../di/IServiceProvider.js"; 2 | 3 | export type IServiceFactory< 4 | T, 5 | TArgs extends unknown[] = [provider: IServiceProvider], 6 | > = (...args: TArgs) => T; 7 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/IAsyncServiceScope.ts: -------------------------------------------------------------------------------- 1 | import type { IServiceProvider } from "../di/IServiceProvider.js"; 2 | 3 | export interface IAsyncServiceScope { 4 | serviceProvider: IServiceProvider; 5 | [Symbol.asyncDispose](): Promise; 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/github/src/gitGithubLinks.ts: -------------------------------------------------------------------------------- 1 | export const gitGithubLinks = [ 2 | /[^\w](?#(?\d+)(?))/gi, 3 | /[^\w](?GH-(?\d+)(?))/g, 4 | /[^\w](?(?[^\/\s]+\/[^\/\s]+)#(?\d+)(?))/gi, 5 | ]; 6 | -------------------------------------------------------------------------------- /.yarn/sdks/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript", 3 | "version": "5.8.3-sdk", 4 | "main": "./lib/typescript.js", 5 | "type": "commonjs", 6 | "bin": { 7 | "tsc": "./bin/tsc", 8 | "tsserver": "./bin/tsserver" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/IServiceCollectionElement.ts: -------------------------------------------------------------------------------- 1 | import type { IServiceDescriptor } from "./IServiceDescriptor.js"; 2 | 3 | export interface IServiceCollectionElement { 4 | single: IServiceDescriptor; 5 | all: IServiceDescriptor[]; 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/RequestPath.ts: -------------------------------------------------------------------------------- 1 | import type { IRequestPathNode } from "./IRequestPathNode.js"; 2 | import type { IServiceDescriptor } from "./IServiceDescriptor.js"; 3 | 4 | export type RequestPath = IRequestPathNode | null>; 5 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/viewport/NodeSizeCacheContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | import type { INodeSizeCache } from "./useNodeSizeCache.js"; 4 | 5 | export const NodeSizeCacheContext = createContext(null); 6 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/IEntryDescriptor.ts: -------------------------------------------------------------------------------- 1 | import type { HtmlTagDescriptor } from "vite"; 2 | 3 | export interface IEntryDescriptor { 4 | chunk: string; 5 | entry: string; 6 | main?: IEntryDescriptor; 7 | htmlTags: HtmlTagDescriptor[]; 8 | } 9 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-analyzer/src/chart/Layout.ts: -------------------------------------------------------------------------------- 1 | export const Layout = { 2 | node: { 3 | radius: 5, 4 | }, 5 | link: { 6 | opacity: 0.3, 7 | hoverOpacity: 1, 8 | }, 9 | linkOptional: { 10 | dashArray: "4 2", 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/helpers/isJsEntityName.ts: -------------------------------------------------------------------------------- 1 | export function isJsEntityName(name: string): boolean { 2 | return [ 3 | "Function", 4 | "Object", 5 | "Array", 6 | "String", 7 | "Number", 8 | "Boolean", 9 | ].includes(name); 10 | } 11 | -------------------------------------------------------------------------------- /packages/@wroud/playground-react/src/IDoc.ts: -------------------------------------------------------------------------------- 1 | import type { IDescribe } from "./IDescribe.js"; 2 | 3 | export interface IDoc { 4 | id: string; 5 | name: string; 6 | describe: IDescribe; 7 | component: React.ComponentType; 8 | props?: T; 9 | } 10 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/controls/index.ts: -------------------------------------------------------------------------------- 1 | export { TreeNodeControl } from "./TreeNodeControl.js"; 2 | export { TreeNodeExpand } from "./TreeNodeExpand.js"; 3 | export { TreeNodeIcon } from "./TreeNodeIcon.js"; 4 | export { TreeNodeName } from "./TreeNodeName.js"; 5 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/node/NodeRenderer.tsx: -------------------------------------------------------------------------------- 1 | import { Node } from "./Node.js"; 2 | import type { NodeComponent } from "./NodeComponent.js"; 3 | 4 | export const NodeRenderer: NodeComponent = function NodeRenderer(props) { 5 | return ; 6 | }; 7 | -------------------------------------------------------------------------------- /packages/@wroud/github/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./IGithubCoAuthor.js"; 2 | export * from "./IGithubTrailers.js"; 3 | export * from "./getGithubTrailers.js"; 4 | export * from "./gitGithubLinks.js"; 5 | export * from "./getGithubLink.js"; 6 | export * from "./GithubURL.js"; 7 | -------------------------------------------------------------------------------- /packages/@wroud/playground/src/PlaygroundRoutes.ts: -------------------------------------------------------------------------------- 1 | export const PlaygroundRoutes = { 2 | root: ".", 3 | story: "/story/:story*", 4 | isolated: "/isolated/:story*", 5 | preview: "/preview/:story*", 6 | components: "/components", 7 | assets: "/assets", 8 | } as const; 9 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/cleanUrl.ts: -------------------------------------------------------------------------------- 1 | const postfixRE = /[?#].*$/; 2 | export function cleanUrl(url: T): T { 3 | if (typeof url === "string") { 4 | return url.replace(postfixRE, "") as T; 5 | } 6 | return url; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/isDevServer.ts: -------------------------------------------------------------------------------- 1 | import type { ViteDevServer, PreviewServer } from "vite"; 2 | 3 | export function isDevServer( 4 | server: ViteDevServer | PreviewServer, 5 | ): server is ViteDevServer { 6 | return "pluginContainer" in server; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/implementation-resolvers/value.ts: -------------------------------------------------------------------------------- 1 | import { ValueServiceImplementationResolver } from "./ValueServiceImplementationResolver.js"; 2 | 3 | export function value(implementation: T) { 4 | return new ValueServiceImplementationResolver(implementation); 5 | } 6 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/plugin/virtualStoriesModule.ts: -------------------------------------------------------------------------------- 1 | export function isVirtualStoriesModule(source: string) { 2 | return source.endsWith("?stories"); 3 | } 4 | export function createVirtualStoriesModule(source: string) { 5 | return source + "?stories"; 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/react/components/SSGContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | import type { IndexComponentProps } from "../IndexComponent.js"; 3 | 4 | export const SSGContext = createContext( 5 | undefined, 6 | ); 7 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/IServiceMetadata.ts: -------------------------------------------------------------------------------- 1 | import type { ServiceType } from "./ServiceType.js"; 2 | 3 | export interface IServiceMetadata< 4 | TServices extends ServiceType[] = ServiceType[], 5 | > { 6 | name: string | undefined; 7 | dependencies: TServices; 8 | } 9 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/src/isReexportPackage.ts: -------------------------------------------------------------------------------- 1 | import type { ISupportedPackage } from "./ISupportedPackage.js"; 2 | 3 | export function isReexportPackage( 4 | supportedPackage: ISupportedPackage, 5 | ): boolean { 6 | return supportedPackage.name === supportedPackage.replace; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/github/src/GithubURL.ts: -------------------------------------------------------------------------------- 1 | export const GithubURL = { 2 | issue: (repository: string, issue: number) => 3 | `https://github.com/${repository}/issues/${issue}`, 4 | commit: (repository: string, hash: string) => 5 | `https://github.com/${repository}/commit/${hash}`, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/@wroud/react-split-view/src/ISplitViewSashProps.ts: -------------------------------------------------------------------------------- 1 | export interface ISplitViewSashProps { 2 | onDoubleClick: () => void; 3 | onPointerDown: (event: React.PointerEvent) => void; 4 | style: { 5 | cursor: "grab"; 6 | touchAction: "none"; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/app/vite.env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module "*&page-url" { 4 | const data: string; 5 | export default data; 6 | } 7 | 8 | declare module "*?page-url" { 9 | const data: string; 10 | export default data; 11 | } 12 | -------------------------------------------------------------------------------- /packages/@wroud/playground-react/src/index.ts: -------------------------------------------------------------------------------- 1 | export { Link, Script } from "@wroud/vite-plugin-ssg/react/components"; 2 | export * from "./describe.js"; 3 | export * from "./story.js"; 4 | export * from "./IStory.js"; 5 | export * from "./doc.js"; 6 | export * from "./IDoc.js"; 7 | export * from "./IDescribe.js"; 8 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/data/nav.ts: -------------------------------------------------------------------------------- 1 | import { DefaultTheme } from "vitepress"; 2 | 3 | /* prettier-ignore */ 4 | export const nav: DefaultTheme.NavItem[] = [ 5 | { text: "guide", link: "/guide/", activeMatch: "/guide/" }, 6 | { text: "packages", link: "/packages/overview", activeMatch: "/packages/" }, 7 | ] 8 | -------------------------------------------------------------------------------- /packages/@wroud/di-react/src/useServices.ts: -------------------------------------------------------------------------------- 1 | import type { ServiceType } from "@wroud/di/types"; 2 | import { useServiceIterator } from "./useServiceIterator.js"; 3 | import { all } from "@wroud/di"; 4 | 5 | export function useServices(type: ServiceType): T[] { 6 | return useServiceIterator(all(type)); 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/git/__testfixtures__/fixture.git-log-path.txt: -------------------------------------------------------------------------------- 1 | 1dfaff1 2 | (HEAD -> main, tag: v1.0.5, tag: v1.0.1) 3 | Aleksei Potsetsuev 4 | wrouds@gmail.com 5 | test(git): test commit with something 6 | some long description 7 | 8 | BREAKING CHANGE: Some breaky change 9 | 10 | fix #123 11 | 12 | ===end=== -------------------------------------------------------------------------------- /packages/@wroud/git/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./IGitCommitInfo.js"; 2 | export * from "./IGitTrailer.js"; 3 | export * from "./getGitCommits.js"; 4 | export * from "./getGitLastSemverTag.js"; 5 | export * from "./getGitLastSemverTags.js"; 6 | export * from "./getGitPrefixedTag.js"; 7 | export * from "./IGitLink.js"; 8 | -------------------------------------------------------------------------------- /packages/@wroud/navigation/src/pattern-matching/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./types.js"; 2 | export * from "./TriePatternMatching.js"; 3 | export * from "../IRouteMatcher.js"; 4 | export * from "./TrieNode.js"; 5 | export * from "./matcher.js"; 6 | export * from "./path-utils.js"; 7 | export * from "./parameter-utils.js"; 8 | -------------------------------------------------------------------------------- /packages/@wroud/playground/src/IPlaygroundContext.ts: -------------------------------------------------------------------------------- 1 | import type { INavigation, TriePatternMatching } from "@wroud/navigation"; 2 | import type { IAppContext } from "@wroud/vite-plugin-ssg/app"; 3 | 4 | export interface IPlaygroundContext extends IAppContext { 5 | navigation: INavigation; 6 | } 7 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/Service.ts: -------------------------------------------------------------------------------- 1 | export class Service implements Disposable, AsyncDisposable { 2 | protected dispose(): Promise | void {} 3 | 4 | [Symbol.dispose]() { 5 | return this.dispose(); 6 | } 7 | 8 | async [Symbol.asyncDispose]() { 9 | return await this.dispose(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/di/createService.ts: -------------------------------------------------------------------------------- 1 | export function createService( 2 | name: string, 3 | ): T extends (...args: any) => any 4 | ? new (...args: Parameters) => ReturnType 5 | : T extends abstract new (...args: any) => any 6 | ? T 7 | : new () => T { 8 | return { name } as any; 9 | } 10 | -------------------------------------------------------------------------------- /packages/@wroud/ts-template/src/ES_TARGETS.ts: -------------------------------------------------------------------------------- 1 | export const ES_TARGETS = [ 2 | "esnext", 3 | "es2024", 4 | "es2023", 5 | "es2022", 6 | "es2021", 7 | "es2020", 8 | "es2019", 9 | "es2018", 10 | "es2017", 11 | "es2016", 12 | "es2015", 13 | "es6", 14 | "es5", 15 | "es3", 16 | ] as const; 17 | -------------------------------------------------------------------------------- /packages/@wroud/flow-middleware/src/interfaces/IMiddlewareRequest.ts: -------------------------------------------------------------------------------- 1 | import type { IMiddlewareContainer } from "./IMiddlewareContainer.js"; 2 | 3 | export interface IMiddlewareRequest> 4 | extends IMiddlewareContainer { 5 | execute(error?: any): Promise; 6 | dispose(): void; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/react-split-view/src/ISplitView.ts: -------------------------------------------------------------------------------- 1 | import type { ISplitViewProps } from "./ISplitViewProps.js"; 2 | import type { ISplitViewSashProps } from "./ISplitViewSashProps.js"; 3 | 4 | export interface ISplitView { 5 | viewProps: ISplitViewProps; 6 | sashProps: ISplitViewSashProps; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/di-react/src/useServiceSync.ts: -------------------------------------------------------------------------------- 1 | import { useServiceProvider } from "./useServiceProvider.js"; 2 | import type { SingleServiceType } from "@wroud/di/types"; 3 | 4 | export function useServiceSync(type: SingleServiceType): T { 5 | const provider = useServiceProvider(); 6 | return provider.getService(type); 7 | } 8 | -------------------------------------------------------------------------------- /packages/yarn-plugin-ts-project-linker/README.md: -------------------------------------------------------------------------------- 1 | # yarn-plugin-ts-project-linker 2 | 3 | ## Installation 4 | 5 | ### Yarn 3+ 6 | 7 | ```sh 8 | yarn plugin import https://raw.githubusercontent.com/Wroud/foundation/refs/heads/main/packages/yarn-plugin-ts-project-linker/bundles/%40yarnpkg/plugin-ts-project-linker.js 9 | ``` 10 | -------------------------------------------------------------------------------- /packages/@wroud/conventional-commits-changelog/src/IConventionalCommitMetadata.ts: -------------------------------------------------------------------------------- 1 | import type { IConventionalCommitCoAuthor } from "./IConventionalCommitCoAuthor.js"; 2 | 3 | export interface IConventionalCommitMetadata { 4 | url?: string; 5 | coAuthors?: IConventionalCommitCoAuthor[]; 6 | formatter?: (message: string) => string; 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/conventional-commits-parser/src/IConventionalCommit.ts: -------------------------------------------------------------------------------- 1 | import type { IGitCommitInfo } from "@wroud/git"; 2 | 3 | export interface IConventionalCommit { 4 | commitInfo: IGitCommitInfo; 5 | type: string; 6 | scope?: string; 7 | description: string; 8 | body?: string; 9 | breakingChanges: string[]; 10 | } 11 | -------------------------------------------------------------------------------- /packages/@wroud/di-react/src/useServicesSync.ts: -------------------------------------------------------------------------------- 1 | import { useServiceProvider } from "./useServiceProvider.js"; 2 | import type { SingleServiceType } from "@wroud/di/types"; 3 | 4 | export function useServicesSync(type: SingleServiceType): T[] { 5 | const provider = useServiceProvider(); 6 | return provider.getServices(type); 7 | } 8 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/__testfixtures__/fixture3.input.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * comment 3 | */ 4 | import { injectable } from "inversify"; 5 | 6 | @injectable() 7 | export class NotificationService { 8 | constructor( 9 | private readonly a: A, 10 | private readonly b: B, 11 | private readonly c: C, 12 | ) {} 13 | } 14 | -------------------------------------------------------------------------------- /packages/@wroud/conventional-commits-changelog/src/conventionalChangelogMarkers.ts: -------------------------------------------------------------------------------- 1 | export const conventionalChangelogMarkers = { 2 | header: "", 3 | version: (version: string) => ``, 4 | changelog: "", 5 | isVersionMarker: (line: string) => line.startsWith("", 6 | "## 1.0.0 (2000-02-23)", 7 | "", 8 | ] 9 | `; 10 | 11 | exports[`createConventionalChangelogHeader > with compare URL 1`] = ` 12 | [ 13 | "", 14 | "## 1.0.0 (2000-02-23)", 15 | "", 16 | "[Compare changes](https://example.com)", 17 | "", 18 | ] 19 | `; 20 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/ServiceType.ts: -------------------------------------------------------------------------------- 1 | import type { IResolverServiceType } from "./IResolverServiceType.js"; 2 | import type { SingleServiceType } from "./SingleServiceType.js"; 3 | 4 | export type ServiceType = 5 | | SingleServiceType 6 | | IResolverServiceType; 7 | 8 | export type GetServiceTypeImplementation< 9 | T extends ServiceType | ServiceType[], 10 | > = 11 | T extends ServiceType 12 | ? U 13 | : { 14 | [K in keyof T]: T[K] extends ServiceType ? V : never; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/@wroud/api-logger/src/ILogger.ts: -------------------------------------------------------------------------------- 1 | export interface ILogger { 2 | /** 3 | * Logs a message with the "info" level. 4 | * @param {any[]} messages - The messages to log. 5 | */ 6 | info(...messages: any[]): void; 7 | 8 | /** 9 | * Logs a message with the "warn" level. 10 | * @param {any[]} messages - The messages to log. 11 | */ 12 | warn(...messages: any[]): void; 13 | 14 | /** 15 | * Logs a message with the "error" level. 16 | * @param {any[]} messages - The messages to log. 17 | */ 18 | error(...messages: any[]): void; 19 | } 20 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-benchmark/tsconfig.modern.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@wroud/tsconfig/tsconfig.json", 3 | "compilerOptions": { 4 | "tsBuildInfoFile": "./lib/modern/.tsbuildinfo", 5 | "rootDir": "src", 6 | "rootDirs": [ 7 | "src" 8 | ], 9 | "outDir": "lib/modern", 10 | "incremental": true, 11 | "composite": true 12 | }, 13 | "include": [ 14 | "src/@wroud", 15 | "src/brandi", 16 | "src/reatom", 17 | "src/needle-di" 18 | ], 19 | "references": [ 20 | { 21 | "path": "../di" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/__testfixtures__/multipleFiles/fixture2.input.ts: -------------------------------------------------------------------------------- 1 | import type { App } from "@cloudbeaver/core-di"; 2 | import { FormState } from "@cloudbeaver/core-ui"; 3 | 4 | import type { 5 | IUserProfileFormState, 6 | UserProfileFormService, 7 | } from "./UserProfileFormService"; 8 | 9 | export class UserProfileFormState extends FormState { 10 | constructor( 11 | app: App, 12 | service: UserProfileFormService, 13 | config: IUserProfileFormState, 14 | ) { 15 | super(app, service, config); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/__testfixtures__/multipleFiles/fixture2.output.ts: -------------------------------------------------------------------------------- 1 | import type { App } from "@cloudbeaver/core-di"; 2 | import { FormState } from "@cloudbeaver/core-ui"; 3 | 4 | import type { 5 | IUserProfileFormState, 6 | UserProfileFormService, 7 | } from "./UserProfileFormService"; 8 | 9 | export class UserProfileFormState extends FormState { 10 | constructor( 11 | app: App, 12 | service: UserProfileFormService, 13 | config: IUserProfileFormState, 14 | ) { 15 | super(app, service, config); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/@wroud/tests-runner/bin/tests-runner.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import v8 from "node:v8"; 4 | import path from "node:path"; 5 | import { startVitest, parseCLI } from "vitest/node"; 6 | 7 | v8.setFlagsFromString("--expose-gc"); 8 | const { filter, options } = parseCLI(["vitest", ...process.argv.slice(2)]); 9 | const vitest = await startVitest("test", filter, { 10 | config: path.resolve(import.meta.dirname, "../vitest.config.ts"), 11 | setupFiles: [import.meta.resolve("../vitest.setup.ts")], 12 | ...options, 13 | }); 14 | 15 | await vitest?.close(); 16 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/stripBase.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | import { stripBase } from "./stripBase.js"; 3 | 4 | describe("stripBase", () => { 5 | it("returns root slash when path equals base", () => { 6 | expect(stripBase("/base", "/base")).toBe("/"); 7 | }); 8 | 9 | it("removes base prefix", () => { 10 | expect(stripBase("/base/foo", "/base")).toBe("/foo"); 11 | }); 12 | 13 | it("returns original path when no base", () => { 14 | expect(stripBase("/foo", "/base")).toBe("/foo"); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/modules/mainQuery.ts: -------------------------------------------------------------------------------- 1 | import { addQueryParam } from "../utils/queryParam.js"; 2 | import { trailingSeparatorRE } from "../utils/trailingSeparatorRE.js"; 3 | 4 | export const ssgMainRE = /(\?|&)ssg-main(?:&|$)/; 5 | export function removeMainQuery(url: string): string { 6 | return url.replace(ssgMainRE, "$1").replace(trailingSeparatorRE, ""); 7 | } 8 | 9 | export function isMainId(id: string) { 10 | return ssgMainRE.test(id); 11 | } 12 | 13 | export function addMainQuery(id: string) { 14 | return addQueryParam(id, "ssg-main"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/getPathsToLookup.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | import { getPathsToLookup } from "./getPathsToLookup.js"; 3 | 4 | describe("getPathsToLookup", () => { 5 | it("returns all paths to lookup from deepest to root", () => { 6 | const result = [...getPathsToLookup("foo/bar/baz")]; 7 | expect(result).toEqual([ 8 | "foo/bar/baz", 9 | "foo/bar/baz/index", 10 | "foo/bar", 11 | "foo/bar/index", 12 | "foo", 13 | "foo/index", 14 | "/index", 15 | ]); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/@wroud/tests-runner/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@wroud/tests-runner", 3 | "private": true, 4 | "type": "module", 5 | "packageManager": "yarn@4.9.1", 6 | "bin": { 7 | "benchmark": "./bin/benchmark.mjs", 8 | "tests-runner": "./bin/tests-runner.mjs" 9 | }, 10 | "devDependencies": { 11 | "@tsconfig/node20": "^20", 12 | "@tsconfig/strictest": "^2", 13 | "@types/node": "^22", 14 | "@vitest/coverage-v8": "^3", 15 | "@wroud/tsconfig": "workspace:*", 16 | "jest-extended": "^5", 17 | "vite": "^6", 18 | "vitest": "^3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/app/Story.tsx: -------------------------------------------------------------------------------- 1 | import { useStory } from "@wroud/playground-react/views"; 2 | import { Template } from "./pages/Template.js"; 3 | 4 | interface Props { 5 | activeStoryId: string | null; 6 | preview?: boolean; 7 | } 8 | 9 | export function Story({ activeStoryId, preview }: Props) { 10 | const story = useStory(activeStoryId); 11 | 12 | let Component = story?.component ?? Template; 13 | 14 | if (preview && typeof story?.options.preview === "function") { 15 | Component = story.options.preview; 16 | } 17 | 18 | return ; 19 | } 20 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/modules/isSsgPageUrlId.ts: -------------------------------------------------------------------------------- 1 | import { addQueryParam } from "../utils/queryParam.js"; 2 | import { trailingSeparatorRE } from "../utils/trailingSeparatorRE.js"; 3 | 4 | const ssgPageIdRe = /(\?|&)page-url(?:&|$)/; 5 | export function removeSsgPageUrlId(url: string): string { 6 | return url.replace(ssgPageIdRe, "$1").replace(trailingSeparatorRE, ""); 7 | } 8 | 9 | export function isSsgPageUrlId(id: string) { 10 | return ssgPageIdRe.test(id); 11 | } 12 | 13 | export function createSsgPageUrlId(url: string) { 14 | return addQueryParam(url, "page-url"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/cleanUrl.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | import { cleanUrl } from "./cleanUrl.js"; 3 | 4 | describe("cleanUrl", () => { 5 | it("removes query strings and fragments", () => { 6 | expect(cleanUrl("/foo?bar#baz")).toBe("/foo"); 7 | expect(cleanUrl("/foo?bar=baz")).toBe("/foo"); 8 | expect(cleanUrl("/foo#section")).toBe("/foo"); 9 | }); 10 | 11 | it("returns null and undefined unchanged", () => { 12 | expect(cleanUrl(null)).toBeNull(); 13 | expect(cleanUrl(undefined)).toBeUndefined(); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import Theme from "vitepress/theme"; 2 | import TwoslashFloatingVue from "@shikijs/vitepress-twoslash/client"; 3 | import { enhanceAppWithTabs } from "vitepress-plugin-tabs/client"; 4 | import "@shikijs/vitepress-twoslash/style.css"; 5 | import type { EnhanceAppContext } from "vitepress"; 6 | import "./custom.css"; 7 | import "./playground-links.css"; 8 | import "uno.css"; 9 | 10 | export default { 11 | extends: Theme, 12 | enhanceApp({ app }: EnhanceAppContext) { 13 | app.use(TwoslashFloatingVue); 14 | enhanceAppWithTabs(app); 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/theme/playground-links.css: -------------------------------------------------------------------------------- 1 | .vp-doc a[href^="https://stackblitz.com"] 2 | { 3 | text-decoration: none; 4 | &:before { 5 | content: "▶"; 6 | width: 20px; 7 | height: 20px; 8 | display: inline-block; 9 | border-radius: 10px; 10 | vertical-align: middle; 11 | position: relative; 12 | top: -2px; 13 | border: 2px solid; 14 | margin-right: 8px; 15 | margin-left: 4px; 16 | line-height: 15px; 17 | padding-left: 4.5px; 18 | font-size: 11px; 19 | font-family: system-ui, BlinkMacSystemFont, sans-serif; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/@wroud/playground-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@wroud/tsconfig/tsconfig.react.json", 3 | "compilerOptions": { 4 | "tsBuildInfoFile": "./lib/.tsbuildinfo", 5 | "rootDir": "src", 6 | "rootDirs": [ 7 | "src" 8 | ], 9 | "outDir": "lib", 10 | "incremental": true, 11 | "composite": true 12 | }, 13 | "include": [ 14 | "src" 15 | ], 16 | "references": [ 17 | { 18 | "path": "../navigation" 19 | }, 20 | { 21 | "path": "../playground" 22 | }, 23 | { 24 | "path": "../vite-plugin-ssg" 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/yarn-plugin-ts-project-linker/src/index.mts: -------------------------------------------------------------------------------- 1 | import { Hooks, Plugin } from "@yarnpkg/core"; 2 | import { link } from "@wroud/ts-project-linker"; 3 | import { npath } from "@yarnpkg/fslib"; 4 | 5 | const plugin: Plugin = { 6 | hooks: { 7 | afterAllInstalled: async (project, options) => { 8 | await link( 9 | { 10 | immutable: options.immutable, 11 | }, 12 | ...project.workspaces.map((workspace) => 13 | npath.fromPortablePath(workspace.cwd), 14 | ), 15 | ); 16 | }, 17 | }, 18 | }; 19 | 20 | export default plugin; 21 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/src/isInjectableDecorator.ts: -------------------------------------------------------------------------------- 1 | import { Decorator } from "jscodeshift"; 2 | import type { ISupportedPackage } from "./ISupportedPackage.js"; 3 | 4 | export function isInjectableDecorator( 5 | packages: ISupportedPackage[], 6 | decorator: Decorator, 7 | ): decorator is Decorator { 8 | if ( 9 | decorator.expression.type !== "CallExpression" || 10 | decorator.expression.callee.type !== "Identifier" 11 | ) { 12 | return false; 13 | } 14 | const name = decorator.expression.callee.name; 15 | return packages.some((p) => p.injectableDecorator === name); 16 | } 17 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/di/validation/validateAsyncImplementation.ts: -------------------------------------------------------------------------------- 1 | import { Debug } from "../../debug.js"; 2 | import { isAsyncServiceImplementationResolver } from "../../implementation-resolvers/isAsyncServiceImplementation.js"; 3 | import type { IServiceCollection } from "../../types/index.js"; 4 | 5 | export function validateAsyncImplementation( 6 | collection: IServiceCollection, 7 | ): void { 8 | for (const descriptor of collection) { 9 | if (isAsyncServiceImplementationResolver(descriptor.resolver)) { 10 | console.warn(Debug.warnings.asyncValidation(descriptor)); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/extras/implementation-resolvers/conditional.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | IServiceImplementationResolver, 3 | ServiceType, 4 | } from "../../types/index.js"; 5 | import { 6 | ConditionalServiceImplementationResolver, 7 | type IConditionFactory, 8 | } from "./ConditionalServiceImplementationResolver.js"; 9 | 10 | export function conditional[]>( 11 | factory: IConditionFactory, 12 | ...dependencies: TArgs 13 | ): IServiceImplementationResolver { 14 | return new ConditionalServiceImplementationResolver(factory, dependencies); 15 | } 16 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/react/components/Link.tsx: -------------------------------------------------------------------------------- 1 | import { use, type LinkHTMLAttributes } from "react"; 2 | import { pathUrlWithBase } from "../pathUrlWithBase.js"; 3 | import { SSGContext } from "./SSGContext.js"; 4 | 5 | export interface LinkProps extends LinkHTMLAttributes {} 6 | 7 | export const Link: React.FC = function Link({ href, ...rest }) { 8 | const { context } = use(SSGContext)!; 9 | 10 | return ( 11 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/src/isMultipleInjectDecorator.ts: -------------------------------------------------------------------------------- 1 | import { Decorator } from "jscodeshift"; 2 | import type { ISupportedPackage } from "./ISupportedPackage.js"; 3 | 4 | export function isMultipleInjectDecorator( 5 | packages: ISupportedPackage[], 6 | decorator: Decorator, 7 | ): decorator is Decorator { 8 | if ( 9 | decorator.expression.type !== "CallExpression" || 10 | decorator.expression.callee.type !== "Identifier" 11 | ) { 12 | return false; 13 | } 14 | const name = decorator.expression.callee.name; 15 | return packages.some((p) => p.multiInjectDecorator === name); 16 | } 17 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/modules/isSsgServerEntryId.ts: -------------------------------------------------------------------------------- 1 | import { addQueryParam } from "../utils/queryParam.js"; 2 | import { trailingSeparatorRE } from "../utils/trailingSeparatorRE.js"; 3 | 4 | const ssgRE = /(\?|&)ssr-server-entry(?:&|$)/; 5 | export function removeSsgServerEntryQuery(url: string): string { 6 | return url.replace(ssgRE, "$1").replace(trailingSeparatorRE, ""); 7 | } 8 | 9 | export function isSsgServerEntryId(id: string) { 10 | return ssgRE.test(id); 11 | } 12 | 13 | export function createSsgServerEntryId(url: string): string { 14 | return addQueryParam(url, "ssr-server-entry"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/modules/ssgEntryQuery.ts: -------------------------------------------------------------------------------- 1 | import { addQueryParam } from "../utils/queryParam.js"; 2 | import { trailingSeparatorRE } from "../utils/trailingSeparatorRE.js"; 3 | 4 | export const ssgEntryQueryRE = /(\?|&)ssg-entry(?:&|$)/; 5 | export function removeSsgEntryQuery(url: string): string { 6 | return url.replace(ssgEntryQueryRE, "$1").replace(trailingSeparatorRE, ""); 7 | } 8 | 9 | export function isSsgEntryQuery(id: string) { 10 | return ssgEntryQueryRE.test(id); 11 | } 12 | 13 | export function createSsgEntryQuery(url: string) { 14 | return addQueryParam(url, "ssg-entry"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/@wroud/playground-react/src/hooks/useDoc.ts: -------------------------------------------------------------------------------- 1 | import { useCallback, useSyncExternalStore } from "react"; 2 | import type { IDoc } from "../IDoc.js"; 3 | import { fetchDocById, subscribeToRegistryChanges } from "../registry.js"; 4 | 5 | export function useDoc(id: string | null): IDoc | null { 6 | const getCallback = useCallback(() => { 7 | if (!id) { 8 | return null; 9 | } 10 | 11 | return fetchDocById(id) ?? null; 12 | }, [id]); 13 | 14 | const doc = useSyncExternalStore( 15 | subscribeToRegistryChanges, 16 | getCallback, 17 | getCallback, 18 | ); 19 | 20 | return doc; 21 | } 22 | -------------------------------------------------------------------------------- /packages/@wroud/di-react/src/ServiceProvider.tsx: -------------------------------------------------------------------------------- 1 | import type { IServiceProvider } from "@wroud/di"; 2 | import { memo } from "react"; 3 | import { ServiceProviderContext } from "./ServiceProviderContext.js"; 4 | 5 | export interface IServiceProviderProps extends React.PropsWithChildren { 6 | provider: IServiceProvider; 7 | } 8 | 9 | export const ServiceProvider = memo( 10 | function ServiceProvider({ provider, children }) { 11 | return ( 12 | 13 | {children} 14 | 15 | ); 16 | }, 17 | ); 18 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/service-type-resolvers/all.ts: -------------------------------------------------------------------------------- 1 | import type { IResolverServiceType, ServiceType } from "../types/index.js"; 2 | import { ListServiceTypeResolver } from "./ListServiceTypeResolver.js"; 3 | 4 | const cache = new WeakMap< 5 | ServiceType, 6 | IResolverServiceType 7 | >(); 8 | 9 | export function all(service: ServiceType): IResolverServiceType { 10 | let cached = cache.get(service) as IResolverServiceType; 11 | if (!cached) { 12 | cached = new ListServiceTypeResolver(service); 13 | cache.set(service, cached); 14 | } 15 | return cached; 16 | } 17 | -------------------------------------------------------------------------------- /packages/@wroud/playground-react/src/hooks/useNode.ts: -------------------------------------------------------------------------------- 1 | import { useCallback, useSyncExternalStore } from "react"; 2 | import { 3 | getRegistryNode, 4 | subscribeToRegistryChanges, 5 | type INode, 6 | } from "../registry.js"; 7 | 8 | export function useNode(id: string | null): INode | null { 9 | const getCallback = useCallback(() => { 10 | if (!id) { 11 | return null; 12 | } 13 | 14 | return getRegistryNode(id) ?? null; 15 | }, [id]); 16 | 17 | const node = useSyncExternalStore( 18 | subscribeToRegistryChanges, 19 | getCallback, 20 | getCallback, 21 | ); 22 | 23 | return node; 24 | } 25 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/tree/ITreeData.ts: -------------------------------------------------------------------------------- 1 | import type { INode } from "../node/INode.js"; 2 | import type { INodeState } from "../node/INodeState.js"; 3 | 4 | export interface ITreeData { 5 | rootId: string; 6 | 7 | getNode(id: string): INode; 8 | getParent?(id: string): string | null; 9 | getChildren: (node: string) => string[]; 10 | getState(id: string): Readonly; 11 | 12 | updateStateAll(state: Partial): void; 13 | updateState(id: string, state: Partial): void; 14 | 15 | update?(): Promise; 16 | load?(nodeId: string, manual: boolean): Promise; 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .yarn/* 2 | !.yarn/patches 3 | !.yarn/plugins 4 | !.yarn/releases 5 | !.yarn/sdks 6 | !.yarn/versions 7 | 8 | # Swap the comments on the following lines if you wish to use zero-installs 9 | # In that case, don't forget to run `yarn config set enableGlobalCache false`! 10 | # Documentation here: https://yarnpkg.com/features/caching#zero-installs 11 | 12 | #!.yarn/cache 13 | .pnp.* 14 | 15 | # coverage 16 | coverage 17 | 18 | # build artifacts 19 | packages/**/dist 20 | packages/**/lib 21 | 22 | # macOS 23 | .DS_Store 24 | 25 | # node_modules 26 | node_modules 27 | 28 | # LLM index files 29 | llms.txt 30 | llms-full.txt 31 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/service-type-resolvers/single.ts: -------------------------------------------------------------------------------- 1 | import type { ServiceType, IResolverServiceType } from "../types/index.js"; 2 | import { SingleServiceTypeResolver } from "./SingleServiceTypeResolver.js"; 3 | 4 | const cache = new WeakMap< 5 | ServiceType, 6 | IResolverServiceType 7 | >(); 8 | 9 | export function single(service: ServiceType): IResolverServiceType { 10 | let cached = cache.get(service) as IResolverServiceType; 11 | if (!cached) { 12 | cached = new SingleServiceTypeResolver(service); 13 | cache.set(service, cached); 14 | } 15 | return cached; 16 | } 17 | -------------------------------------------------------------------------------- /packages/@wroud/navigation/src/IRoute.ts: -------------------------------------------------------------------------------- 1 | import type { IRouteState } from "./IRouteState.js"; 2 | 3 | export type RouteActivationFn = ( 4 | toRoute: IRouteState, 5 | fromRoute: IRouteState | null 6 | ) => boolean | Promise; 7 | 8 | export type RouteDeActivationFn = ( 9 | toRoute: IRouteState | null, 10 | fromRoute: IRouteState | null 11 | ) => boolean | Promise; 12 | 13 | export interface IRoute { 14 | id: string; 15 | parents: string[]; 16 | canActivate?: RouteActivationFn; 17 | canDeactivate?: RouteDeActivationFn; 18 | } 19 | 20 | export interface IRouteOptions extends Omit {} 21 | -------------------------------------------------------------------------------- /.github/workflows/push-main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | concurrency: 8 | group: ci-main 9 | cancel-in-progress: false 10 | 11 | jobs: 12 | build: 13 | uses: ./.github/workflows/build.yml 14 | secrets: inherit 15 | 16 | release: 17 | needs: build 18 | uses: ./.github/workflows/release.yml 19 | secrets: inherit 20 | with: 21 | build-run-id: ${{ needs.build.outputs.run-id }} 22 | 23 | docs: 24 | needs: build 25 | uses: ./.github/workflows/build-docs.yml 26 | secrets: inherit 27 | with: 28 | build-run-id: ${{ needs.build.outputs.run-id }} 29 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/modules/isSsgComponentId.ts: -------------------------------------------------------------------------------- 1 | import { addQueryParam } from "../utils/queryParam.js"; 2 | import { trailingSeparatorRE } from "../utils/trailingSeparatorRE.js"; 3 | 4 | const ssgComponentIdRe = /(\?|&)ssg-component(?:&|$)/; 5 | export function removeSsgComponentQuery(url: string): string { 6 | return url.replace(ssgComponentIdRe, "$1").replace(trailingSeparatorRE, ""); 7 | } 8 | 9 | export function isSsgComponentId(id: string) { 10 | return ssgComponentIdRe.test(id); 11 | } 12 | 13 | export function createSsgComponentId(url: string): string { 14 | return addQueryParam(url, "ssg-component"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/changePathExt.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | import { changePathExt } from "./changePathExt.js"; 3 | 4 | describe("changePathExt", () => { 5 | it("changes extension and preserves query", () => { 6 | expect(changePathExt("/foo/bar.txt", ".js")).toBe("/foo/bar.js"); 7 | expect(changePathExt("/foo/bar.txt?raw", ".js")).toBe("/foo/bar.js?raw"); 8 | }); 9 | 10 | it("adds extension when none exists", () => { 11 | expect(changePathExt("/foo/bar", ".js")).toBe("/foo/bar.js"); 12 | expect(changePathExt(".env", ".js")).toBe(".env.js"); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/isGitLfsPlaceholder.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if content appears to be a Git LFS pointer file. 3 | * Git LFS pointer files start with "version https://git-lfs.github.com/spec" 4 | * and should not be inlined as they are placeholders. 5 | * 6 | * @param content - The file content to check 7 | * @returns true if the content appears to be a Git LFS pointer 8 | */ 9 | export function isGitLfsPlaceholder(content: string | Buffer): boolean { 10 | const text = typeof content === "string" ? content : content.toString("utf8"); 11 | return text.startsWith("version https://git-lfs.github.com/spec"); 12 | } 13 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/removeNoInlineQuery.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from "vitest"; 2 | import { removeNoInlineQuery, isNoInlineId } from "./removeNoInlineQuery.js"; 3 | 4 | describe("removeNoInlineQuery", () => { 5 | it("removes ?no-inline query", () => { 6 | expect(removeNoInlineQuery("/foo.js?no-inline")).toBe("/foo.js"); 7 | expect(removeNoInlineQuery("/foo.js?no-inline&v=1")).toBe("/foo.js?v=1"); 8 | }); 9 | 10 | it("detects no-inline id", () => { 11 | expect(isNoInlineId("/foo.js?no-inline")).toBe(true); 12 | expect(isNoInlineId("/foo.js?v=1")).toBe(false); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/docs/.vitepress/tools/getGAHeaders.ts: -------------------------------------------------------------------------------- 1 | import { HeadConfig } from "vitepress"; 2 | 3 | export function getGAHeaders(): HeadConfig[] { 4 | if (process.env.NODE_ENV !== "production") { 5 | return []; 6 | } 7 | 8 | return [ 9 | [ 10 | "script", 11 | { 12 | async: "", 13 | src: "https://www.googletagmanager.com/gtag/js?id=G-8F954Z5B1Z", 14 | }, 15 | ], 16 | [ 17 | "script", 18 | {}, 19 | "window.dataLayer = window.dataLayer || [];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js', new Date());\ngtag('config', 'G-8F954Z5B1Z');", 20 | ], 21 | ]; 22 | } 23 | -------------------------------------------------------------------------------- /packages/docs/src/packages/react-tree/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # React Tree 6 | 7 | `@wroud/react-tree` is a virtualized tree component for React. It focuses on performance and customization so you can efficiently render large hierarchies. 8 | 9 | ## Key Features 10 | 11 | - **Virtualization** for rendering only the visible portion of large trees. 12 | - **Node Selection** built in through the `useTree` hook. 13 | - **Custom Renderers** to override node controls or content. 14 | - **Async Loading** support for fetching children on demand. 15 | - **CSS Customization** via class maps and optional default styles. 16 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-analyzer/src/loadImplementation.ts: -------------------------------------------------------------------------------- 1 | import { resolveGeneratorAsync } from "@wroud/di/helpers/resolveGeneratorAsync.js"; 2 | import type { IServiceDescriptor } from "@wroud/di/types"; 3 | 4 | export async function getDeps(descriptor: IServiceDescriptor) { 5 | const resolved = await resolveGeneratorAsync( 6 | descriptor.resolver.resolve( 7 | function* gen(dep, reqBy, mode) { 8 | return null as any; 9 | }, 10 | descriptor, 11 | null, 12 | { next: null, value: null }, 13 | "async", 14 | {}, 15 | ), 16 | ); 17 | 18 | return resolved.dependencies; 19 | } 20 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/__testfixtures__/multipleFiles/fixture4.module.output.ts: -------------------------------------------------------------------------------- 1 | import { ModuleRegistry } from "@wroud/di"; 2 | import { AuthConfigurationParametersResource } from "./multipleFiles/fixture4"; 3 | import { NotificationService as NotificationService1 } from "./multipleFiles/fixture3"; 4 | import { NotificationService } from "./multipleFiles/fixture1"; 5 | 6 | ModuleRegistry.add({ 7 | name: "di-tools-codemod", 8 | 9 | configure: serviceCollection => { 10 | serviceCollection.addSingleton(NotificationService).addSingleton(AuthConfigurationParametersResource).addSingleton(NotificationService1); 11 | } 12 | }); -------------------------------------------------------------------------------- /packages/@wroud/tests-runner/bin/benchmark.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import v8 from "node:v8"; 4 | import path from "node:path"; 5 | import { startVitest, parseCLI } from "vitest/node"; 6 | 7 | v8.setFlagsFromString("--expose-gc"); 8 | process.env["NODE_ENV"] = "production"; 9 | const { filter, options } = parseCLI(["vitest", ...process.argv.slice(2)]); 10 | const vitest = await startVitest("benchmark", filter, { 11 | config: path.resolve(import.meta.dirname, "../vitest.config.ts"), 12 | setupFiles: [import.meta.resolve("../vitest.setup.ts")], 13 | ...options, 14 | mode: "production", 15 | }); 16 | 17 | await vitest?.close(); 18 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/splitFileAndPostfix.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Splits a file path into the file part and any postfix query parameters. 3 | * This mimics Vite's behavior for handling asset URLs with query parameters. 4 | * 5 | * @param file - The file path potentially with query parameters 6 | * @returns A tuple of [file, postfix] where postfix includes the '?' if present 7 | */ 8 | export function splitFileAndPostfix(file: string): [string, string] { 9 | const queryIndex = file.indexOf("?"); 10 | if (queryIndex >= 0) { 11 | return [file.slice(0, queryIndex), file.slice(queryIndex)]; 12 | } 13 | return [file, ""]; 14 | } 15 | -------------------------------------------------------------------------------- /packages/@wroud/playground-react/src/hooks/useStory.ts: -------------------------------------------------------------------------------- 1 | import { useCallback, useSyncExternalStore } from "react"; 2 | import type { IStory } from "../IStory.js"; 3 | import { fetchStoryById, subscribeToRegistryChanges } from "../registry.js"; 4 | 5 | export function useStory(id: string | null): IStory | null { 6 | const getStoryCallback = useCallback(() => { 7 | if (!id) { 8 | return null; 9 | } 10 | 11 | return fetchStoryById(id) ?? null; 12 | }, [id]); 13 | 14 | const story = useSyncExternalStore( 15 | subscribeToRegistryChanges, 16 | getStoryCallback, 17 | getStoryCallback, 18 | ); 19 | 20 | return story; 21 | } 22 | -------------------------------------------------------------------------------- /packages/@wroud/ts-template/src/templates/project/getTsConfigTemplate.ts: -------------------------------------------------------------------------------- 1 | interface IGetTsConfigTemplate { 2 | parentConfig: string; 3 | target?: string; 4 | } 5 | export const getTsConfigTemplate = ({ 6 | parentConfig, 7 | target, 8 | }: IGetTsConfigTemplate) => `{ 9 | "extends": "${parentConfig}", 10 | "compilerOptions": { 11 | "tsBuildInfoFile": "./lib/.tsbuildinfo", 12 | "rootDir": "src", 13 | "rootDirs": [ 14 | "src" 15 | ], 16 | "outDir": "lib",${target ? `\n "target": "${target}",` : ""} 17 | "incremental": true, 18 | "composite": true 19 | }, 20 | "include": [ 21 | "src" 22 | ] 23 | } 24 | `; 25 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/modules/isSsgClientEntryId.ts: -------------------------------------------------------------------------------- 1 | import { addQueryParam } from "../utils/queryParam.js"; 2 | import { trailingSeparatorRE } from "../utils/trailingSeparatorRE.js"; 3 | 4 | const ssgClientEntryIdRe = /(\?|&)ssg-client-entry(?:&|$)/; 5 | export function removeSsgClientEntryQuery(url: string): string { 6 | return url.replace(ssgClientEntryIdRe, "$1").replace(trailingSeparatorRE, ""); 7 | } 8 | 9 | export function isSsgClientEntryId(id: string) { 10 | return ssgClientEntryIdRe.test(id); 11 | } 12 | 13 | export function createSsgClientEntryId(url: string): string { 14 | return addQueryParam(url, "ssg-client-entry"); 15 | } 16 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-ssg/src/utils/changePathExt.ts: -------------------------------------------------------------------------------- 1 | export function changePathExt(path: string, ext: string) { 2 | const [pathPart, queryPart] = path.split("?") as [string, string | undefined]; 3 | const queryString = queryPart ? `?${queryPart}` : ""; 4 | const lastDotIndex = pathPart.lastIndexOf("."); 5 | 6 | // If no dot found or dot is at the beginning (like in .env), treat as no extension 7 | if (lastDotIndex <= 0) { 8 | return pathPart + ext + queryString; 9 | } 10 | 11 | // Remove existing extension and add new one 12 | const basename = pathPart.substring(0, lastDotIndex); 13 | return basename + ext + queryString; 14 | } 15 | -------------------------------------------------------------------------------- /packages/@wroud/git/src/validateGitEnvironment.ts: -------------------------------------------------------------------------------- 1 | import { execa } from "execa"; 2 | 3 | /** 4 | * Validates that Git is installed and the current directory is a Git repository. 5 | */ 6 | export async function validateGitEnvironment() { 7 | try { 8 | // Check if Git is installed 9 | await execa`git --version`; 10 | } catch { 11 | throw new Error("Git is not installed or not found in PATH."); 12 | } 13 | 14 | try { 15 | // Check if the current directory is a Git repository 16 | await execa`git rev-parse --is-inside-work-tree`; 17 | } catch { 18 | throw new Error("The current directory is not a Git repository."); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/@wroud/api-logger/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # Changelog 3 | 4 | All notable changes to this project will be documented in this file. 5 | 6 | 7 | ## 0.1.1 (2025-02-07) 8 | 9 | [Compare changes](https://github.com/Wroud/foundation/compare/api-logger-v0.1.0...api-logger-v0.1.1) 10 | 11 | 12 | ### 🩹 Fixes 13 | 14 | - bump dependencies version ([91a7990](https://github.com/Wroud/foundation/commit/91a7990)) 15 | 16 | 17 | ## 0.1.0 (2024-11-26) 18 | 19 | 20 | ### ✨ Features 21 | 22 | - base implementation ([74bb7e2](https://github.com/Wroud/foundation/commit/74bb7e2)) 23 | 24 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/di/createService.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, it, describe } from "vitest"; 2 | import { createService } from "./createService.js"; 3 | 4 | describe("createService", () => { 5 | it("has name", () => { 6 | expect(createService("name")).toHaveProperty("name", "name"); 7 | }); 8 | 9 | it("new call throws error", () => { 10 | const service = createService("name"); 11 | expect(() => new service()).toThrowError("service is not a constructor"); 12 | }); 13 | 14 | it("call throws error", () => { 15 | const service = createService("name"); 16 | expect(() => (service as any)()).toThrowError("is not a function"); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/app/Content.tsx: -------------------------------------------------------------------------------- 1 | import { NodeContent } from "./NodeContent.js"; 2 | import { IframeView, useNode } from "@wroud/playground-react/views"; 3 | 4 | interface Props { 5 | activeNodeId: string | null; 6 | } 7 | 8 | export function Content({ activeNodeId }: Props) { 9 | const node = useNode(activeNodeId); 10 | 11 | return ( 12 |
13 | {!node || node.type === "doc" ? ( 14 | 15 | ) : ( 16 | 17 | )} 18 |
19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /packages/@wroud/conventional-commits-bump/src/getConventionalCommitsBump.ts: -------------------------------------------------------------------------------- 1 | import type { IConventionalCommit } from "@wroud/conventional-commits-parser"; 2 | 3 | export function getConventionalCommitsBump( 4 | commits: IConventionalCommit[], 5 | ): "major" | "minor" | "patch" | null { 6 | let bump: "minor" | "patch" | null = null; 7 | 8 | for (const commit of commits) { 9 | if (commit.breakingChanges.length > 0) { 10 | return "major"; 11 | } 12 | 13 | if (commit.type === "feat") { 14 | bump = "minor"; 15 | } else if (commit.type === "fix" && bump !== "minor") { 16 | bump = "patch"; 17 | } 18 | } 19 | 20 | return bump; 21 | } 22 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-codemod/src/isConstructorInjectDecorator.ts: -------------------------------------------------------------------------------- 1 | import { Decorator } from "jscodeshift"; 2 | import type { ISupportedPackage } from "./ISupportedPackage.js"; 3 | 4 | export function isConstructorInjectDecorator( 5 | packages: ISupportedPackage[], 6 | decorator: Decorator, 7 | ): decorator is Decorator { 8 | if ( 9 | decorator.expression.type !== "CallExpression" || 10 | decorator.expression.callee.type !== "Identifier" 11 | ) { 12 | return false; 13 | } 14 | const name = decorator.expression.callee.name; 15 | 16 | return packages.some( 17 | (p) => p.injectDecorator === name || p.multiInjectDecorator === name, 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/implementation-resolvers/constructor.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | GetServiceTypeImplementation, 3 | IServiceConstructor, 4 | IServiceImplementationResolver, 5 | ServiceType, 6 | } from "../types/index.js"; 7 | import { ConstructorServiceImplementationResolver } from "./ConstructorServiceImplementationResolver.js"; 8 | 9 | export function constructor[]>( 10 | constructor: IServiceConstructor>, 11 | ...dependencies: TArgs 12 | ): IServiceImplementationResolver { 13 | return new ConstructorServiceImplementationResolver( 14 | constructor, 15 | dependencies, 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-analyzer/src/isOptionalDependency.ts: -------------------------------------------------------------------------------- 1 | import { isServiceTypeResolver } from "@wroud/di/service-type-resolvers/BaseServiceTypeResolver.js"; 2 | import { isOptionalServiceTypeResolver } from "@wroud/di/service-type-resolvers/OptionalServiceTypeResolver.js"; 3 | import type { ServiceType } from "@wroud/di/types"; 4 | 5 | export function isOptionalDependency(dependency: ServiceType): boolean { 6 | let current: ServiceType | null = dependency; 7 | while (isServiceTypeResolver(current)) { 8 | if (isOptionalServiceTypeResolver(current)) { 9 | return true; 10 | } 11 | 12 | current = current.next; 13 | } 14 | 15 | return false; 16 | } 17 | -------------------------------------------------------------------------------- /packages/@wroud/react-reactive-value/src/useCreateReactiveValue.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import type { 3 | IReactiveValue, 4 | IReactiveValueSubscribe, 5 | } from "./IReactiveValue.js"; 6 | 7 | type NoInfer = intrinsic; 8 | export function useCreateReactiveValue( 9 | get: (...args: TArgs) => T, 10 | subscribe: NoInfer> | null, 11 | deps: React.DependencyList, 12 | ): IReactiveValue { 13 | const value = useMemo>( 14 | () => ({ 15 | get, 16 | subscribe: subscribe ?? (() => () => {}), 17 | }), 18 | deps, 19 | ); 20 | 21 | return value; 22 | } 23 | -------------------------------------------------------------------------------- /packages/@wroud/ts-template/src/getDefaultProjectName.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | 3 | export function getDefaultProjectName() { 4 | const normalizedPath = path.normalize(process.cwd()); // Handle cross-platform path differences 5 | const segments = normalizedPath.split(path.sep).filter(Boolean); // Split and remove empty segments 6 | 7 | const len = segments.length; 8 | 9 | // Check if the second-to-last segment starts with '@' 10 | if (len > 1 && segments[len - 2]?.startsWith("@")) { 11 | return `${segments[len - 2]}/${segments[len - 1]}`; // Return last two parts 12 | } 13 | 14 | // Otherwise, return only the last segment 15 | return segments[len - 1]!; 16 | } 17 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-analyzer/src/chart/getLinkPoints.ts: -------------------------------------------------------------------------------- 1 | import type { ILinkDatum } from "./createLinks.js"; 2 | import { Layout } from "./Layout.js"; 3 | 4 | export function getLinkPoints(link: ILinkDatum) { 5 | const target = link.target; 6 | const source = link.source; 7 | 8 | const dx = target.x! - source.x!; 9 | const dy = target.y! - source.y!; 10 | const distance = Math.sqrt(dx * dx + dy * dy); 11 | const offsetX = (dx * Layout.node.radius) / distance; 12 | const offsetY = (dy * Layout.node.radius) / distance; 13 | 14 | return [ 15 | { x: source.x! + offsetX, y: source.y! + offsetY }, 16 | { x: target.x! - offsetX, y: target.y! - offsetY }, 17 | ]; 18 | } 19 | -------------------------------------------------------------------------------- /packages/docs/src/packages/react-split-view/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # React Split View 6 | 7 | ## Overview 8 | 9 | `@wroud/react-split-view` is a lightweight React hook for creating resizable split panes. It supports horizontal and vertical layouts with minimal configuration and no external dependencies. 10 | 11 | ## Key Features 12 | 13 | - **Simple API**: Manage split views with a single hook. 14 | - **Lightweight**: Small bundle size and zero dependencies. 15 | - **Flexible Layouts**: Horizontal, vertical, and nested splits. 16 | - **Sticky Edges**: Optional snap-to-edge behavior while dragging. 17 | - **TypeScript**: Written in TypeScript for a fully typed API. 18 | -------------------------------------------------------------------------------- /packages/@wroud/react-tree/src/tree/useClasses.ts: -------------------------------------------------------------------------------- 1 | import { getCombinedClasses } from "./treeClasses.js"; 2 | import type { ITreeClasses } from "./ITreeClasses.js"; 3 | 4 | /** 5 | * Hook that combines default and custom classes for the tree 6 | * @param classes - User-provided custom classes 7 | * @param useDefaultClasses - Whether to include default optimized styles 8 | * @returns Combined classes object 9 | */ 10 | export function useClasses( 11 | classes: ITreeClasses | undefined, 12 | useDefaultClasses: boolean, 13 | ): ITreeClasses { 14 | return getCombinedClasses( 15 | classes as Record | undefined, 16 | useDefaultClasses, 17 | ) as ITreeClasses; 18 | } 19 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/app/components/LayoutIsolated.tsx: -------------------------------------------------------------------------------- 1 | import type { IndexComponentProps } from "@wroud/vite-plugin-ssg"; 2 | import { Html, Body, Head } from "@wroud/vite-plugin-ssg/react/components"; 3 | 4 | interface Props extends IndexComponentProps { 5 | children?: React.ReactNode; 6 | } 7 | 8 | export function LayoutIsolated({ children }: Props) { 9 | return ( 10 | 11 | 12 | 13 | 14 | Playground 15 | 16 | {children} 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/implementation-resolvers/ValueServiceImplementationResolver.ts: -------------------------------------------------------------------------------- 1 | import { EMPTY_DEPS } from "../helpers/EMPTY_DEPS.js"; 2 | import { getNameOfServiceType } from "../helpers/getNameOfServiceType.js"; 3 | import { BaseServiceImplementationResolver } from "./BaseServiceImplementationResolver.js"; 4 | 5 | export class ValueServiceImplementationResolver< 6 | T, 7 | > extends BaseServiceImplementationResolver { 8 | get name(): string { 9 | return getNameOfServiceType(this.implementation); 10 | } 11 | 12 | constructor(private readonly implementation: T) { 13 | super({ 14 | dependencies: EMPTY_DEPS, 15 | create: () => implementation, 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/@wroud/di-tools-benchmark/tsconfig.legacy-decorators.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@wroud/tsconfig/tsconfig.json", 3 | "compilerOptions": { 4 | "tsBuildInfoFile": "./lib/legacy-decorators/.tsbuildinfo", 5 | "rootDir": "src", 6 | "rootDirs": [ 7 | "src" 8 | ], 9 | "outDir": "lib/legacy", 10 | "incremental": true, 11 | "composite": true, 12 | "types": [ 13 | "reflect-metadata" 14 | ], 15 | "experimentalDecorators": true, 16 | "emitDecoratorMetadata": true 17 | }, 18 | "include": [ 19 | "src/inversify", 20 | "src/inversify7", 21 | "src/tsyringe" 22 | ], 23 | "references": [ 24 | { 25 | "path": "../di" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /packages/@wroud/di/src/types/IServiceInstancesStore.ts: -------------------------------------------------------------------------------- 1 | import type { IServiceDescriptor } from "./IServiceDescriptor.js"; 2 | import type { IServiceInstanceInfo } from "./IServiceInstanceInfo.js"; 3 | 4 | export interface IServiceInstancesStore 5 | extends Iterable> { 6 | hasInstanceOf(descriptor: IServiceDescriptor): boolean; 7 | getInstanceInfo( 8 | descriptor: IServiceDescriptor, 9 | ): IServiceInstanceInfo | undefined; 10 | addInstance( 11 | descriptor: IServiceDescriptor, 12 | requestedBy: IServiceDescriptor | null, 13 | ): IServiceInstanceInfo; 14 | [Symbol.dispose](): void; 15 | [Symbol.asyncDispose](): Promise; 16 | } 17 | -------------------------------------------------------------------------------- /packages/@wroud/playground-react/src/views/MarkdownView.tsx: -------------------------------------------------------------------------------- 1 | import Markdown from "react-markdown"; 2 | 3 | export interface MarkdownViewProps { 4 | content: string; 5 | } 6 | 7 | export function MarkdownView({ content }: MarkdownViewProps) { 8 | return ( 9 |
10 |
11 | {content} 12 |
13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/@wroud/vite-plugin-playground/src/app/NodeContent.tsx: -------------------------------------------------------------------------------- 1 | import { Template } from "./pages/Template.js"; 2 | import { Story } from "./Story.js"; 3 | import { Doc } from "./Doc.js"; 4 | import { useNode } from "@wroud/playground-react/views"; 5 | interface Props { 6 | activeNodeId: string | null; 7 | preview?: boolean; 8 | } 9 | 10 | export function NodeContent({ activeNodeId, preview }: Props) { 11 | const node = useNode(activeNodeId); 12 | 13 | switch (node?.type) { 14 | case "story": 15 | return ; 16 | case "doc": 17 | return ; 18 | default: 19 | return