akanjs 0.0.1 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CODE_OF_CONDUCT.md +54 -0
- package/CONTRIBUTING.md +83 -0
- package/LICENSE +21 -0
- package/README.ko.md +244 -0
- package/README.md +237 -6
- package/base/base.ts +194 -0
- package/base/baseEnv.ts +162 -0
- package/base/index.ts +6 -0
- package/base/primitiveRegistry.ts +342 -0
- package/base/symbols.ts +11 -0
- package/base/types.ts +137 -0
- package/base/utils.ts +30 -0
- package/cli/application/application.command.ts +213 -0
- package/cli/application/application.interface.tsx +225 -0
- package/cli/application/application.runner.ts +359 -0
- package/cli/application/application.script.ts +244 -0
- package/cli/build.ts +25 -0
- package/cli/cloud/cloud.command.ts +48 -0
- package/cli/cloud/cloud.runner.ts +158 -0
- package/cli/cloud/cloud.script.ts +40 -0
- package/cli/guideline/guideline.command.ts +31 -0
- package/cli/guideline/guideline.prompt.ts +212 -0
- package/cli/guideline/guideline.runner.ts +53 -0
- package/cli/guideline/guideline.script.ts +33 -0
- package/cli/guidelines/___library/sharedUiStructureDescription.en.md +767 -0
- package/cli/guidelines/___library/utilUiStructureDescription.en.md +395 -0
- package/cli/guidelines/___lint/lintRuleDescription.en.md +64 -0
- package/cli/guidelines/___module/moduleStructureDescription.en.md +80 -0
- package/cli/guidelines/componentRule/componentRule.generate.json +131 -0
- package/cli/guidelines/componentRule/componentRule.instruction.md +637 -0
- package/cli/guidelines/cssRule/cssRule.generate.json +93 -0
- package/cli/guidelines/cssRule/cssRule.instruction.md +435 -0
- package/cli/guidelines/databaseModule/databaseModule.generate.json +51 -0
- package/cli/guidelines/databaseModule/databaseModule.instruction.md +612 -0
- package/cli/guidelines/docPageRule/docPageRule.generate.json +72 -0
- package/cli/guidelines/docPageRule/docPageRule.instruction.md +389 -0
- package/cli/guidelines/enumConstant/enumConstant.generate.json +24 -0
- package/cli/guidelines/enumConstant/enumConstant.instruction.md +232 -0
- package/cli/guidelines/framework/framework.generate.json +119 -0
- package/cli/guidelines/framework/framework.instruction.md +1110 -0
- package/cli/guidelines/howToUseStore/howToUseStore.generate.json +0 -0
- package/cli/guidelines/modelConstant/modelConstant.generate.json +128 -0
- package/cli/guidelines/modelConstant/modelConstant.instruction.md +506 -0
- package/cli/guidelines/modelDictionary/modelDictionary.generate.json +108 -0
- package/cli/guidelines/modelDictionary/modelDictionary.instruction.md +547 -0
- package/cli/guidelines/modelDocument/modelDocument.generate.json +129 -0
- package/cli/guidelines/modelDocument/modelDocument.instruction.md +536 -0
- package/cli/guidelines/modelService/modelService.generate.json +135 -0
- package/cli/guidelines/modelService/modelService.instruction.md +708 -0
- package/cli/guidelines/modelSignal/modelSignal.generate.json +201 -0
- package/cli/guidelines/modelSignal/modelSignal.instruction.md +552 -0
- package/cli/guidelines/modelStore/modelStore.generate.json +130 -0
- package/cli/guidelines/modelStore/modelStore.instruction.md +585 -0
- package/cli/guidelines/modelTemplate/modelTemplate.generate.json +104 -0
- package/cli/guidelines/modelTemplate/modelTemplate.instruction.md +604 -0
- package/cli/guidelines/modelUnit/modelUnit.generate.json +92 -0
- package/cli/guidelines/modelUnit/modelUnit.instruction.md +541 -0
- package/cli/guidelines/modelUtil/modelUtil.generate.json +93 -0
- package/cli/guidelines/modelUtil/modelUtil.instruction.md +752 -0
- package/cli/guidelines/modelView/modelView.generate.json +80 -0
- package/cli/guidelines/modelView/modelView.instruction.md +1005 -0
- package/cli/guidelines/modelZone/modelZone.generate.json +126 -0
- package/cli/guidelines/modelZone/modelZone.instruction.md +528 -0
- package/cli/guidelines/scalarConstant/scalarConstant.generate.json +106 -0
- package/cli/guidelines/scalarConstant/scalarConstant.instruction.md +442 -0
- package/cli/guidelines/scalarDictionary/scalarDictionary.generate.json +83 -0
- package/cli/guidelines/scalarDictionary/scalarDictionary.instruction.md +273 -0
- package/cli/guidelines/scalarModule/scalarModule.generate.json +35 -0
- package/cli/guidelines/scalarModule/scalarModule.instruction.md +81 -0
- package/cli/guidelines/sharedUiUsage/sharedUiUsage.generate.json +108 -0
- package/cli/guidelines/sharedUiUsage/sharedUiUsage.instruction.md +310 -0
- package/cli/guidelines/utilUiUsage/utilUiUsage.generate.json +140 -0
- package/cli/guidelines/utilUiUsage/utilUiUsage.instruction.md +339 -0
- package/cli/index.js +11399 -0
- package/cli/index.ts +24 -0
- package/cli/library/library.command.ts +28 -0
- package/cli/library/library.runner.ts +69 -0
- package/cli/library/library.script.ts +39 -0
- package/cli/module/module.command.ts +35 -0
- package/cli/module/module.prompt.ts +18 -0
- package/cli/module/module.request.ts +319 -0
- package/cli/module/module.runner.ts +76 -0
- package/cli/module/module.script.ts +161 -0
- package/cli/package/package.command.ts +32 -0
- package/cli/package/package.runner.ts +64 -0
- package/cli/package/package.script.ts +35 -0
- package/cli/page/page.command.ts +14 -0
- package/cli/page/page.runner.ts +14 -0
- package/cli/page/page.script.ts +12 -0
- package/cli/scalar/scalar.command.ts +21 -0
- package/cli/scalar/scalar.prompt.ts +131 -0
- package/cli/scalar/scalar.runner.ts +38 -0
- package/cli/scalar/scalar.script.ts +16 -0
- package/cli/templates/__scalar/__model__/__model__.constant.ts +15 -0
- package/cli/templates/__scalar/__model__/__model__.dictionary.ts +19 -0
- package/cli/templates/__scalar/__model__/__model__.document.ts +15 -0
- package/cli/templates/app/akan.config.ts +14 -0
- package/cli/templates/app/capacitor.config.ts.template +8 -0
- package/cli/templates/app/common/commonLogic.ts +12 -0
- package/cli/templates/app/common/index.ts +10 -0
- package/cli/templates/app/env/env.client.debug.ts.template +7 -0
- package/cli/templates/app/env/env.client.develop.ts.template +7 -0
- package/cli/templates/app/env/env.client.local.ts.template +7 -0
- package/cli/templates/app/env/env.client.main.ts.template +7 -0
- package/cli/templates/app/env/env.client.testing.ts.template +7 -0
- package/cli/templates/app/env/env.client.ts +21 -0
- package/cli/templates/app/env/env.client.type.ts +16 -0
- package/cli/templates/app/env/env.server.debug.ts.template +7 -0
- package/cli/templates/app/env/env.server.develop.ts.template +9 -0
- package/cli/templates/app/env/env.server.local.ts.template +14 -0
- package/cli/templates/app/env/env.server.main.ts.template +9 -0
- package/cli/templates/app/env/env.server.testing.ts.template +6 -0
- package/cli/templates/app/env/env.server.ts +20 -0
- package/cli/templates/app/lib/___appName__/__appName__.dictionary.ts +17 -0
- package/cli/templates/app/lib/___appName__/__appName__.service.ts +13 -0
- package/cli/templates/app/lib/___appName__/__appName__.signal.ts +17 -0
- package/cli/templates/app/lib/___appName__/__appName__.store.ts +15 -0
- package/cli/templates/app/lib/option.ts +17 -0
- package/cli/templates/app/main.ts +16 -0
- package/cli/templates/app/package.json.template +5 -0
- package/cli/templates/app/page/_index.tsx +172 -0
- package/cli/templates/app/page/_layout.tsx +32 -0
- package/cli/templates/app/page/styles.css.template +53 -0
- package/cli/templates/app/public/favicon.ico +0 -0
- package/cli/templates/app/public/logo.png +0 -0
- package/cli/templates/app/srvkit/backendLogic.ts +12 -0
- package/cli/templates/app/srvkit/index.ts +10 -0
- package/cli/templates/app/tsconfig.json.template +21 -0
- package/cli/templates/app/ui/UiComponent.ts +16 -0
- package/cli/templates/app/ui/index.ts +10 -0
- package/cli/templates/app/webkit/frontendLogic.ts +12 -0
- package/cli/templates/app/webkit/index.ts +10 -0
- package/cli/templates/client.ts +46 -0
- package/cli/templates/crudPages/[__model__Id]/edit/page.tsx +47 -0
- package/cli/templates/crudPages/[__model__Id]/page.tsx +52 -0
- package/cli/templates/crudPages/new/page.tsx +42 -0
- package/cli/templates/crudPages/page.tsx +43 -0
- package/cli/templates/crudSinglePage/page.tsx +37 -0
- package/cli/templates/env/_env.server.type.ts +16 -0
- package/cli/templates/facetIndex/index.ts +32 -0
- package/cli/templates/index.ts +10 -0
- package/cli/templates/lib/__lib/lib.constant.ts +38 -0
- package/cli/templates/lib/__lib/lib.dictionary.ts +33 -0
- package/cli/templates/lib/__lib/lib.document.ts +35 -0
- package/cli/templates/lib/__lib/lib.service.ts +33 -0
- package/cli/templates/lib/__lib/lib.signal.ts +34 -0
- package/cli/templates/lib/__lib/lib.store.ts +33 -0
- package/cli/templates/lib/cnst.ts +29 -0
- package/cli/templates/lib/db.ts +32 -0
- package/cli/templates/lib/dict.ts +49 -0
- package/cli/templates/lib/sig.ts +60 -0
- package/cli/templates/lib/srv.ts +34 -0
- package/cli/templates/lib/st.ts +31 -0
- package/cli/templates/lib/useClient.ts +19 -0
- package/cli/templates/lib/useServer.ts +7 -0
- package/cli/templates/libRoot/.gitignore.template +16 -0
- package/cli/templates/libRoot/akan.config.ts +12 -0
- package/cli/templates/libRoot/base/baseLogic.ts +10 -0
- package/cli/templates/libRoot/base/index.ts +8 -0
- package/cli/templates/libRoot/common/commonLogic.ts +10 -0
- package/cli/templates/libRoot/common/index.ts +8 -0
- package/cli/templates/libRoot/env/env.server.example.ts.template +6 -0
- package/cli/templates/libRoot/env/env.server.testing.ts.template +6 -0
- package/cli/templates/libRoot/lib/___libName__/__libName__.dictionary.ts +15 -0
- package/cli/templates/libRoot/lib/___libName__/__libName__.service.ts +11 -0
- package/cli/templates/libRoot/lib/___libName__/__libName__.store.ts +13 -0
- package/cli/templates/libRoot/lib/option.ts +17 -0
- package/cli/templates/libRoot/package.json.template +5 -0
- package/cli/templates/libRoot/srvkit/backendLogic.ts +10 -0
- package/cli/templates/libRoot/srvkit/index.ts +8 -0
- package/cli/templates/libRoot/tsconfig.json.template +11 -0
- package/cli/templates/libRoot/ui/index.ts +7 -0
- package/cli/templates/libRoot/webkit/frontendLogic.ts +10 -0
- package/cli/templates/libRoot/webkit/index.ts +8 -0
- package/cli/templates/localDev/docker-compose.yaml.template +37 -0
- package/cli/templates/module/__Model__.Template.tsx +36 -0
- package/cli/templates/module/__Model__.Unit.tsx +26 -0
- package/cli/templates/module/__Model__.Util.tsx +30 -0
- package/cli/templates/module/__Model__.View.tsx +29 -0
- package/cli/templates/module/__Model__.Zone.tsx +43 -0
- package/cli/templates/module/__model__.constant.ts +24 -0
- package/cli/templates/module/__model__.dictionary.ts +30 -0
- package/cli/templates/module/__model__.document.ts +23 -0
- package/cli/templates/module/__model__.service.ts +16 -0
- package/cli/templates/module/__model__.signal.ts +27 -0
- package/cli/templates/module/__model__.store.ts +19 -0
- package/cli/templates/module/index.tsx +44 -0
- package/cli/templates/moduleRoot/index.tsx +31 -0
- package/cli/templates/pkgRoot/tsconfig.json.template +10 -0
- package/cli/templates/server.ts +45 -0
- package/cli/templates/workspaceRoot/.env.template +14 -0
- package/cli/templates/workspaceRoot/.gitignore.template +130 -0
- package/cli/templates/workspaceRoot/.vscode/settings.json.template +23 -0
- package/cli/templates/workspaceRoot/biome.json.template +175 -0
- package/cli/templates/workspaceRoot/bunfig.toml +4 -0
- package/cli/templates/workspaceRoot/infra/app/Chart.yaml.template +6 -0
- package/cli/templates/workspaceRoot/infra/app/templates/frontend.yaml.template +182 -0
- package/cli/templates/workspaceRoot/infra/app/values/_common-values.yaml.template +183 -0
- package/cli/templates/workspaceRoot/package.json.template +7 -0
- package/cli/templates/workspaceRoot/tsconfig.json.template +26 -0
- package/cli/testHelpers.ts +171 -0
- package/cli/workspace/workspace.command.ts +59 -0
- package/cli/workspace/workspace.runner.ts +57 -0
- package/cli/workspace/workspace.script.ts +68 -0
- package/client/capacitor.ts +68 -0
- package/client/clientRuntime.ts +141 -0
- package/client/cookie.ts +121 -0
- package/client/createFont.ts +8 -0
- package/client/csrTypes.ts +259 -0
- package/client/decorators.ts +25 -0
- package/client/device.ts +147 -0
- package/client/fetch.ts +1 -0
- package/client/index.ts +15 -0
- package/client/locale.ts +4 -0
- package/client/makePageProto.tsx +178 -0
- package/client/router.ts +286 -0
- package/client/rscNavigation.ts +19 -0
- package/client/storage.ts +33 -0
- package/client/translator.ts +43 -0
- package/client/types.ts +228 -0
- package/client/useClient.ts +1 -0
- package/common/Logger.ts +177 -0
- package/common/applyMixins.ts +14 -0
- package/common/capitalize.ts +4 -0
- package/common/deepObjectify.ts +27 -0
- package/common/formatNumber.ts +14 -0
- package/common/formatPhone.ts +7 -0
- package/common/getAllPropertyDescriptors.ts +13 -0
- package/common/hmrPhase.ts +17 -0
- package/common/httpClient.ts +101 -0
- package/common/index.ts +50 -0
- package/common/isDayjs.ts +3 -0
- package/common/isEmail.ts +2 -0
- package/common/isPhoneNumber.ts +8 -0
- package/common/isQueryEqual.ts +23 -0
- package/common/isValidDate.ts +14 -0
- package/common/localeConfig.ts +41 -0
- package/common/lowerlize.ts +4 -0
- package/common/mergeVersion.ts +10 -0
- package/common/objectify.ts +7 -0
- package/common/pathGet.ts +13 -0
- package/common/pathSet.ts +16 -0
- package/common/randomPick.ts +1 -0
- package/common/randomPicks.ts +12 -0
- package/common/routeConvention.ts +203 -0
- package/common/sleep.ts +8 -0
- package/common/splitVersion.ts +11 -0
- package/common/subRoute.ts +34 -0
- package/common/types.ts +15 -0
- package/constant/constantRegistry.ts +334 -0
- package/constant/crystalize.ts +45 -0
- package/constant/deserialize.ts +70 -0
- package/constant/fieldInfo.ts +415 -0
- package/constant/getDefault.ts +18 -0
- package/constant/immerify.ts +16 -0
- package/constant/index.ts +10 -0
- package/constant/purify.ts +118 -0
- package/constant/serialize.ts +87 -0
- package/constant/types.ts +105 -0
- package/constant/via.ts +360 -0
- package/devkit/aiEditor.ts +299 -0
- package/devkit/akanApp/akanApp.host.ts +356 -0
- package/devkit/akanApp/index.ts +1 -0
- package/devkit/akanConfig/akanConfig.ts +332 -0
- package/devkit/akanConfig/index.ts +2 -0
- package/devkit/akanConfig/types.ts +187 -0
- package/devkit/applicationBuildReporter.ts +69 -0
- package/devkit/applicationBuildRunner.ts +302 -0
- package/devkit/applicationReleasePackager.ts +205 -0
- package/devkit/artifact/implicitRootLayout.ts +155 -0
- package/devkit/artifact/index.ts +1 -0
- package/devkit/artifact/routeSeedIndex.ts +128 -0
- package/devkit/auth.ts +41 -0
- package/devkit/builder.ts +164 -0
- package/devkit/capacitor.base.config.ts +74 -0
- package/devkit/capacitorApp.ts +385 -0
- package/devkit/commandDecorators/argMeta.ts +88 -0
- package/devkit/commandDecorators/command.ts +314 -0
- package/devkit/commandDecorators/commandBuilder.ts +188 -0
- package/devkit/commandDecorators/commandMeta.ts +6 -0
- package/devkit/commandDecorators/dependencyBuilder.ts +100 -0
- package/devkit/commandDecorators/helpFormatter.ts +217 -0
- package/devkit/commandDecorators/index.ts +8 -0
- package/devkit/commandDecorators/targetMeta.ts +31 -0
- package/devkit/commandDecorators/types.ts +10 -0
- package/devkit/constants.ts +25 -0
- package/devkit/createTunnel.ts +36 -0
- package/devkit/dependencyScanner.ts +339 -0
- package/devkit/executors.ts +1325 -0
- package/devkit/extractDeps.ts +85 -0
- package/devkit/fileEditor.ts +106 -0
- package/devkit/fileSys.ts +39 -0
- package/devkit/frontendBuild/allRoutesBuilder.ts +103 -0
- package/devkit/frontendBuild/clientBuildTypes.ts +114 -0
- package/devkit/frontendBuild/clientEntriesBundler.ts +300 -0
- package/devkit/frontendBuild/clientEntryDiscovery.ts +196 -0
- package/devkit/frontendBuild/csrArtifactBuilder.ts +237 -0
- package/devkit/frontendBuild/cssCompiler.ts +279 -0
- package/devkit/frontendBuild/cssImportResolver.ts +116 -0
- package/devkit/frontendBuild/fontOptimizer.ts +427 -0
- package/devkit/frontendBuild/hmrChangeClassifier.ts +28 -0
- package/devkit/frontendBuild/hmrWatcher.ts +101 -0
- package/devkit/frontendBuild/index.ts +18 -0
- package/devkit/frontendBuild/pagesBundleBuilder.ts +137 -0
- package/devkit/frontendBuild/pagesEntrySourceGenerator.ts +37 -0
- package/devkit/frontendBuild/precompressArtifacts.ts +59 -0
- package/devkit/frontendBuild/routeClientBuilder.ts +290 -0
- package/devkit/frontendBuild/routesManifestArtifactSerializer.ts +62 -0
- package/devkit/frontendBuild/ssrBaseArtifactBuilder.ts +139 -0
- package/devkit/frontendBuild/vendorSpecifiers.ts +16 -0
- package/devkit/frontendBuild/watchRootResolver.ts +28 -0
- package/devkit/getCredentials.ts +19 -0
- package/devkit/getDirname.ts +3 -0
- package/devkit/getModelFileData.ts +59 -0
- package/devkit/getRelatedCnsts.ts +300 -0
- package/devkit/guideline.ts +19 -0
- package/devkit/incrementalBuilder/incrementalBuilder.host.ts +78 -0
- package/devkit/incrementalBuilder/incrementalBuilder.proc.ts +330 -0
- package/devkit/incrementalBuilder/index.ts +1 -0
- package/devkit/index.ts +36 -0
- package/devkit/lint/no-import-client-functions.grit +32 -0
- package/devkit/lint/no-import-external-library.grit +21 -0
- package/devkit/lint/no-js-private-class-method.grit +42 -0
- package/devkit/lint/no-use-client-in-server.grit +7 -0
- package/devkit/lint/non-scalar-props-restricted.grit +13 -0
- package/devkit/linter.ts +248 -0
- package/devkit/mobile/index.ts +1 -0
- package/devkit/mobile/mobileTarget.ts +47 -0
- package/devkit/prompter.ts +71 -0
- package/devkit/scanInfo.ts +605 -0
- package/devkit/selectModel.ts +11 -0
- package/devkit/spinner.ts +54 -0
- package/devkit/sshTunnel.ts +151 -0
- package/devkit/streamAi.ts +45 -0
- package/devkit/transforms/barrelAnalyzer.ts +249 -0
- package/devkit/transforms/barrelImportsPlugin.ts +451 -0
- package/devkit/transforms/externalizeFrameworkPlugin.ts +159 -0
- package/devkit/transforms/index.ts +5 -0
- package/devkit/transforms/rscUseClientTransform.ts +52 -0
- package/devkit/transforms/useClientBundlePlugin.ts +47 -0
- package/devkit/typeChecker.ts +260 -0
- package/devkit/types.ts +42 -0
- package/devkit/ui/MultiScrollList.tsx +228 -0
- package/devkit/ui/ScrollList.tsx +106 -0
- package/devkit/ui/index.ts +2 -0
- package/devkit/uploadRelease.ts +95 -0
- package/devkit/useStdoutDimensions.ts +20 -0
- package/dictionary/base.dictionary.ts +91 -0
- package/dictionary/dictInfo.ts +1079 -0
- package/dictionary/dictionary.ts +10 -0
- package/dictionary/index.ts +12 -0
- package/dictionary/locale.ts +230 -0
- package/dictionary/trans.ts +196 -0
- package/document/by.ts +39 -0
- package/document/dataLoader.ts +91 -0
- package/document/database.ts +168 -0
- package/document/databaseRegistry.ts +113 -0
- package/document/documentQuery.ts +143 -0
- package/document/documentSchema.ts +91 -0
- package/document/filterMeta.ts +210 -0
- package/document/index.ts +11 -0
- package/document/into.ts +169 -0
- package/document/loaderInfo.ts +50 -0
- package/document/schema.ts +24 -0
- package/document/types.ts +41 -0
- package/fetch/client/fetchClient.ts +600 -0
- package/fetch/client/httpClient.ts +157 -0
- package/fetch/client/index.ts +3 -0
- package/fetch/client/wsClient.ts +246 -0
- package/fetch/fetchType/appliedReturn.type.ts +108 -0
- package/fetch/fetchType/buildFetch.type.ts +24 -0
- package/fetch/fetchType/clientSignal.type.ts +22 -0
- package/fetch/fetchType/endpointFetch.type.ts +56 -0
- package/fetch/fetchType/index.ts +5 -0
- package/fetch/fetchType/sliceFetch.type.ts +173 -0
- package/fetch/index.ts +4 -0
- package/fetch/requestStorage.ts +127 -0
- package/fetch/serializer/fetch.serializer.ts +131 -0
- package/fetch/serializer/index.ts +1 -0
- package/fetch/types.ts +28 -0
- package/package.json +202 -5
- package/server/SSR_MEMORY_DIAGNOSIS.md +107 -0
- package/server/akanApp.ts +855 -0
- package/server/akanLib.ts +43 -0
- package/server/akanOption.ts +42 -0
- package/server/akanServer.ts +369 -0
- package/server/artifact/builderRpc.ts +124 -0
- package/server/artifact/index.ts +6 -0
- package/server/artifact/ipcTypes.ts +46 -0
- package/server/artifact/manifestTypes.ts +19 -0
- package/server/artifact/routeClientCache.ts +224 -0
- package/server/artifact/routeSeedIndexStore.ts +89 -0
- package/server/artifact/routesManifestStore.ts +120 -0
- package/server/decorators.ts +95 -0
- package/server/di/diLifecycle.ts +520 -0
- package/server/di/index.ts +4 -0
- package/server/di/predefinedAdaptor.ts +77 -0
- package/server/di/resolveAdaptorHierarchy.ts +82 -0
- package/server/di/resolveHierarchy.ts +89 -0
- package/server/di/resolveServiceHierarchy.ts +47 -0
- package/server/di/utils.ts +40 -0
- package/server/hmr/changeBatch.ts +14 -0
- package/server/hmr/clientScript.ts +310 -0
- package/server/hmr/devHmrController.ts +395 -0
- package/server/hmr/index.ts +4 -0
- package/server/hmr/wsHub.ts +56 -0
- package/server/imageOptimizer.ts +427 -0
- package/server/imageOptimizerError.ts +8 -0
- package/server/index.ts +14 -0
- package/server/lifecycle/shutdownManager.ts +52 -0
- package/server/logging/rotatingLogWriter.ts +190 -0
- package/server/processMetricsCollector.ts +78 -0
- package/server/proxy/akanResponse.ts +16 -0
- package/server/proxy/bunRequestFields.ts +12 -0
- package/server/proxy/hostBasePathWebProxy.ts +112 -0
- package/server/proxy/index.ts +15 -0
- package/server/proxy/localeWebProxy.ts +71 -0
- package/server/proxy/types.ts +41 -0
- package/server/proxy/webProxyRunner.ts +90 -0
- package/server/resolver/database.resolver.ts +340 -0
- package/server/resolver/index.ts +3 -0
- package/server/resolver/resolver.contract.fixture.ts +222 -0
- package/server/resolver/service.resolver.ts +176 -0
- package/server/resolver/signal.resolver.ts +386 -0
- package/server/robots.ts +32 -0
- package/server/routeElementComposer.tsx +91 -0
- package/server/routeTreeBuilder.ts +279 -0
- package/server/routing/apiRouter.ts +226 -0
- package/server/rscClient.tsx +140 -0
- package/server/rscWorker.tsx +625 -0
- package/server/rscWorkerHost.ts +616 -0
- package/server/sitemap.ts +90 -0
- package/server/ssrFromRscRenderer.tsx +285 -0
- package/server/ssrTypes.ts +48 -0
- package/server/types/react-server-dom-webpack.d.ts +91 -0
- package/server/types.tsx +109 -0
- package/server/vendor/akanjs-base.ts +1 -0
- package/server/vendor/akanjs-common.ts +1 -0
- package/server/vendor/akanjs-constant.ts +1 -0
- package/server/vendor/akanjs-store.ts +1 -0
- package/server/vendor/react-dom-client.ts +5 -0
- package/server/vendor/react-dom.ts +21 -0
- package/server/vendor/react-jsx-dev-runtime.ts +5 -0
- package/server/vendor/react-jsx-runtime.ts +5 -0
- package/server/vendor/react-refresh-runtime.ts +6 -0
- package/server/vendor/react-server-dom-webpack-client-browser.ts +12 -0
- package/server/vendor/react.ts +51 -0
- package/server/vendor/scheduler.ts +23 -0
- package/server/webRouter.ts +712 -0
- package/service/adapt.ts +47 -0
- package/service/base.service.ts +18 -0
- package/service/index.ts +10 -0
- package/service/injectInfo.ts +393 -0
- package/service/ipcTypes.ts +127 -0
- package/service/predefinedAdaptor/cache.adaptor.ts +105 -0
- package/service/predefinedAdaptor/compress.adaptor.ts +357 -0
- package/service/predefinedAdaptor/database.adaptor.ts +1310 -0
- package/service/predefinedAdaptor/index.ts +13 -0
- package/service/predefinedAdaptor/logging.adaptor.ts +36 -0
- package/service/predefinedAdaptor/queue.adaptor.ts +42 -0
- package/service/predefinedAdaptor/role.adaptor.ts +18 -0
- package/service/predefinedAdaptor/schedule.adaptor.ts +188 -0
- package/service/predefinedAdaptor/solidCache.adaptor.ts +143 -0
- package/service/predefinedAdaptor/solidPubsub.adaptor.ts +98 -0
- package/service/predefinedAdaptor/solidQueue.adaptor.ts +203 -0
- package/service/predefinedAdaptor/solidSqlite.ts +85 -0
- package/service/predefinedAdaptor/sqlitePath.ts +20 -0
- package/service/predefinedAdaptor/storage.adaptor.ts +121 -0
- package/service/predefinedAdaptor/websocket.adaptor.ts +313 -0
- package/service/serve.ts +223 -0
- package/service/serviceModule.ts +221 -0
- package/service/serviceRegistry.ts +26 -0
- package/service/types.ts +113 -0
- package/signal/base.signal.ts +46 -0
- package/signal/endpoint.ts +122 -0
- package/signal/endpointInfo.ts +374 -0
- package/signal/exception.ts +50 -0
- package/signal/guard.ts +18 -0
- package/signal/guards.ts +16 -0
- package/signal/index.ts +18 -0
- package/signal/intercept.ts +39 -0
- package/signal/internal.ts +56 -0
- package/signal/internalArg.ts +38 -0
- package/signal/internalInfo.ts +208 -0
- package/signal/middleware.ts +108 -0
- package/signal/serializer/fetch.serializer.ts +128 -0
- package/signal/serializer/index.ts +1 -0
- package/signal/serverSignal.ts +114 -0
- package/signal/signalContext.ts +446 -0
- package/signal/signalRegistry.ts +82 -0
- package/signal/slice.ts +158 -0
- package/signal/sliceInfo.ts +254 -0
- package/signal/types.ts +131 -0
- package/store/action.ts +1067 -0
- package/store/baseSt.ts +81 -0
- package/store/hooks.ts +2 -0
- package/store/index.ts +8 -0
- package/store/rootStore.ts +26 -0
- package/store/state.ts +226 -0
- package/store/stateBuilder.ts +429 -0
- package/store/stateInfo.ts +66 -0
- package/store/store.ts +194 -0
- package/store/storeInstance.ts +382 -0
- package/store/storeRegistry.ts +84 -0
- package/store/types.ts +69 -0
- package/store/withSelector.ts +62 -0
- package/test/index.ts +16 -0
- package/test/playwright.config.base.ts +48 -0
- package/test/playwright.pageAgent.ts +41 -0
- package/test/sample.ts +19 -0
- package/test/sampleOf.ts +70 -0
- package/test/signalTest.preload.ts +10 -0
- package/test/signalTestRuntime.ts +126 -0
- package/test/testServer.ts +187 -0
- package/ui/BottomSheet.tsx +103 -0
- package/ui/Button.tsx +70 -0
- package/ui/ClientSide.tsx +11 -0
- package/ui/Clipboard.tsx +49 -0
- package/ui/Constant/Doc.tsx +696 -0
- package/ui/Constant/Mermaid.tsx +149 -0
- package/ui/Constant/index.ts +6 -0
- package/ui/Constant/schemaDoc.ts +324 -0
- package/ui/Copy.tsx +27 -0
- package/ui/CsrImage.tsx +38 -0
- package/ui/Data/CardList.tsx +141 -0
- package/ui/Data/Dashboard.tsx +72 -0
- package/ui/Data/Insight.tsx +35 -0
- package/ui/Data/Item.tsx +285 -0
- package/ui/Data/ListContainer.tsx +320 -0
- package/ui/Data/Pagination.tsx +54 -0
- package/ui/Data/QueryMaker.tsx +21 -0
- package/ui/Data/TableList.tsx +161 -0
- package/ui/Data/index.ts +11 -0
- package/ui/Data/index_.tsx +11 -0
- package/ui/DatePicker.tsx +184 -0
- package/ui/Dialog/Action.tsx +15 -0
- package/ui/Dialog/Close.tsx +22 -0
- package/ui/Dialog/Content.tsx +11 -0
- package/ui/Dialog/Modal.tsx +137 -0
- package/ui/Dialog/Provider.tsx +33 -0
- package/ui/Dialog/Title.tsx +15 -0
- package/ui/Dialog/Trigger.tsx +22 -0
- package/ui/Dialog/context.ts +20 -0
- package/ui/Dialog/index.tsx +15 -0
- package/ui/DragAction.tsx +129 -0
- package/ui/DraggableList.tsx +230 -0
- package/ui/Dropdown.tsx +51 -0
- package/ui/Empty.tsx +32 -0
- package/ui/Field.tsx +1556 -0
- package/ui/FontFace.tsx +26 -0
- package/ui/Image.tsx +185 -0
- package/ui/InfiniteScroll.tsx +67 -0
- package/ui/Input.tsx +636 -0
- package/ui/KeyboardAvoiding.tsx +62 -0
- package/ui/Layout/BottomAction.tsx +15 -0
- package/ui/Layout/BottomInset.tsx +42 -0
- package/ui/Layout/BottomTab.tsx +71 -0
- package/ui/Layout/Header.tsx +38 -0
- package/ui/Layout/LeftSider.tsx +34 -0
- package/ui/Layout/Navbar.tsx +46 -0
- package/ui/Layout/RightSider.tsx +41 -0
- package/ui/Layout/Sider.tsx +69 -0
- package/ui/Layout/Template.tsx +11 -0
- package/ui/Layout/TopLeftAction.tsx +28 -0
- package/ui/Layout/Unit.tsx +19 -0
- package/ui/Layout/View.tsx +12 -0
- package/ui/Layout/Zone.tsx +10 -0
- package/ui/Layout/index.ts +27 -0
- package/ui/Link/Back.tsx +15 -0
- package/ui/Link/Close.tsx +20 -0
- package/ui/Link/CsrLink.tsx +41 -0
- package/ui/Link/Lang.tsx +16 -0
- package/ui/Link/SsrLink.tsx +68 -0
- package/ui/Link/index.tsx +32 -0
- package/ui/Link/types.ts +47 -0
- package/ui/Load/Edit.tsx +19 -0
- package/ui/Load/Edit_Client.tsx +120 -0
- package/ui/Load/Page.tsx +40 -0
- package/ui/Load/PageCSR.tsx +39 -0
- package/ui/Load/Pagination.tsx +89 -0
- package/ui/Load/Units.tsx +330 -0
- package/ui/Load/View.tsx +115 -0
- package/ui/Load/index.ts +11 -0
- package/ui/Load/index_.tsx +6 -0
- package/ui/Loading/Area.tsx +10 -0
- package/ui/Loading/Button.tsx +17 -0
- package/ui/Loading/Input.tsx +17 -0
- package/ui/Loading/ProgressBar.tsx +14 -0
- package/ui/Loading/Skeleton.tsx +22 -0
- package/ui/Loading/Spin.tsx +22 -0
- package/ui/Loading/index.tsx +8 -0
- package/ui/Menu.tsx +273 -0
- package/ui/Modal.tsx +87 -0
- package/ui/Model/AdminPanel.tsx +51 -0
- package/ui/Model/Edit.tsx +46 -0
- package/ui/Model/EditModal.tsx +301 -0
- package/ui/Model/EditWrapper.tsx +48 -0
- package/ui/Model/LoadInit.tsx +11 -0
- package/ui/Model/New.tsx +46 -0
- package/ui/Model/NewWrapper.tsx +20 -0
- package/ui/Model/NewWrapper_Client.tsx +57 -0
- package/ui/Model/Remove.tsx +75 -0
- package/ui/Model/RemoveWrapper.tsx +38 -0
- package/ui/Model/SureToRemove.tsx +108 -0
- package/ui/Model/View.tsx +65 -0
- package/ui/Model/ViewEditModal.tsx +125 -0
- package/ui/Model/ViewModal.tsx +71 -0
- package/ui/Model/ViewWrapper.tsx +38 -0
- package/ui/Model/index.ts +33 -0
- package/ui/Model/index_.tsx +16 -0
- package/ui/More.tsx +56 -0
- package/ui/ObjectId.tsx +29 -0
- package/ui/Pagination.tsx +120 -0
- package/ui/Popconfirm.tsx +135 -0
- package/ui/Portal.tsx +10 -0
- package/ui/Radio.tsx +53 -0
- package/ui/RecentTime.tsx +123 -0
- package/ui/Refresh.tsx +24 -0
- package/ui/ScreenNavigator.tsx +129 -0
- package/ui/Select.tsx +322 -0
- package/ui/Signal/Arg.tsx +352 -0
- package/ui/Signal/Doc.tsx +231 -0
- package/ui/Signal/Listener.tsx +74 -0
- package/ui/Signal/Message.tsx +267 -0
- package/ui/Signal/Object.tsx +131 -0
- package/ui/Signal/PubSub.tsx +247 -0
- package/ui/Signal/Request.tsx +30 -0
- package/ui/Signal/Response.tsx +76 -0
- package/ui/Signal/RestApi.tsx +390 -0
- package/ui/Signal/WebSocket.tsx +47 -0
- package/ui/Signal/index.ts +10 -0
- package/ui/Signal/makeExample.ts +75 -0
- package/ui/System/CSR.tsx +420 -0
- package/ui/System/Client.tsx +296 -0
- package/ui/System/Common.tsx +83 -0
- package/ui/System/DevModeToggle.tsx +21 -0
- package/ui/System/Gtag.tsx +69 -0
- package/ui/System/Messages.tsx +175 -0
- package/ui/System/Reconnect.tsx +156 -0
- package/ui/System/Root.tsx +10 -0
- package/ui/System/SSR.tsx +163 -0
- package/ui/System/SelectLanguage.tsx +47 -0
- package/ui/System/ThemeToggle.tsx +98 -0
- package/ui/System/index.tsx +23 -0
- package/ui/Tab/Menu.tsx +56 -0
- package/ui/Tab/Menus.tsx +10 -0
- package/ui/Tab/Panel.tsx +25 -0
- package/ui/Tab/Provider.tsx +25 -0
- package/ui/Tab/context.ts +16 -0
- package/ui/Tab/index.tsx +11 -0
- package/ui/Table.tsx +131 -0
- package/ui/ToggleSelect.tsx +144 -0
- package/ui/Unauthorized.tsx +29 -0
- package/ui/animated.tsx +8 -0
- package/ui/fontCss.ts +86 -0
- package/ui/index.ts +44 -0
- package/ui/styles.css +617 -0
- package/webkit/bootCsr.tsx +275 -0
- package/webkit/createRobotPage.ts +15 -0
- package/webkit/createSitemapPage.ts +4 -0
- package/webkit/index.ts +19 -0
- package/webkit/lazy.tsx +37 -0
- package/webkit/types.ts +7 -0
- package/webkit/useCamera.tsx +99 -0
- package/webkit/useCodepush.tsx +99 -0
- package/webkit/useContact.tsx +48 -0
- package/webkit/useCsrValues.ts +661 -0
- package/webkit/useDebounce.ts +24 -0
- package/webkit/useFetch.ts +48 -0
- package/webkit/useGeoLocation.tsx +24 -0
- package/webkit/useHistory.ts +76 -0
- package/webkit/useInterval.ts +21 -0
- package/webkit/useLocation.ts +69 -0
- package/webkit/usePurchase.tsx +156 -0
- package/webkit/usePushNoti.tsx +48 -0
- package/webkit/useThrottle.ts +22 -0
- package/src/index.js +0 -2
- package/src/index.js.map +0 -1
- package/src/lib/akan2.js +0 -4
- package/src/lib/akan2.js.map +0 -1
- package/src/run.js +0 -4
- package/src/run.js.map +0 -1
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import type { BunPlugin } from "bun";
|
|
3
|
+
import ts from "typescript";
|
|
4
|
+
import type { App } from "../commandDecorators";
|
|
5
|
+
import { BarrelAnalyzer, type BarrelExportMap, type PackageEntry } from "./barrelAnalyzer";
|
|
6
|
+
|
|
7
|
+
export interface BarrelImportsPluginOptions {
|
|
8
|
+
/** Absolute paths whose content should be returned unchanged (e.g. node_modules). */
|
|
9
|
+
skipPath?: (absPath: string) => boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Optional transform applied after the barrel rewrite in the same onLoad
|
|
12
|
+
* pass. Useful to chain further transforms (e.g. `"use client"` stubbing)
|
|
13
|
+
* that would otherwise be blocked — Bun's `onLoad` cannot fall through to a
|
|
14
|
+
* second plugin once a response is returned.
|
|
15
|
+
* Return the transformed source, or `null` to indicate no change.
|
|
16
|
+
*/
|
|
17
|
+
pipeAfter?: (source: string, args: { path: string }) => string | Promise<string | null> | null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const createBarrelImportsPlugin = async (
|
|
21
|
+
app: App,
|
|
22
|
+
{ skipPath = defaultSkipPath, pipeAfter }: BarrelImportsPluginOptions = {},
|
|
23
|
+
): Promise<BunPlugin> => {
|
|
24
|
+
const akanConfig = await app.getConfig();
|
|
25
|
+
const barrels = [...new Set(akanConfig.barrelImports)].filter(Boolean);
|
|
26
|
+
const analyzer = new BarrelAnalyzer({
|
|
27
|
+
resolvePackage: await createTsconfigPackageResolver(app),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
name: "barrel-imports",
|
|
32
|
+
setup(build) {
|
|
33
|
+
|
|
34
|
+
build.onLoad(
|
|
35
|
+
{
|
|
36
|
+
filter:
|
|
37
|
+
/^(?:(?!.*[\\/]node_modules[\\/]).*|.*[\\/]node_modules[\\/]akanjs[\\/].*)\.(tsx|ts|jsx|js)(\?v=\d+)?$/,
|
|
38
|
+
},
|
|
39
|
+
async (args) => {
|
|
40
|
+
const realPath = args.path.replace(/\?v=\d+$/, "");
|
|
41
|
+
const loader = loaderFor(realPath);
|
|
42
|
+
if (skipPath(realPath)) {
|
|
43
|
+
const raw = await Bun.file(realPath).text();
|
|
44
|
+
return { contents: raw, loader };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let source = await Bun.file(realPath).text();
|
|
48
|
+
|
|
49
|
+
const hasMacroAttr = MACRO_ATTR_RE.test(source);
|
|
50
|
+
|
|
51
|
+
if (!hasMacroAttr && barrels.length > 0) {
|
|
52
|
+
|
|
53
|
+
let maybe = false;
|
|
54
|
+
for (const b of barrels) {
|
|
55
|
+
if (source.includes(b)) {
|
|
56
|
+
maybe = true;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (maybe) {
|
|
61
|
+
const rewritten = await rewriteBarrelImports(source, barrels, analyzer);
|
|
62
|
+
if (rewritten !== null) source = rewritten;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (pipeAfter) {
|
|
67
|
+
const piped = await pipeAfter(source, { path: realPath });
|
|
68
|
+
if (piped !== null) source = piped;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { contents: source, loader };
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Build a `resolvePackage` that maps a package specifier (like `akanjs/ui`)
|
|
80
|
+
* to its barrel entry file using the workspace tsconfig `paths`. If no direct
|
|
81
|
+
* mapping exists, falls back to node_modules resolution.
|
|
82
|
+
*/
|
|
83
|
+
export const createTsconfigPackageResolver = async (
|
|
84
|
+
app: App,
|
|
85
|
+
): Promise<(pkgName: string) => Promise<PackageEntry | null>> => {
|
|
86
|
+
const tsconfig = await app.getTsConfig();
|
|
87
|
+
const tsconfigPaths = tsconfig.compilerOptions.paths ?? {};
|
|
88
|
+
|
|
89
|
+
const wildcardEntries = Object.entries(tsconfigPaths)
|
|
90
|
+
.filter(([k]) => k.endsWith("/*"))
|
|
91
|
+
.map(([k, v]) => ({
|
|
92
|
+
prefix: k.slice(0, -1), // keep trailing `/`
|
|
93
|
+
replacements: v,
|
|
94
|
+
}))
|
|
95
|
+
.sort((a, b) => b.prefix.length - a.prefix.length);
|
|
96
|
+
|
|
97
|
+
return async (pkgName) => {
|
|
98
|
+
const exact = tsconfigPaths[pkgName];
|
|
99
|
+
if (exact && exact.length > 0) {
|
|
100
|
+
const raw = exact[0];
|
|
101
|
+
if (!raw) return null;
|
|
102
|
+
const entryFile = path.resolve(app.workspace.workspaceRoot, raw);
|
|
103
|
+
if (!(await Bun.file(entryFile).exists())) return null;
|
|
104
|
+
|
|
105
|
+
const parsed = path.parse(entryFile);
|
|
106
|
+
const lastSlash = pkgName.lastIndexOf("/");
|
|
107
|
+
if (parsed.name !== "index" && lastSlash !== -1) {
|
|
108
|
+
const facet = pkgName.slice(lastSlash + 1);
|
|
109
|
+
const parentSpec = pkgName.slice(0, lastSlash);
|
|
110
|
+
if (facet === parsed.name && parentSpec.length > 0) {
|
|
111
|
+
return { pkgName: parentSpec, entryFile, pkgDir: parsed.dir };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return { pkgName, entryFile, pkgDir: path.dirname(entryFile) };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
for (const { prefix, replacements } of wildcardEntries) {
|
|
118
|
+
if (!pkgName.startsWith(prefix)) continue;
|
|
119
|
+
const suffix = pkgName.slice(prefix.length);
|
|
120
|
+
for (const repl of replacements) {
|
|
121
|
+
if (!repl) continue;
|
|
122
|
+
const replPath = repl.endsWith("/*") ? repl.slice(0, -1) : repl;
|
|
123
|
+
const candidate = path.resolve(app.workspace.workspaceRoot, replPath + suffix);
|
|
124
|
+
|
|
125
|
+
for (const ext of CANDIDATE_EXTS) {
|
|
126
|
+
const file = `${candidate}${ext}`;
|
|
127
|
+
if (await Bun.file(file).exists()) {
|
|
128
|
+
const lastSlash = pkgName.lastIndexOf("/");
|
|
129
|
+
if (lastSlash !== -1) {
|
|
130
|
+
const parentSpec = pkgName.slice(0, lastSlash);
|
|
131
|
+
if (parentSpec.length > 0) {
|
|
132
|
+
return { pkgName: parentSpec, entryFile: file, pkgDir: path.dirname(file) };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return { pkgName, entryFile: file, pkgDir: path.dirname(file) };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
for (const ext of CANDIDATE_EXTS) {
|
|
139
|
+
const file = path.join(candidate, `index${ext}`);
|
|
140
|
+
if (await Bun.file(file).exists()) {
|
|
141
|
+
return { pkgName, entryFile: file, pkgDir: candidate };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const exported = await resolveNodePackageExport(app.workspace.workspaceRoot, pkgName);
|
|
150
|
+
if (exported) return exported;
|
|
151
|
+
|
|
152
|
+
const pkgJsonPath = path.join(app.workspace.workspaceRoot, "node_modules", pkgName, "package.json");
|
|
153
|
+
if (!(await Bun.file(pkgJsonPath).exists())) return null;
|
|
154
|
+
try {
|
|
155
|
+
const pkgJson = JSON.parse(await Bun.file(pkgJsonPath).text()) as {
|
|
156
|
+
main?: string;
|
|
157
|
+
module?: string;
|
|
158
|
+
};
|
|
159
|
+
const rel = pkgJson.module ?? pkgJson.main ?? "index.js";
|
|
160
|
+
const entryFile = path.resolve(path.dirname(pkgJsonPath), rel);
|
|
161
|
+
if (!(await Bun.file(entryFile).exists())) return null;
|
|
162
|
+
return { pkgName, entryFile, pkgDir: path.dirname(pkgJsonPath) };
|
|
163
|
+
} catch {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const CANDIDATE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
|
|
170
|
+
|
|
171
|
+
const NODE_MODULES_RE = /[\\/]node_modules[\\/]/;
|
|
172
|
+
const AKANJS_NODE_MODULE_RE = /[\\/]node_modules[\\/]akanjs[\\/]/;
|
|
173
|
+
const defaultSkipPath = (absPath: string) => NODE_MODULES_RE.test(absPath) && !AKANJS_NODE_MODULE_RE.test(absPath);
|
|
174
|
+
|
|
175
|
+
type ExportValue = string | string[] | { [condition: string]: ExportValue | undefined };
|
|
176
|
+
|
|
177
|
+
const resolveNodePackageExport = async (workspaceRoot: string, specifier: string): Promise<PackageEntry | null> => {
|
|
178
|
+
const packageName = getPackageName(specifier);
|
|
179
|
+
if (!packageName) return null;
|
|
180
|
+
const pkgJsonPath = path.join(workspaceRoot, "node_modules", packageName, "package.json");
|
|
181
|
+
if (!(await Bun.file(pkgJsonPath).exists())) return null;
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
const pkgDir = path.dirname(pkgJsonPath);
|
|
185
|
+
const pkgJson = JSON.parse(await Bun.file(pkgJsonPath).text()) as {
|
|
186
|
+
exports?: Record<string, ExportValue>;
|
|
187
|
+
module?: string;
|
|
188
|
+
main?: string;
|
|
189
|
+
};
|
|
190
|
+
const subpath = specifier === packageName ? "." : `.${specifier.slice(packageName.length)}`;
|
|
191
|
+
const exported = resolvePackageExport(pkgJson.exports, subpath);
|
|
192
|
+
const rel = exported ?? (subpath === "." ? (pkgJson.module ?? pkgJson.main ?? "index.js") : null);
|
|
193
|
+
if (!rel || !rel.startsWith(".")) return null;
|
|
194
|
+
const entryFile = await resolveFileCandidate(path.resolve(pkgDir, rel));
|
|
195
|
+
if (!entryFile) return null;
|
|
196
|
+
const pkgEntryName = specifier;
|
|
197
|
+
return { pkgName: pkgEntryName, entryFile, pkgDir: path.dirname(entryFile), preserveFilePath: true };
|
|
198
|
+
} catch {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const resolveExportValue = (value: ExportValue | undefined): string | null => {
|
|
204
|
+
if (!value) return null;
|
|
205
|
+
if (typeof value === "string") return value;
|
|
206
|
+
if (Array.isArray(value)) {
|
|
207
|
+
for (const item of value) {
|
|
208
|
+
const resolved = resolveExportValue(item);
|
|
209
|
+
if (resolved) return resolved;
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
for (const condition of ["source", "import", "default", "types"]) {
|
|
214
|
+
const resolved = resolveExportValue(value[condition]);
|
|
215
|
+
if (resolved) return resolved;
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
const resolvePackageExport = (exportsMap: Record<string, ExportValue> | undefined, subpath: string): string | null => {
|
|
221
|
+
if (!exportsMap) return null;
|
|
222
|
+
const exact = resolveExportValue(exportsMap[subpath]);
|
|
223
|
+
if (exact) return exact;
|
|
224
|
+
|
|
225
|
+
for (const [key, value] of Object.entries(exportsMap)) {
|
|
226
|
+
const starIdx = key.indexOf("*");
|
|
227
|
+
if (starIdx === -1) continue;
|
|
228
|
+
const prefix = key.slice(0, starIdx);
|
|
229
|
+
const suffix = key.slice(starIdx + 1);
|
|
230
|
+
if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix)) continue;
|
|
231
|
+
const wildcard = subpath.slice(prefix.length, subpath.length - suffix.length);
|
|
232
|
+
const resolved = resolveExportValue(value);
|
|
233
|
+
if (resolved) return resolved.replace("*", wildcard);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return null;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const getPackageName = (specifier: string): string | null => {
|
|
240
|
+
const parts = specifier.split("/");
|
|
241
|
+
if (!parts[0]) return null;
|
|
242
|
+
if (specifier.startsWith("@")) return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : null;
|
|
243
|
+
return parts[0];
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const resolveFileCandidate = async (candidate: string): Promise<string | null> => {
|
|
247
|
+
if (await Bun.file(candidate).exists()) return candidate;
|
|
248
|
+
if (path.extname(candidate)) return null;
|
|
249
|
+
for (const ext of CANDIDATE_EXTS) {
|
|
250
|
+
const file = `${candidate}${ext}`;
|
|
251
|
+
if (await Bun.file(file).exists()) return file;
|
|
252
|
+
}
|
|
253
|
+
for (const ext of CANDIDATE_EXTS) {
|
|
254
|
+
const file = path.join(candidate, `index${ext}`);
|
|
255
|
+
if (await Bun.file(file).exists()) return file;
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const MACRO_ATTR_RE = /with\s*\{\s*type\s*:\s*["']macro["']\s*\}/;
|
|
261
|
+
|
|
262
|
+
/** Exposed for testing. */
|
|
263
|
+
export const rewriteBarrelImports = async (
|
|
264
|
+
source: string,
|
|
265
|
+
barrels: string[],
|
|
266
|
+
analyzer: BarrelAnalyzer,
|
|
267
|
+
): Promise<string | null> => {
|
|
268
|
+
const statements = findImportStatements(source);
|
|
269
|
+
if (statements.length === 0) return null;
|
|
270
|
+
|
|
271
|
+
let changed = false;
|
|
272
|
+
let out = source;
|
|
273
|
+
for (let i = statements.length - 1; i >= 0; i--) {
|
|
274
|
+
const stmt = statements[i];
|
|
275
|
+
if (!stmt) continue;
|
|
276
|
+
if (!barrels.includes(stmt.specifier)) continue;
|
|
277
|
+
const map = await analyzer.analyze(stmt.specifier);
|
|
278
|
+
if (!map || map.size === 0) continue;
|
|
279
|
+
const replacement = rewriteSingleStatement(stmt, map);
|
|
280
|
+
if (replacement === null) continue;
|
|
281
|
+
out = out.slice(0, stmt.start) + replacement + out.slice(stmt.end);
|
|
282
|
+
changed = true;
|
|
283
|
+
}
|
|
284
|
+
return changed ? out : null;
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
interface ImportStatement {
|
|
288
|
+
start: number;
|
|
289
|
+
end: number;
|
|
290
|
+
clause: string;
|
|
291
|
+
specifier: string;
|
|
292
|
+
trailingSemicolon: boolean;
|
|
293
|
+
raw: string;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const findImportStatements = (source: string): ImportStatement[] => {
|
|
297
|
+
const statements: ImportStatement[] = [];
|
|
298
|
+
const sourceFile = ts.createSourceFile("barrel-imports.tsx", source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
299
|
+
for (const statement of sourceFile.statements) {
|
|
300
|
+
if (!ts.isImportDeclaration(statement)) continue;
|
|
301
|
+
if (!ts.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
302
|
+
const importClause = statement.importClause;
|
|
303
|
+
if (!importClause) continue;
|
|
304
|
+
const statementStart = statement.getStart(sourceFile);
|
|
305
|
+
const statementEnd = statement.end;
|
|
306
|
+
statements.push({
|
|
307
|
+
start: statementStart,
|
|
308
|
+
end: statementEnd,
|
|
309
|
+
clause: source.slice(importClause.getStart(sourceFile), importClause.end).trim(),
|
|
310
|
+
specifier: statement.moduleSpecifier.text,
|
|
311
|
+
trailingSemicolon: source.slice(statement.moduleSpecifier.end, statement.end).includes(";"),
|
|
312
|
+
raw: source.slice(statementStart, statementEnd),
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
return statements;
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
interface NamedImportItem {
|
|
319
|
+
imported: string;
|
|
320
|
+
local: string;
|
|
321
|
+
isType: boolean;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
interface ParsedClause {
|
|
325
|
+
defaultImport?: string;
|
|
326
|
+
namespaceImport?: string;
|
|
327
|
+
named?: NamedImportItem[];
|
|
328
|
+
/** Whole clause is `import type { ... } from "..."`. */
|
|
329
|
+
typeOnly: boolean;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const parseImportClause = (clause: string): ParsedClause | null => {
|
|
333
|
+
let rest = clause.trim();
|
|
334
|
+
let typeOnly = false;
|
|
335
|
+
if (rest.startsWith("type ")) {
|
|
336
|
+
typeOnly = true;
|
|
337
|
+
rest = rest.slice(5).trim();
|
|
338
|
+
}
|
|
339
|
+
const parsed: ParsedClause = { typeOnly };
|
|
340
|
+
|
|
341
|
+
const commaMatch = /^(\w+)\s*,\s*(.+)$/.exec(rest);
|
|
342
|
+
if (commaMatch) {
|
|
343
|
+
parsed.defaultImport = commaMatch[1];
|
|
344
|
+
rest = commaMatch[2] ?? "";
|
|
345
|
+
} else if (/^\w+$/.test(rest)) {
|
|
346
|
+
parsed.defaultImport = rest;
|
|
347
|
+
return parsed;
|
|
348
|
+
}
|
|
349
|
+
if (rest.startsWith("*")) {
|
|
350
|
+
const ns = /^\*\s+as\s+(\w+)$/.exec(rest);
|
|
351
|
+
if (!ns) return null;
|
|
352
|
+
parsed.namespaceImport = ns[1];
|
|
353
|
+
return parsed;
|
|
354
|
+
}
|
|
355
|
+
if (rest.startsWith("{")) {
|
|
356
|
+
const close = rest.indexOf("}");
|
|
357
|
+
if (close === -1) return null;
|
|
358
|
+
const inner = rest.slice(1, close);
|
|
359
|
+
parsed.named = parseNamedImportList(inner);
|
|
360
|
+
return parsed;
|
|
361
|
+
}
|
|
362
|
+
return parsed;
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
const parseNamedImportList = (body: string): NamedImportItem[] => {
|
|
366
|
+
const out: NamedImportItem[] = [];
|
|
367
|
+
for (const raw of body.split(",")) {
|
|
368
|
+
const s = raw.trim();
|
|
369
|
+
if (!s) continue;
|
|
370
|
+
let isType = false;
|
|
371
|
+
let rest = s;
|
|
372
|
+
if (rest.startsWith("type ")) {
|
|
373
|
+
isType = true;
|
|
374
|
+
rest = rest.slice(5).trim();
|
|
375
|
+
}
|
|
376
|
+
const asMatch = /^(\w+)\s+as\s+(\w+)$/.exec(rest);
|
|
377
|
+
if (asMatch) {
|
|
378
|
+
out.push({ imported: asMatch[1] ?? "", local: asMatch[2] ?? "", isType });
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
if (/^\w+$/.test(rest)) {
|
|
382
|
+
out.push({ imported: rest, local: rest, isType });
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return out;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
const rewriteSingleStatement = (stmt: ImportStatement, map: BarrelExportMap): string | null => {
|
|
389
|
+
const clause = parseImportClause(stmt.clause);
|
|
390
|
+
if (!clause) return null;
|
|
391
|
+
|
|
392
|
+
if (clause.namespaceImport) return null;
|
|
393
|
+
|
|
394
|
+
if (clause.typeOnly && !clause.defaultImport) return null;
|
|
395
|
+
if (!clause.named || clause.named.length === 0) {
|
|
396
|
+
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const remaining: NamedImportItem[] = [];
|
|
401
|
+
const rewrites = new Map<string, NamedImportItem[]>();
|
|
402
|
+
for (const item of clause.named) {
|
|
403
|
+
if (item.isType) {
|
|
404
|
+
remaining.push(item);
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
const target = map.get(item.imported);
|
|
408
|
+
if (!target) {
|
|
409
|
+
remaining.push(item);
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
const list = rewrites.get(target.subpath) ?? [];
|
|
413
|
+
|
|
414
|
+
list.push({ imported: target.originalName, local: item.local, isType: false });
|
|
415
|
+
rewrites.set(target.subpath, list);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (rewrites.size === 0) return null;
|
|
419
|
+
|
|
420
|
+
const lines: string[] = [];
|
|
421
|
+
|
|
422
|
+
const tail = ";";
|
|
423
|
+
|
|
424
|
+
if (clause.defaultImport || remaining.length > 0) {
|
|
425
|
+
const parts: string[] = [];
|
|
426
|
+
if (clause.defaultImport) parts.push(clause.defaultImport);
|
|
427
|
+
if (remaining.length > 0) {
|
|
428
|
+
parts.push(`{ ${remaining.map(serializeNamedItem).join(", ")} }`);
|
|
429
|
+
}
|
|
430
|
+
lines.push(`import ${parts.join(", ")} from "${stmt.specifier}"${tail}`);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
for (const [subpath, items] of rewrites) {
|
|
434
|
+
lines.push(`import { ${items.map(serializeNamedItem).join(", ")} } from "${subpath}"${tail}`);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return lines.join("\n");
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
const serializeNamedItem = (item: NamedImportItem): string => {
|
|
441
|
+
const prefix = item.isType ? "type " : "";
|
|
442
|
+
if (item.imported === item.local) return `${prefix}${item.imported}`;
|
|
443
|
+
return `${prefix}${item.imported} as ${item.local}`;
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
const loaderFor = (absPath: string): "ts" | "tsx" | "js" | "jsx" => {
|
|
447
|
+
if (absPath.endsWith(".tsx")) return "tsx";
|
|
448
|
+
if (absPath.endsWith(".jsx")) return "jsx";
|
|
449
|
+
if (absPath.endsWith(".ts")) return "ts";
|
|
450
|
+
return "js";
|
|
451
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import type { BunPlugin } from "bun";
|
|
3
|
+
import type { App } from "../commandDecorators";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Keep framework/runtime singletons external while bundling authored
|
|
7
|
+
* workspace sources and ordinary npm dependencies into the pages bundle.
|
|
8
|
+
*
|
|
9
|
+
* Why a plugin instead of `Bun.build({ external })` or
|
|
10
|
+
* `Bun.build({ packages: "external" })`:
|
|
11
|
+
* - `packages: "external"` externalizes every bare specifier, including
|
|
12
|
+
* `@apps/*` / `@libs/*` — workspace packages that must stay bundled
|
|
13
|
+
* so the `"use client"` plugin can rewrite their exports — and ordinary
|
|
14
|
+
* npm dependencies like `dayjs` / `clsx`, which the production runtime
|
|
15
|
+
* package.json does not install for the SSR pages artifact.
|
|
16
|
+
* - Top-level `external: [...]` applies to macro-time module resolution
|
|
17
|
+
* too; any `with { type: "macro" }` import chain that transitively
|
|
18
|
+
* resolves `react` during build then fails with `ENOENT "react"`.
|
|
19
|
+
*
|
|
20
|
+
* An `onResolve` plugin only participates in the output-graph walk, so
|
|
21
|
+
* macros evaluate against the real modules in node_modules while the
|
|
22
|
+
* emitted bundle keeps bare specifiers only for runtime singletons that
|
|
23
|
+
* are installed in the generated production package.json.
|
|
24
|
+
*
|
|
25
|
+
* Externalization rules (applied in order):
|
|
26
|
+
* 1. Relative specifiers (`./`, `../`) are NEVER externalized — they
|
|
27
|
+
* always resolve to the current package's source tree and must be
|
|
28
|
+
* inlined so transitive `"use client"` stubs work.
|
|
29
|
+
* 2. Specifiers listed in `include` (workspace aliases like
|
|
30
|
+
* `@apps/*`, `@libs/*`) are NEVER externalized.
|
|
31
|
+
* 3. React / RSC runtime packages and framework host packages are
|
|
32
|
+
* externalized so the runtime supplies a single shared instance.
|
|
33
|
+
* 4. Other bare npm packages are bundled so the Docker runtime does not
|
|
34
|
+
* need to install every transitive page dependency separately.
|
|
35
|
+
*/
|
|
36
|
+
export interface ExternalizeFrameworkOptions {
|
|
37
|
+
app: App;
|
|
38
|
+
/**
|
|
39
|
+
* Prefixes that should be BUNDLED (kept internal). Defaults to
|
|
40
|
+
* `@apps/` and `@libs/` which are the workspace aliases used by the
|
|
41
|
+
* framework's app template.
|
|
42
|
+
*/
|
|
43
|
+
include?: string[];
|
|
44
|
+
/**
|
|
45
|
+
* Extra bare specifiers to force-externalize beyond the allowlist
|
|
46
|
+
* defaults. Not commonly needed since the default rule already
|
|
47
|
+
* externalizes every non-workspace specifier.
|
|
48
|
+
*/
|
|
49
|
+
extra?: string[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const DEFAULT_INCLUDE = ["akanjs/", "@apps/", "@libs/"];
|
|
53
|
+
|
|
54
|
+
const DEFAULT_EXCLUDE_EXACT = new Set<string>(["akanjs/webkit", "akanjs/server", "akanjs/cli", "akanjs/devkit"]);
|
|
55
|
+
const DEFAULT_EXCLUDE_PREFIX = ["akanjs/server/", "akanjs/cli/", "akanjs/devkit/"];
|
|
56
|
+
const RUNTIME_EXTERNAL_EXACT = new Set<string>([
|
|
57
|
+
"react",
|
|
58
|
+
"react-dom",
|
|
59
|
+
"react/jsx-runtime",
|
|
60
|
+
"react/jsx-dev-runtime",
|
|
61
|
+
"react-server-dom-webpack",
|
|
62
|
+
"react-server-dom-webpack/server.node",
|
|
63
|
+
"react-server-dom-webpack/client.node",
|
|
64
|
+
"react-server-dom-webpack/client.browser",
|
|
65
|
+
]);
|
|
66
|
+
const RUNTIME_EXTERNAL_PREFIX = ["react-dom/", "react-server-dom-webpack/"];
|
|
67
|
+
|
|
68
|
+
const CANDIDATE_EXTS = [".tsx", ".ts", ".jsx", ".js", ".mjs", ".cjs"];
|
|
69
|
+
|
|
70
|
+
export async function createExternalizeFrameworkPlugin(options: ExternalizeFrameworkOptions): Promise<BunPlugin> {
|
|
71
|
+
const tsconfig = await options.app.getTsConfig();
|
|
72
|
+
const includePrefixes = options.include ?? DEFAULT_INCLUDE;
|
|
73
|
+
const extraExact = new Set(options.extra ?? []);
|
|
74
|
+
const workspaceRoot = options.app.workspace.workspaceRoot;
|
|
75
|
+
const tsconfigPaths = tsconfig.compilerOptions.paths ?? {};
|
|
76
|
+
|
|
77
|
+
const rootEntries = Object.entries(tsconfigPaths)
|
|
78
|
+
.filter(([k]) => !k.endsWith("/*"))
|
|
79
|
+
.map(([k, v]) => ({ pkg: k, entryFile: v[0] ?? null }))
|
|
80
|
+
.filter((e): e is { pkg: string; entryFile: string } => e.entryFile !== null);
|
|
81
|
+
const wildcardEntries = Object.entries(tsconfigPaths)
|
|
82
|
+
.filter(([k]) => k.endsWith("/*"))
|
|
83
|
+
.map(([k, v]) => ({ prefix: k.slice(0, -1), replacements: v }))
|
|
84
|
+
.sort((a, b) => b.prefix.length - a.prefix.length);
|
|
85
|
+
|
|
86
|
+
async function resolveWorkspaceSubpath(spec: string): Promise<string | null> {
|
|
87
|
+
if (!workspaceRoot) return null;
|
|
88
|
+
|
|
89
|
+
for (const { prefix, replacements } of wildcardEntries) {
|
|
90
|
+
if (!spec.startsWith(prefix)) continue;
|
|
91
|
+
const suffix = spec.slice(prefix.length);
|
|
92
|
+
for (const repl of replacements) {
|
|
93
|
+
const replPath = repl?.endsWith("/*") ? repl.slice(0, -1) : (repl ?? "");
|
|
94
|
+
if (!replPath) continue;
|
|
95
|
+
const candidate = path.resolve(workspaceRoot, replPath + suffix);
|
|
96
|
+
const hit = await firstExisting(candidate);
|
|
97
|
+
if (hit) return hit;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (const { pkg, entryFile } of rootEntries) {
|
|
102
|
+
if (spec !== pkg && !spec.startsWith(`${pkg}/`)) continue;
|
|
103
|
+
if (spec === pkg) continue;
|
|
104
|
+
const suffix = spec.slice(pkg.length + 1);
|
|
105
|
+
const pkgDir = path.dirname(path.resolve(workspaceRoot, entryFile));
|
|
106
|
+
const candidate = path.join(pkgDir, suffix);
|
|
107
|
+
const hit = await firstExisting(candidate);
|
|
108
|
+
if (hit) return hit;
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
name: "akan-externalize-framework",
|
|
115
|
+
setup(build) {
|
|
116
|
+
build.onResolve({ filter: /.*/ }, async (args) => {
|
|
117
|
+
const spec = args.path;
|
|
118
|
+
|
|
119
|
+
if (spec === "." || spec === ".." || spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/"))
|
|
120
|
+
return undefined;
|
|
121
|
+
|
|
122
|
+
if (extraExact.has(spec) || DEFAULT_EXCLUDE_EXACT.has(spec)) return { path: spec, external: true };
|
|
123
|
+
for (const prefix of DEFAULT_EXCLUDE_PREFIX) {
|
|
124
|
+
if (spec.startsWith(prefix)) return { path: spec, external: true };
|
|
125
|
+
}
|
|
126
|
+
if (RUNTIME_EXTERNAL_EXACT.has(spec)) return { path: spec, external: true };
|
|
127
|
+
for (const prefix of RUNTIME_EXTERNAL_PREFIX) {
|
|
128
|
+
if (spec.startsWith(prefix)) return { path: spec, external: true };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
for (const prefix of includePrefixes) {
|
|
132
|
+
if (!spec.startsWith(prefix)) continue;
|
|
133
|
+
const resolved = await resolveWorkspaceSubpath(spec);
|
|
134
|
+
if (resolved) return { path: resolved };
|
|
135
|
+
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return undefined;
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function firstExisting(basePath: string): Promise<string | null> {
|
|
146
|
+
|
|
147
|
+
if (await Bun.file(basePath).exists()) return basePath;
|
|
148
|
+
|
|
149
|
+
for (const ext of CANDIDATE_EXTS) {
|
|
150
|
+
const candidate = `${basePath}${ext}`;
|
|
151
|
+
if (await Bun.file(candidate).exists()) return candidate;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
for (const ext of CANDIDATE_EXTS) {
|
|
155
|
+
const candidate = path.join(basePath, `index${ext}`);
|
|
156
|
+
if (await Bun.file(candidate).exists()) return candidate;
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
const USE_CLIENT_RE = /^\s*(?:\/\*[\s\S]*?\*\/\s*|\/\/[^\n]*\n\s*)*["']use client["']/;
|
|
4
|
+
const IMPLICIT_ROOT_LAYOUT_RE =
|
|
5
|
+
/[/\\]\.akan[/\\]generated[/\\](?:implicit-root-layout|root-layouts[/\\].*__root_layout)\.(tsx|ts|jsx|js)$/;
|
|
6
|
+
|
|
7
|
+
export interface UseClientTransformArgs {
|
|
8
|
+
path: string;
|
|
9
|
+
workspaceRoot?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function toClientReferencePath(absPath: string, workspaceRoot: string): string {
|
|
13
|
+
return path.relative(path.resolve(workspaceRoot), path.resolve(absPath)).split(path.sep).join("/");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns the stubbed module source if `source` is a client module, else null.
|
|
18
|
+
* The returned source is TypeScript-compatible (loader "ts" is safe).
|
|
19
|
+
*/
|
|
20
|
+
export function transformUseClient(source: string, args: UseClientTransformArgs): string | null {
|
|
21
|
+
if (!USE_CLIENT_RE.test(source)) return null;
|
|
22
|
+
if (IMPLICIT_ROOT_LAYOUT_RE.test(args.path)) return null;
|
|
23
|
+
const transpiler = new Bun.Transpiler({ loader: loaderFor(args.path) });
|
|
24
|
+
const { exports } = transpiler.scan(source);
|
|
25
|
+
if (exports.length === 0) return null;
|
|
26
|
+
|
|
27
|
+
const referencePath = args.workspaceRoot ? toClientReferencePath(args.path, args.workspaceRoot) : args.path;
|
|
28
|
+
const filePathLit = JSON.stringify(referencePath);
|
|
29
|
+
const lines: string[] = [`import { registerClientReference } from "react-server-dom-webpack/server.node";`];
|
|
30
|
+
|
|
31
|
+
for (const name of exports) {
|
|
32
|
+
const nameLit = JSON.stringify(name);
|
|
33
|
+
const errMsg = JSON.stringify(
|
|
34
|
+
`Attempted to call '${name}' from '${referencePath}' on the server, but it is a client-only export.`,
|
|
35
|
+
);
|
|
36
|
+
const proxy = `() => { throw new Error(${errMsg}); }`;
|
|
37
|
+
const binding =
|
|
38
|
+
name === "default"
|
|
39
|
+
? `export default registerClientReference(${proxy}, ${filePathLit}, ${nameLit});`
|
|
40
|
+
: `export const ${name} = registerClientReference(${proxy}, ${filePathLit}, ${nameLit});`;
|
|
41
|
+
lines.push(binding);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return lines.join("\n");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function loaderFor(absPath: string): "ts" | "tsx" | "js" | "jsx" {
|
|
48
|
+
if (absPath.endsWith(".tsx")) return "tsx";
|
|
49
|
+
if (absPath.endsWith(".jsx")) return "jsx";
|
|
50
|
+
if (absPath.endsWith(".ts")) return "ts";
|
|
51
|
+
return "js";
|
|
52
|
+
}
|