akanjs 2.0.0-rc.0 → 2.0.0-rc.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/cli/index.js CHANGED
@@ -9346,7 +9346,7 @@ import {
9346
9346
  fork,
9347
9347
  spawn
9348
9348
  } from "child_process";
9349
- import { mkdir as mkdir2, stat as stat2 } from "fs/promises";
9349
+ import { mkdir as mkdir2, readdir as readDirEntries, stat as stat2 } from "fs/promises";
9350
9350
  import path7 from "path";
9351
9351
  import chalk4 from "chalk";
9352
9352
 
@@ -11074,7 +11074,7 @@ class Executor {
11074
11074
  const fileContent = await this.#applyTemplateFile({ templatePath: prefixTemplatePath, targetPath: path7.join(basePath2, filename), scanInfo, overwrite }, dict, options);
11075
11075
  return fileContent ? [fileContent] : [];
11076
11076
  } else {
11077
- const subdirs = await this.readdir(templatePath);
11077
+ const subdirs = await readDirEntries(templatePath);
11078
11078
  const fileContents = (await Promise.all(subdirs.map(async (subdir) => {
11079
11079
  const subpath = path7.join(templatePath, subdir);
11080
11080
  if ((await stat2(subpath)).isFile()) {
@@ -11198,6 +11198,9 @@ class WorkspaceExecutor extends Executor {
11198
11198
  if (type === "lib" || type === "pkg")
11199
11199
  rootTsConfig.compilerOptions.paths[`@${name}`] = [`${type}s/${name}/index.ts`];
11200
11200
  rootTsConfig.compilerOptions.paths[`@${name}/*`] = [`${type}s/${name}/*`];
11201
+ rootTsConfig.compilerOptions.paths[`@${type}s/${name}/*`] = [`${type}s/${name}/*`];
11202
+ if (type === "lib" || type === "pkg")
11203
+ rootTsConfig.compilerOptions.paths[`@${type}s/${name}`] = [`${type}s/${name}/index.ts`];
11201
11204
  if (rootTsConfig.references) {
11202
11205
  if (!rootTsConfig.references.some((ref) => ref.path === `./${type}s/${name}/tsconfig.json`))
11203
11206
  rootTsConfig.references.push({ path: `./${type}s/${name}/tsconfig.json` });
@@ -11207,7 +11210,7 @@ class WorkspaceExecutor extends Executor {
11207
11210
  }
11208
11211
  async unsetTsPaths(type, name) {
11209
11212
  const rootTsConfig = await this.readJson("tsconfig.json");
11210
- const filteredKeys = Object.keys(rootTsConfig.compilerOptions.paths ?? {}).filter((key) => !key.startsWith(`@${name}`));
11213
+ const filteredKeys = Object.keys(rootTsConfig.compilerOptions.paths ?? {}).filter((key) => !key.startsWith(`@${name}`) && !key.startsWith(`@${type}s/${name}`));
11211
11214
  rootTsConfig.compilerOptions.paths = Object.fromEntries(filteredKeys.map((key) => [key, rootTsConfig.compilerOptions.paths?.[key] ?? []]));
11212
11215
  if (rootTsConfig.references) {
11213
11216
  rootTsConfig.references = rootTsConfig.references.filter((ref) => !ref.path.startsWith(`./${type}s/${name}`));
@@ -12737,6 +12740,8 @@ class BarrelAnalyzer {
12737
12740
  const rel = path12.relative(pkg.pkgDir, absFile);
12738
12741
  if (!rel || rel.startsWith("..") || path12.isAbsolute(rel))
12739
12742
  return null;
12743
+ if (pkg.preserveFilePath)
12744
+ return `${pkg.pkgName}/${rel.split(path12.sep).join("/")}`;
12740
12745
  const noExt = stripKnownExt(rel);
12741
12746
  const tail = collapseIndex(noExt);
12742
12747
  if (tail === "")
@@ -12817,7 +12822,7 @@ var collapseIndex = (relPathNoExt) => {
12817
12822
 
12818
12823
  import path13 from "path";
12819
12824
  import ts3 from "typescript";
12820
- var createBarrelImportsPlugin = async (app, { skipPath = (p) => p.includes("node_modules"), pipeAfter } = {}) => {
12825
+ var createBarrelImportsPlugin = async (app, { skipPath = defaultSkipPath, pipeAfter } = {}) => {
12821
12826
  const akanConfig2 = await app.getConfig();
12822
12827
  const barrels = [...new Set(akanConfig2.barrelImports)].filter(Boolean);
12823
12828
  const analyzer = new BarrelAnalyzer({
@@ -12826,7 +12831,9 @@ var createBarrelImportsPlugin = async (app, { skipPath = (p) => p.includes("node
12826
12831
  return {
12827
12832
  name: "barrel-imports",
12828
12833
  setup(build) {
12829
- build.onLoad({ filter: /^(?!.*[\\/]node_modules[\\/]).*\.(tsx|ts|jsx|js)(\?v=\d+)?$/ }, async (args) => {
12834
+ build.onLoad({
12835
+ filter: /^(?:(?!.*[\\/]node_modules[\\/]).*|.*[\\/]node_modules[\\/]akanjs[\\/].*)\.(tsx|ts|jsx|js)(\?v=\d+)?$/
12836
+ }, async (args) => {
12830
12837
  const realPath = args.path.replace(/\?v=\d+$/, "");
12831
12838
  const loader = loaderFor(realPath);
12832
12839
  if (skipPath(realPath)) {
@@ -12936,6 +12943,9 @@ var createTsconfigPackageResolver = async (app) => {
12936
12943
  };
12937
12944
  };
12938
12945
  var CANDIDATE_EXTS2 = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
12946
+ var NODE_MODULES_RE = /[\\/]node_modules[\\/]/;
12947
+ var AKANJS_NODE_MODULE_RE = /[\\/]node_modules[\\/]akanjs[\\/]/;
12948
+ var defaultSkipPath = (absPath) => NODE_MODULES_RE.test(absPath) && !AKANJS_NODE_MODULE_RE.test(absPath);
12939
12949
  var resolveNodePackageExport = async (workspaceRoot, specifier) => {
12940
12950
  const packageName = getPackageName(specifier);
12941
12951
  if (!packageName)
@@ -12955,7 +12965,7 @@ var resolveNodePackageExport = async (workspaceRoot, specifier) => {
12955
12965
  if (!entryFile)
12956
12966
  return null;
12957
12967
  const pkgEntryName = specifier;
12958
- return { pkgName: pkgEntryName, entryFile, pkgDir: path13.dirname(entryFile) };
12968
+ return { pkgName: pkgEntryName, entryFile, pkgDir: path13.dirname(entryFile), preserveFilePath: true };
12959
12969
  } catch {
12960
12970
  return null;
12961
12971
  }
@@ -1,10 +1,7 @@
1
- import { getEnv() } from "akanjs/base";
1
+ import { getEnv } from "akanjs/base";
2
2
 
3
3
  import type { ModulesOptions } from "../lib/option";
4
4
 
5
5
  export const env: ModulesOptions = {
6
6
  ...getEnv(),
7
- hostname: null,
8
- redis: {},
9
-
10
7
  };
@@ -7,7 +7,7 @@ import {
7
7
  type SpawnOptions,
8
8
  spawn,
9
9
  } from "node:child_process";
10
- import { mkdir, stat } from "node:fs/promises";
10
+ import { mkdir, readdir as readDirEntries, stat } from "node:fs/promises";
11
11
  import path from "node:path";
12
12
  import {
13
13
  capitalize,
@@ -455,7 +455,7 @@ export class Executor {
455
455
  );
456
456
  return fileContent ? [fileContent] : ([] as FileContent[]);
457
457
  } else {
458
- const subdirs = await this.readdir(templatePath);
458
+ const subdirs = await readDirEntries(templatePath);
459
459
  const fileContents = (
460
460
  await Promise.all(
461
461
  subdirs.map(async (subdir) => {
@@ -615,6 +615,9 @@ export class WorkspaceExecutor extends Executor {
615
615
  if (type === "lib" || type === "pkg")
616
616
  rootTsConfig.compilerOptions.paths[`@${name}`] = [`${type}s/${name}/index.ts`];
617
617
  rootTsConfig.compilerOptions.paths[`@${name}/*`] = [`${type}s/${name}/*`];
618
+ rootTsConfig.compilerOptions.paths[`@${type}s/${name}/*`] = [`${type}s/${name}/*`];
619
+ if (type === "lib" || type === "pkg")
620
+ rootTsConfig.compilerOptions.paths[`@${type}s/${name}`] = [`${type}s/${name}/index.ts`];
618
621
  if (rootTsConfig.references) {
619
622
  if (!rootTsConfig.references.some((ref) => ref.path === `./${type}s/${name}/tsconfig.json`))
620
623
  rootTsConfig.references.push({ path: `./${type}s/${name}/tsconfig.json` });
@@ -625,7 +628,7 @@ export class WorkspaceExecutor extends Executor {
625
628
  async unsetTsPaths(type: "app" | "lib" | "pkg", name: string) {
626
629
  const rootTsConfig = (await this.readJson("tsconfig.json")) as TsConfigJson;
627
630
  const filteredKeys = Object.keys(rootTsConfig.compilerOptions.paths ?? {}).filter(
628
- (key) => !key.startsWith(`@${name}`),
631
+ (key) => !key.startsWith(`@${name}`) && !key.startsWith(`@${type}s/${name}`),
629
632
  );
630
633
  rootTsConfig.compilerOptions.paths = Object.fromEntries(
631
634
  filteredKeys.map((key) => [key, rootTsConfig.compilerOptions.paths?.[key] ?? []]),
@@ -17,6 +17,8 @@ export interface PackageEntry {
17
17
  entryFile: string;
18
18
  /** Absolute directory used as the base for subpath computation. Typically dirname(entryFile). */
19
19
  pkgDir: string;
20
+ /** Preserve concrete file paths for package exports that do not support extensionless deep imports. */
21
+ preserveFilePath?: boolean;
20
22
  }
21
23
 
22
24
  export interface BarrelAnalyzerOptions {
@@ -162,6 +164,7 @@ export class BarrelAnalyzer {
162
164
  #subpathFor(pkg: PackageEntry, absFile: string): string | null {
163
165
  const rel = path.relative(pkg.pkgDir, absFile);
164
166
  if (!rel || rel.startsWith("..") || path.isAbsolute(rel)) return null;
167
+ if (pkg.preserveFilePath) return `${pkg.pkgName}/${rel.split(path.sep).join("/")}`;
165
168
  const noExt = stripKnownExt(rel);
166
169
 
167
170
  const tail = collapseIndex(noExt);
@@ -19,7 +19,7 @@ export interface BarrelImportsPluginOptions {
19
19
 
20
20
  export const createBarrelImportsPlugin = async (
21
21
  app: App,
22
- { skipPath = (p) => p.includes("node_modules"), pipeAfter }: BarrelImportsPluginOptions = {},
22
+ { skipPath = defaultSkipPath, pipeAfter }: BarrelImportsPluginOptions = {},
23
23
  ): Promise<BunPlugin> => {
24
24
  const akanConfig = await app.getConfig();
25
25
  const barrels = [...new Set(akanConfig.barrelImports)].filter(Boolean);
@@ -31,40 +31,46 @@ export const createBarrelImportsPlugin = async (
31
31
  name: "barrel-imports",
32
32
  setup(build) {
33
33
 
34
- build.onLoad({ filter: /^(?!.*[\\/]node_modules[\\/]).*\.(tsx|ts|jsx|js)(\?v=\d+)?$/ }, async (args) => {
35
- const realPath = args.path.replace(/\?v=\d+$/, "");
36
- const loader = loaderFor(realPath);
37
- if (skipPath(realPath)) {
38
- const raw = await Bun.file(realPath).text();
39
- return { contents: raw, loader };
40
- }
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
+ }
41
46
 
42
- let source = await Bun.file(realPath).text();
47
+ let source = await Bun.file(realPath).text();
43
48
 
44
- const hasMacroAttr = MACRO_ATTR_RE.test(source);
49
+ const hasMacroAttr = MACRO_ATTR_RE.test(source);
45
50
 
46
- if (!hasMacroAttr && barrels.length > 0) {
47
-
48
- let maybe = false;
49
- for (const b of barrels) {
50
- if (source.includes(b)) {
51
- maybe = true;
52
- break;
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;
53
63
  }
54
64
  }
55
- if (maybe) {
56
- const rewritten = await rewriteBarrelImports(source, barrels, analyzer);
57
- if (rewritten !== null) source = rewritten;
58
- }
59
- }
60
65
 
61
- if (pipeAfter) {
62
- const piped = await pipeAfter(source, { path: realPath });
63
- if (piped !== null) source = piped;
64
- }
66
+ if (pipeAfter) {
67
+ const piped = await pipeAfter(source, { path: realPath });
68
+ if (piped !== null) source = piped;
69
+ }
65
70
 
66
- return { contents: source, loader };
67
- });
71
+ return { contents: source, loader };
72
+ },
73
+ );
68
74
  },
69
75
  };
70
76
  };
@@ -162,6 +168,10 @@ export const createTsconfigPackageResolver = async (
162
168
 
163
169
  const CANDIDATE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
164
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
+
165
175
  type ExportValue = string | string[] | { [condition: string]: ExportValue | undefined };
166
176
 
167
177
  const resolveNodePackageExport = async (workspaceRoot: string, specifier: string): Promise<PackageEntry | null> => {
@@ -184,7 +194,7 @@ const resolveNodePackageExport = async (workspaceRoot: string, specifier: string
184
194
  const entryFile = await resolveFileCandidate(path.resolve(pkgDir, rel));
185
195
  if (!entryFile) return null;
186
196
  const pkgEntryName = specifier;
187
- return { pkgName: pkgEntryName, entryFile, pkgDir: path.dirname(entryFile) };
197
+ return { pkgName: pkgEntryName, entryFile, pkgDir: path.dirname(entryFile), preserveFilePath: true };
188
198
  } catch {
189
199
  return null;
190
200
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akanjs",
3
- "version": "2.0.0-rc.0",
3
+ "version": "2.0.0-rc.1",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "types": ["bun-types"]
5
- },
6
- "include": ["**/*.test.ts"]
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "types": ["bun-types"]
5
- },
6
- "include": ["**/*.test.ts"]
7
- }