@visulima/package 3.5.1 → 3.5.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## @visulima/package [3.5.2](https://github.com/visulima/visulima/compare/@visulima/package@3.5.1...@visulima/package@3.5.2) (2025-03-03)
2
+
3
+ ### Miscellaneous Chores
4
+
5
+ * updated dev dependencies ([487a976](https://github.com/visulima/visulima/commit/487a976932dc7c39edfc19ffd3968960ff338066))
6
+
7
+
8
+ ### Dependencies
9
+
10
+ * **@visulima/fs:** upgraded to 3.1.1
11
+
1
12
  ## @visulima/package [3.5.1](https://github.com/visulima/visulima/compare/@visulima/package@3.5.0...@visulima/package@3.5.1) (2025-01-29)
2
13
 
3
14
 
package/LICENSE.md CHANGED
@@ -86,7 +86,7 @@ License: MIT
86
86
  By: Simon Boudrias
87
87
  Repository: https://github.com/SBoudrias/Inquirer.js.git
88
88
 
89
- > Copyright (c) 2023 Simon Boudrias
89
+ > Copyright (c) 2025 Simon Boudrias
90
90
  >
91
91
  > Permission is hereby granted, free of charge, to any person
92
92
  > obtaining a copy of this software and associated documentation
package/README.md CHANGED
@@ -166,6 +166,7 @@ If you would like to help take a look at the [list of issues](https://github.com
166
166
  The visulima package is open-sourced software licensed under the [MIT][license-url]
167
167
 
168
168
  [typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
169
+
169
170
  [typescript-url]: https://www.typescriptlang.org/ "TypeScript" "typescript"
170
171
  [license-image]: https://img.shields.io/npm/l/@visulima/package?color=blueviolet&style=for-the-badge
171
172
  [license-url]: LICENSE.md "license"
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { PackageNotFoundError } from './error.cjs';
2
2
  export { RootMonorepo, Strategy, findMonorepoRoot, findMonorepoRootSync } from './monorepo.cjs';
3
3
  export { findPackageRoot, findPackageRootSync } from './package.cjs';
4
- export { E as EnsurePackagesOptions, F as FindPackageJsonCache, d as NormalizedPackageJson, N as NormalizedReadResult, P as PackageJson, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-B2CLbuXK.cjs';
4
+ export { E as EnsurePackagesOptions, F as FindPackageJsonCache, d as NormalizedPackageJson, N as NormalizedReadResult, P as PackageJson, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-z2Cyn4CW.cjs';
5
5
  export { PackageManager, PackageManagerResult, findLockFile, findLockFileSync, findPackageManager, findPackageManagerSync, generateMissingPackagesInstallMessage, getPackageManagerVersion, identifyInitiatingPackageManager } from './package-manager.cjs';
6
6
  import '@visulima/fs';
7
7
  import '@antfu/install-pkg';
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { PackageNotFoundError } from './error.mjs';
2
2
  export { RootMonorepo, Strategy, findMonorepoRoot, findMonorepoRootSync } from './monorepo.mjs';
3
3
  export { findPackageRoot, findPackageRootSync } from './package.mjs';
4
- export { E as EnsurePackagesOptions, F as FindPackageJsonCache, d as NormalizedPackageJson, N as NormalizedReadResult, P as PackageJson, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-B2CLbuXK.mjs';
4
+ export { E as EnsurePackagesOptions, F as FindPackageJsonCache, d as NormalizedPackageJson, N as NormalizedReadResult, P as PackageJson, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-z2Cyn4CW.mjs';
5
5
  export { PackageManager, PackageManagerResult, findLockFile, findLockFileSync, findPackageManager, findPackageManagerSync, generateMissingPackagesInstallMessage, getPackageManagerVersion, identifyInitiatingPackageManager } from './package-manager.mjs';
6
6
  import '@visulima/fs';
7
7
  import '@antfu/install-pkg';
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { PackageNotFoundError } from './error.js';
2
2
  export { RootMonorepo, Strategy, findMonorepoRoot, findMonorepoRootSync } from './monorepo.js';
3
3
  export { findPackageRoot, findPackageRootSync } from './package.js';
4
- export { E as EnsurePackagesOptions, F as FindPackageJsonCache, d as NormalizedPackageJson, N as NormalizedReadResult, P as PackageJson, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-B2CLbuXK.d.mjs';
4
+ export { E as EnsurePackagesOptions, F as FindPackageJsonCache, d as NormalizedPackageJson, N as NormalizedReadResult, P as PackageJson, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-z2Cyn4CW.js';
5
5
  export { PackageManager, PackageManagerResult, findLockFile, findLockFileSync, findPackageManager, findPackageManagerSync, generateMissingPackagesInstallMessage, getPackageManagerVersion, identifyInitiatingPackageManager } from './package-manager.js';
6
6
  import '@visulima/fs';
7
7
  import '@antfu/install-pkg';
@@ -1,4 +1,4 @@
1
- export { F as FindPackageJsonCache, N as NormalizedReadResult, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-B2CLbuXK.cjs';
2
1
  import '@visulima/fs';
2
+ export { F as FindPackageJsonCache, N as NormalizedReadResult, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-z2Cyn4CW.cjs';
3
3
  import '@antfu/install-pkg';
4
4
  import 'normalize-package-data';
@@ -1,4 +1,4 @@
1
- export { F as FindPackageJsonCache, N as NormalizedReadResult, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-B2CLbuXK.mjs';
2
1
  import '@visulima/fs';
2
+ export { F as FindPackageJsonCache, N as NormalizedReadResult, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-z2Cyn4CW.mjs';
3
3
  import '@antfu/install-pkg';
4
4
  import 'normalize-package-data';
@@ -1,4 +1,4 @@
1
- export { F as FindPackageJsonCache, N as NormalizedReadResult, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-B2CLbuXK.d.mjs';
2
1
  import '@visulima/fs';
2
+ export { F as FindPackageJsonCache, N as NormalizedReadResult, e as ensurePackages, f as findPackageJson, a as findPackageJsonSync, g as getPackageJsonProperty, h as hasPackageJsonAnyDependency, b as hasPackageJsonProperty, p as parsePackageJson, w as writePackageJson, c as writePackageJsonSync } from './packem_shared/package-json-z2Cyn4CW.js';
3
3
  import '@antfu/install-pkg';
4
4
  import 'normalize-package-data';
@@ -844,11 +844,89 @@ type PathsOptions = {
844
844
  ```
845
845
  */
846
846
  bracketNotation?: boolean;
847
+
848
+ /**
849
+ Only include leaf paths in the output.
850
+
851
+ @default false
852
+
853
+ @example
854
+ ```
855
+ type Post = {
856
+ id: number;
857
+ author: {
858
+ id: number;
859
+ name: {
860
+ first: string;
861
+ last: string;
862
+ };
863
+ };
864
+ };
865
+
866
+ type AllPaths = Paths<Post, {leavesOnly: false}>;
867
+ //=> 'id' | 'author' | 'author.id' | 'author.name' | 'author.name.first' | 'author.name.last'
868
+
869
+ type LeafPaths = Paths<Post, {leavesOnly: true}>;
870
+ //=> 'id' | 'author.id' | 'author.name.first' | 'author.name.last'
871
+ ```
872
+
873
+ @example
874
+ ```
875
+ type ArrayExample = {
876
+ array: Array<{foo: string}>;
877
+ tuple: [string, {bar: string}];
878
+ };
879
+
880
+ type AllPaths = Paths<ArrayExample, {leavesOnly: false}>;
881
+ //=> 'array' | `array.${number}` | `array.${number}.foo` | 'tuple' | 'tuple.0' | 'tuple.1' | 'tuple.1.bar'
882
+
883
+ type LeafPaths = Paths<ArrayExample, {leavesOnly: true}>;
884
+ //=> `array.${number}.foo` | 'tuple.0' | 'tuple.1.bar'
885
+ ```
886
+ */
887
+ leavesOnly?: boolean;
888
+
889
+ /**
890
+ Only include paths at the specified depth. By default all paths up to {@link PathsOptions.maxRecursionDepth | `maxRecursionDepth`} are included.
891
+
892
+ Note: Depth starts at `0` for root properties.
893
+
894
+ @default number
895
+
896
+ @example
897
+ ```
898
+ type Post = {
899
+ id: number;
900
+ author: {
901
+ id: number;
902
+ name: {
903
+ first: string;
904
+ last: string;
905
+ };
906
+ };
907
+ };
908
+
909
+ type DepthZero = Paths<Post, {depth: 0}>;
910
+ //=> 'id' | 'author'
911
+
912
+ type DepthOne = Paths<Post, {depth: 1}>;
913
+ //=> 'author.id' | 'author.name'
914
+
915
+ type DepthTwo = Paths<Post, {depth: 2}>;
916
+ //=> 'author.name.first' | 'author.name.last'
917
+
918
+ type LeavesAtDepthOne = Paths<Post, {leavesOnly: true; depth: 1}>;
919
+ //=> 'author.id'
920
+ ```
921
+ */
922
+ depth?: number;
847
923
  };
848
924
 
849
925
  type DefaultPathsOptions = {
850
926
  maxRecursionDepth: 10;
851
927
  bracketNotation: false;
928
+ leavesOnly: false;
929
+ depth: number;
852
930
  };
853
931
 
854
932
  /**
@@ -897,6 +975,10 @@ type Paths<T, Options extends PathsOptions = {}> = _Paths<T, {
897
975
  maxRecursionDepth: Options['maxRecursionDepth'] extends number ? Options['maxRecursionDepth'] : DefaultPathsOptions['maxRecursionDepth'];
898
976
  // Set default bracketNotation to false
899
977
  bracketNotation: Options['bracketNotation'] extends boolean ? Options['bracketNotation'] : DefaultPathsOptions['bracketNotation'];
978
+ // Set default leavesOnly to false
979
+ leavesOnly: Options['leavesOnly'] extends boolean ? Options['leavesOnly'] : DefaultPathsOptions['leavesOnly'];
980
+ // Set default depth to number
981
+ depth: Options['depth'] extends number ? Options['depth'] : DefaultPathsOptions['depth'];
900
982
  }>;
901
983
 
902
984
  type _Paths<T, Options extends Required<PathsOptions>> =
@@ -936,11 +1018,36 @@ type InternalPaths<T, Options extends Required<PathsOptions>> =
936
1018
  ) extends infer TranformedKey extends string | number ?
937
1019
  // 1. If style is 'a[0].b' and 'Key' is a numberlike value like 3 or '3', transform 'Key' to `[${Key}]`, else to `${Key}` | Key
938
1020
  // 2. If style is 'a.0.b', transform 'Key' to `${Key}` | Key
939
- | TranformedKey
1021
+ | ((Options['leavesOnly'] extends true
1022
+ ? MaxDepth extends 0
1023
+ ? TranformedKey
1024
+ : T[Key] extends EmptyObject | readonly [] | NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>
1025
+ ? TranformedKey
1026
+ : never
1027
+ : TranformedKey
1028
+ ) extends infer _TransformedKey
1029
+ // If `depth` is provided, the condition becomes truthy only when it reaches `0`.
1030
+ // Otherwise, since `depth` defaults to `number`, the condition is always truthy, returning paths at all depths.
1031
+ ? 0 extends Options['depth']
1032
+ ? _TransformedKey
1033
+ : never
1034
+ : never)
940
1035
  | (
941
1036
  // Recursively generate paths for the current key
942
1037
  GreaterThan<MaxDepth, 0> extends true // Limit the depth to prevent infinite recursion
943
- ? _Paths<T[Key], {bracketNotation: Options['bracketNotation']; maxRecursionDepth: Subtract<MaxDepth, 1>}> extends infer SubPath
1038
+ ? _Paths<T[Key],
1039
+ {
1040
+ bracketNotation: Options['bracketNotation'];
1041
+ maxRecursionDepth: Subtract<MaxDepth, 1>;
1042
+ leavesOnly: Options['leavesOnly'];
1043
+ depth: Options['depth'] extends infer Depth extends number // For distributing `Options['depth']`
1044
+ ? Depth extends 0 // Don't subtract further if `Depth` has reached `0`
1045
+ ? never
1046
+ : ToString<Depth> extends `-${number}` // Don't subtract if `Depth` is -ve
1047
+ ? never
1048
+ : Subtract<Options['depth'], 1> // If `Subtract` supported -ve numbers, then `depth` could have simply been `Subtract<Options['depth'], 1>`
1049
+ : never; // Should never happen
1050
+ }> extends infer SubPath
944
1051
  ? SubPath extends string | number
945
1052
  ? (
946
1053
  Options['bracketNotation'] extends true
@@ -1860,10 +1967,10 @@ type NormalizedReadResult = {
1860
1967
  };
1861
1968
  declare const findPackageJson: (cwd?: URL | string, options?: ReadOptions) => Promise<NormalizedReadResult>;
1862
1969
  declare const findPackageJsonSync: (cwd?: URL | string, options?: ReadOptions) => NormalizedReadResult;
1863
- declare const writePackageJson: <T = PackageJson$1>(data: T, options?: WriteJsonOptions & {
1970
+ declare const writePackageJson: <T = PackageJson>(data: T, options?: WriteJsonOptions & {
1864
1971
  cwd?: URL | string;
1865
1972
  }) => Promise<void>;
1866
- declare const writePackageJsonSync: <T = PackageJson$1>(data: T, options?: WriteJsonOptions & {
1973
+ declare const writePackageJsonSync: <T = PackageJson>(data: T, options?: WriteJsonOptions & {
1867
1974
  cwd?: URL | string;
1868
1975
  }) => void;
1869
1976
  declare const parsePackageJson: (packageFile: JsonObject | string, options?: {
@@ -844,11 +844,89 @@ type PathsOptions = {
844
844
  ```
845
845
  */
846
846
  bracketNotation?: boolean;
847
+
848
+ /**
849
+ Only include leaf paths in the output.
850
+
851
+ @default false
852
+
853
+ @example
854
+ ```
855
+ type Post = {
856
+ id: number;
857
+ author: {
858
+ id: number;
859
+ name: {
860
+ first: string;
861
+ last: string;
862
+ };
863
+ };
864
+ };
865
+
866
+ type AllPaths = Paths<Post, {leavesOnly: false}>;
867
+ //=> 'id' | 'author' | 'author.id' | 'author.name' | 'author.name.first' | 'author.name.last'
868
+
869
+ type LeafPaths = Paths<Post, {leavesOnly: true}>;
870
+ //=> 'id' | 'author.id' | 'author.name.first' | 'author.name.last'
871
+ ```
872
+
873
+ @example
874
+ ```
875
+ type ArrayExample = {
876
+ array: Array<{foo: string}>;
877
+ tuple: [string, {bar: string}];
878
+ };
879
+
880
+ type AllPaths = Paths<ArrayExample, {leavesOnly: false}>;
881
+ //=> 'array' | `array.${number}` | `array.${number}.foo` | 'tuple' | 'tuple.0' | 'tuple.1' | 'tuple.1.bar'
882
+
883
+ type LeafPaths = Paths<ArrayExample, {leavesOnly: true}>;
884
+ //=> `array.${number}.foo` | 'tuple.0' | 'tuple.1.bar'
885
+ ```
886
+ */
887
+ leavesOnly?: boolean;
888
+
889
+ /**
890
+ Only include paths at the specified depth. By default all paths up to {@link PathsOptions.maxRecursionDepth | `maxRecursionDepth`} are included.
891
+
892
+ Note: Depth starts at `0` for root properties.
893
+
894
+ @default number
895
+
896
+ @example
897
+ ```
898
+ type Post = {
899
+ id: number;
900
+ author: {
901
+ id: number;
902
+ name: {
903
+ first: string;
904
+ last: string;
905
+ };
906
+ };
907
+ };
908
+
909
+ type DepthZero = Paths<Post, {depth: 0}>;
910
+ //=> 'id' | 'author'
911
+
912
+ type DepthOne = Paths<Post, {depth: 1}>;
913
+ //=> 'author.id' | 'author.name'
914
+
915
+ type DepthTwo = Paths<Post, {depth: 2}>;
916
+ //=> 'author.name.first' | 'author.name.last'
917
+
918
+ type LeavesAtDepthOne = Paths<Post, {leavesOnly: true; depth: 1}>;
919
+ //=> 'author.id'
920
+ ```
921
+ */
922
+ depth?: number;
847
923
  };
848
924
 
849
925
  type DefaultPathsOptions = {
850
926
  maxRecursionDepth: 10;
851
927
  bracketNotation: false;
928
+ leavesOnly: false;
929
+ depth: number;
852
930
  };
853
931
 
854
932
  /**
@@ -897,6 +975,10 @@ type Paths<T, Options extends PathsOptions = {}> = _Paths<T, {
897
975
  maxRecursionDepth: Options['maxRecursionDepth'] extends number ? Options['maxRecursionDepth'] : DefaultPathsOptions['maxRecursionDepth'];
898
976
  // Set default bracketNotation to false
899
977
  bracketNotation: Options['bracketNotation'] extends boolean ? Options['bracketNotation'] : DefaultPathsOptions['bracketNotation'];
978
+ // Set default leavesOnly to false
979
+ leavesOnly: Options['leavesOnly'] extends boolean ? Options['leavesOnly'] : DefaultPathsOptions['leavesOnly'];
980
+ // Set default depth to number
981
+ depth: Options['depth'] extends number ? Options['depth'] : DefaultPathsOptions['depth'];
900
982
  }>;
901
983
 
902
984
  type _Paths<T, Options extends Required<PathsOptions>> =
@@ -936,11 +1018,36 @@ type InternalPaths<T, Options extends Required<PathsOptions>> =
936
1018
  ) extends infer TranformedKey extends string | number ?
937
1019
  // 1. If style is 'a[0].b' and 'Key' is a numberlike value like 3 or '3', transform 'Key' to `[${Key}]`, else to `${Key}` | Key
938
1020
  // 2. If style is 'a.0.b', transform 'Key' to `${Key}` | Key
939
- | TranformedKey
1021
+ | ((Options['leavesOnly'] extends true
1022
+ ? MaxDepth extends 0
1023
+ ? TranformedKey
1024
+ : T[Key] extends EmptyObject | readonly [] | NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>
1025
+ ? TranformedKey
1026
+ : never
1027
+ : TranformedKey
1028
+ ) extends infer _TransformedKey
1029
+ // If `depth` is provided, the condition becomes truthy only when it reaches `0`.
1030
+ // Otherwise, since `depth` defaults to `number`, the condition is always truthy, returning paths at all depths.
1031
+ ? 0 extends Options['depth']
1032
+ ? _TransformedKey
1033
+ : never
1034
+ : never)
940
1035
  | (
941
1036
  // Recursively generate paths for the current key
942
1037
  GreaterThan<MaxDepth, 0> extends true // Limit the depth to prevent infinite recursion
943
- ? _Paths<T[Key], {bracketNotation: Options['bracketNotation']; maxRecursionDepth: Subtract<MaxDepth, 1>}> extends infer SubPath
1038
+ ? _Paths<T[Key],
1039
+ {
1040
+ bracketNotation: Options['bracketNotation'];
1041
+ maxRecursionDepth: Subtract<MaxDepth, 1>;
1042
+ leavesOnly: Options['leavesOnly'];
1043
+ depth: Options['depth'] extends infer Depth extends number // For distributing `Options['depth']`
1044
+ ? Depth extends 0 // Don't subtract further if `Depth` has reached `0`
1045
+ ? never
1046
+ : ToString<Depth> extends `-${number}` // Don't subtract if `Depth` is -ve
1047
+ ? never
1048
+ : Subtract<Options['depth'], 1> // If `Subtract` supported -ve numbers, then `depth` could have simply been `Subtract<Options['depth'], 1>`
1049
+ : never; // Should never happen
1050
+ }> extends infer SubPath
944
1051
  ? SubPath extends string | number
945
1052
  ? (
946
1053
  Options['bracketNotation'] extends true
@@ -1860,10 +1967,10 @@ type NormalizedReadResult = {
1860
1967
  };
1861
1968
  declare const findPackageJson: (cwd?: URL | string, options?: ReadOptions) => Promise<NormalizedReadResult>;
1862
1969
  declare const findPackageJsonSync: (cwd?: URL | string, options?: ReadOptions) => NormalizedReadResult;
1863
- declare const writePackageJson: <T = PackageJson$1>(data: T, options?: WriteJsonOptions & {
1970
+ declare const writePackageJson: <T = PackageJson>(data: T, options?: WriteJsonOptions & {
1864
1971
  cwd?: URL | string;
1865
1972
  }) => Promise<void>;
1866
- declare const writePackageJsonSync: <T = PackageJson$1>(data: T, options?: WriteJsonOptions & {
1973
+ declare const writePackageJsonSync: <T = PackageJson>(data: T, options?: WriteJsonOptions & {
1867
1974
  cwd?: URL | string;
1868
1975
  }) => void;
1869
1976
  declare const parsePackageJson: (packageFile: JsonObject | string, options?: {
@@ -844,11 +844,89 @@ type PathsOptions = {
844
844
  ```
845
845
  */
846
846
  bracketNotation?: boolean;
847
+
848
+ /**
849
+ Only include leaf paths in the output.
850
+
851
+ @default false
852
+
853
+ @example
854
+ ```
855
+ type Post = {
856
+ id: number;
857
+ author: {
858
+ id: number;
859
+ name: {
860
+ first: string;
861
+ last: string;
862
+ };
863
+ };
864
+ };
865
+
866
+ type AllPaths = Paths<Post, {leavesOnly: false}>;
867
+ //=> 'id' | 'author' | 'author.id' | 'author.name' | 'author.name.first' | 'author.name.last'
868
+
869
+ type LeafPaths = Paths<Post, {leavesOnly: true}>;
870
+ //=> 'id' | 'author.id' | 'author.name.first' | 'author.name.last'
871
+ ```
872
+
873
+ @example
874
+ ```
875
+ type ArrayExample = {
876
+ array: Array<{foo: string}>;
877
+ tuple: [string, {bar: string}];
878
+ };
879
+
880
+ type AllPaths = Paths<ArrayExample, {leavesOnly: false}>;
881
+ //=> 'array' | `array.${number}` | `array.${number}.foo` | 'tuple' | 'tuple.0' | 'tuple.1' | 'tuple.1.bar'
882
+
883
+ type LeafPaths = Paths<ArrayExample, {leavesOnly: true}>;
884
+ //=> `array.${number}.foo` | 'tuple.0' | 'tuple.1.bar'
885
+ ```
886
+ */
887
+ leavesOnly?: boolean;
888
+
889
+ /**
890
+ Only include paths at the specified depth. By default all paths up to {@link PathsOptions.maxRecursionDepth | `maxRecursionDepth`} are included.
891
+
892
+ Note: Depth starts at `0` for root properties.
893
+
894
+ @default number
895
+
896
+ @example
897
+ ```
898
+ type Post = {
899
+ id: number;
900
+ author: {
901
+ id: number;
902
+ name: {
903
+ first: string;
904
+ last: string;
905
+ };
906
+ };
907
+ };
908
+
909
+ type DepthZero = Paths<Post, {depth: 0}>;
910
+ //=> 'id' | 'author'
911
+
912
+ type DepthOne = Paths<Post, {depth: 1}>;
913
+ //=> 'author.id' | 'author.name'
914
+
915
+ type DepthTwo = Paths<Post, {depth: 2}>;
916
+ //=> 'author.name.first' | 'author.name.last'
917
+
918
+ type LeavesAtDepthOne = Paths<Post, {leavesOnly: true; depth: 1}>;
919
+ //=> 'author.id'
920
+ ```
921
+ */
922
+ depth?: number;
847
923
  };
848
924
 
849
925
  type DefaultPathsOptions = {
850
926
  maxRecursionDepth: 10;
851
927
  bracketNotation: false;
928
+ leavesOnly: false;
929
+ depth: number;
852
930
  };
853
931
 
854
932
  /**
@@ -897,6 +975,10 @@ type Paths<T, Options extends PathsOptions = {}> = _Paths<T, {
897
975
  maxRecursionDepth: Options['maxRecursionDepth'] extends number ? Options['maxRecursionDepth'] : DefaultPathsOptions['maxRecursionDepth'];
898
976
  // Set default bracketNotation to false
899
977
  bracketNotation: Options['bracketNotation'] extends boolean ? Options['bracketNotation'] : DefaultPathsOptions['bracketNotation'];
978
+ // Set default leavesOnly to false
979
+ leavesOnly: Options['leavesOnly'] extends boolean ? Options['leavesOnly'] : DefaultPathsOptions['leavesOnly'];
980
+ // Set default depth to number
981
+ depth: Options['depth'] extends number ? Options['depth'] : DefaultPathsOptions['depth'];
900
982
  }>;
901
983
 
902
984
  type _Paths<T, Options extends Required<PathsOptions>> =
@@ -936,11 +1018,36 @@ type InternalPaths<T, Options extends Required<PathsOptions>> =
936
1018
  ) extends infer TranformedKey extends string | number ?
937
1019
  // 1. If style is 'a[0].b' and 'Key' is a numberlike value like 3 or '3', transform 'Key' to `[${Key}]`, else to `${Key}` | Key
938
1020
  // 2. If style is 'a.0.b', transform 'Key' to `${Key}` | Key
939
- | TranformedKey
1021
+ | ((Options['leavesOnly'] extends true
1022
+ ? MaxDepth extends 0
1023
+ ? TranformedKey
1024
+ : T[Key] extends EmptyObject | readonly [] | NonRecursiveType | ReadonlyMap<unknown, unknown> | ReadonlySet<unknown>
1025
+ ? TranformedKey
1026
+ : never
1027
+ : TranformedKey
1028
+ ) extends infer _TransformedKey
1029
+ // If `depth` is provided, the condition becomes truthy only when it reaches `0`.
1030
+ // Otherwise, since `depth` defaults to `number`, the condition is always truthy, returning paths at all depths.
1031
+ ? 0 extends Options['depth']
1032
+ ? _TransformedKey
1033
+ : never
1034
+ : never)
940
1035
  | (
941
1036
  // Recursively generate paths for the current key
942
1037
  GreaterThan<MaxDepth, 0> extends true // Limit the depth to prevent infinite recursion
943
- ? _Paths<T[Key], {bracketNotation: Options['bracketNotation']; maxRecursionDepth: Subtract<MaxDepth, 1>}> extends infer SubPath
1038
+ ? _Paths<T[Key],
1039
+ {
1040
+ bracketNotation: Options['bracketNotation'];
1041
+ maxRecursionDepth: Subtract<MaxDepth, 1>;
1042
+ leavesOnly: Options['leavesOnly'];
1043
+ depth: Options['depth'] extends infer Depth extends number // For distributing `Options['depth']`
1044
+ ? Depth extends 0 // Don't subtract further if `Depth` has reached `0`
1045
+ ? never
1046
+ : ToString<Depth> extends `-${number}` // Don't subtract if `Depth` is -ve
1047
+ ? never
1048
+ : Subtract<Options['depth'], 1> // If `Subtract` supported -ve numbers, then `depth` could have simply been `Subtract<Options['depth'], 1>`
1049
+ : never; // Should never happen
1050
+ }> extends infer SubPath
944
1051
  ? SubPath extends string | number
945
1052
  ? (
946
1053
  Options['bracketNotation'] extends true
@@ -1860,10 +1967,10 @@ type NormalizedReadResult = {
1860
1967
  };
1861
1968
  declare const findPackageJson: (cwd?: URL | string, options?: ReadOptions) => Promise<NormalizedReadResult>;
1862
1969
  declare const findPackageJsonSync: (cwd?: URL | string, options?: ReadOptions) => NormalizedReadResult;
1863
- declare const writePackageJson: <T = PackageJson$1>(data: T, options?: WriteJsonOptions & {
1970
+ declare const writePackageJson: <T = PackageJson>(data: T, options?: WriteJsonOptions & {
1864
1971
  cwd?: URL | string;
1865
1972
  }) => Promise<void>;
1866
- declare const writePackageJsonSync: <T = PackageJson$1>(data: T, options?: WriteJsonOptions & {
1973
+ declare const writePackageJsonSync: <T = PackageJson>(data: T, options?: WriteJsonOptions & {
1867
1974
  cwd?: URL | string;
1868
1975
  }) => void;
1869
1976
  declare const parsePackageJson: (packageFile: JsonObject | string, options?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visulima/package",
3
- "version": "3.5.1",
3
+ "version": "3.5.2",
4
4
  "description": "One Package to rule them all, finds your root-dir, monorepo, or package manager.",
5
5
  "keywords": [
6
6
  "anolilab",
@@ -146,8 +146,8 @@
146
146
  ],
147
147
  "dependencies": {
148
148
  "@antfu/install-pkg": "^1.0.0",
149
- "@inquirer/confirm": "^5.1.3",
150
- "@visulima/fs": "3.1.0",
149
+ "@inquirer/confirm": "^5.1.6",
150
+ "@visulima/fs": "3.1.1",
151
151
  "@visulima/path": "1.3.4",
152
152
  "normalize-package-data": "^7.0.0"
153
153
  },