@stacksjs/path 0.75.244 → 0.75.246

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { appPath, frameworkPath, projectPath, storagePath } from './project';
1
+ import { appPath, frameworkDefaultsRoot, frameworkPath, projectPath, storagePath, usesVendoredDefaults } from './project';
2
2
  import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, parse, relative, resolve, sep, toNamespacedPath } from 'node:path';
3
3
  import type { ParsedPath } from 'node:path';
4
4
  /**
@@ -1220,6 +1220,8 @@ export declare interface Path {
1220
1220
  frameworkPath: (path?: string) => string
1221
1221
  browserPath: (path?: string) => string
1222
1222
  storagePath: (path?: string) => string
1223
+ frameworkDefaultsRoot: (projectRoot?: string) => string
1224
+ usesVendoredDefaults: (projectRoot?: string) => boolean
1223
1225
  functionsPath: (path?: string) => string
1224
1226
  gitPath: (path?: string) => string
1225
1227
  langPath: (path?: string) => string
@@ -1319,6 +1321,6 @@ export declare interface Path {
1319
1321
  * comparison can say whether it is current.
1320
1322
  */
1321
1323
  export type DefaultsProvenance = 'not-applicable' | 'current' | 'stale' | 'unstamped';
1322
- export { appPath, frameworkPath, isCompiledBinary, projectPath, storagePath } from './project';
1324
+ export { appPath, frameworkDefaultsRoot, frameworkPath, isCompiledBinary, isInstalledDefaultsRoot, linkPackagedDefaults, packagedDefaultsRoot, projectPath, storagePath, usesVendoredDefaults } from './project';
1323
1325
  export { resolveModulePath } from './module-resolution';
1324
1326
  export { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep, toNamespacedPath };
package/dist/index.js CHANGED
@@ -2,21 +2,21 @@
2
2
  // src/index.ts
3
3
  import {
4
4
  existsSync as existsSync3,
5
- lstatSync,
5
+ lstatSync as lstatSync2,
6
6
  mkdirSync,
7
7
  readFileSync,
8
8
  readdirSync,
9
9
  readlinkSync,
10
- realpathSync,
10
+ realpathSync as realpathSync2,
11
11
  renameSync,
12
- rmSync,
12
+ rmSync as rmSync2,
13
13
  unlinkSync
14
14
  } from "fs";
15
15
  import os from "os";
16
16
  import {
17
17
  basename,
18
18
  delimiter,
19
- dirname,
19
+ dirname as dirname2,
20
20
  extname,
21
21
  isAbsolute as isAbsolute2,
22
22
  join as join2,
@@ -30,8 +30,8 @@ import {
30
30
  import process2 from "process";
31
31
 
32
32
  // src/project.ts
33
- import { existsSync } from "fs";
34
- import { join, relative, resolve, sep } from "path";
33
+ import { existsSync, lstatSync, realpathSync, rmSync, symlinkSync } from "fs";
34
+ import { dirname, join, relative, resolve, sep } from "path";
35
35
  import process from "process";
36
36
  var cachedCwd;
37
37
  var cachedProjectRoot = "";
@@ -73,8 +73,75 @@ function appPath(path, options) {
73
73
  return relative(options.cwd || process.cwd(), absolutePath);
74
74
  return absolutePath;
75
75
  }
76
+ var VENDORED_DEFAULTS = "framework/defaults";
77
+ var packagedDefaultsRoots = new Map;
78
+ function isInstalledDefaultsRoot(path) {
79
+ return /[/\\]@stacksjs[/\\]defaults$/.test(path) && !/[/\\]install[/\\]cache[/\\]/.test(path);
80
+ }
81
+ function packagedDefaultsRoot(projectRoot = projectPath()) {
82
+ const cached = packagedDefaultsRoots.get(projectRoot);
83
+ if (cached)
84
+ return cached;
85
+ for (const dir of ["node_modules", "pantry"]) {
86
+ const candidate = join(projectRoot, dir, "@stacksjs", "defaults");
87
+ if (existsSync(join(candidate, "package.json"))) {
88
+ packagedDefaultsRoots.set(projectRoot, candidate);
89
+ return candidate;
90
+ }
91
+ }
92
+ if (cached === null)
93
+ return null;
94
+ let root = null;
95
+ try {
96
+ const resolved = dirname(Bun.resolveSync("@stacksjs/defaults/package.json", projectRoot));
97
+ if (isInstalledDefaultsRoot(resolved))
98
+ root = resolved;
99
+ } catch {}
100
+ packagedDefaultsRoots.set(projectRoot, root);
101
+ return root;
102
+ }
103
+ function usesVendoredDefaults(projectRoot = projectPath()) {
104
+ try {
105
+ return lstatSync(join(projectRoot, "storage", VENDORED_DEFAULTS)).isDirectory();
106
+ } catch {
107
+ return false;
108
+ }
109
+ }
110
+ function linkPackagedDefaults(projectRoot = projectPath()) {
111
+ const link = join(projectRoot, "storage", VENDORED_DEFAULTS);
112
+ let existing;
113
+ try {
114
+ existing = lstatSync(link);
115
+ } catch {}
116
+ if (existing && !existing.isSymbolicLink())
117
+ return false;
118
+ if (existing && existsSync(link))
119
+ return false;
120
+ if (!existsSync(dirname(link)))
121
+ return false;
122
+ const target = packagedDefaultsRoot(projectRoot);
123
+ if (!target)
124
+ return false;
125
+ try {
126
+ if (existing)
127
+ rmSync(link, { force: true });
128
+ symlinkSync(relative(realpathSync(dirname(link)), realpathSync(target)), link, "dir");
129
+ return true;
130
+ } catch {
131
+ return false;
132
+ }
133
+ }
134
+ function frameworkDefaultsRoot(projectRoot = projectPath()) {
135
+ const vendored = join(projectRoot, "storage", VENDORED_DEFAULTS);
136
+ if (usesVendoredDefaults(projectRoot))
137
+ return vendored;
138
+ return packagedDefaultsRoot(projectRoot) ?? vendored;
139
+ }
76
140
  function storagePath(path) {
77
- return projectPath(`storage/${path || ""}`);
141
+ const sub = path || "";
142
+ if (sub === VENDORED_DEFAULTS || sub.startsWith(`${VENDORED_DEFAULTS}/`))
143
+ return resolve(frameworkDefaultsRoot(), `.${sub.slice(VENDORED_DEFAULTS.length)}`);
144
+ return projectPath(`storage/${sub}`);
78
145
  }
79
146
  function frameworkPath(path, options) {
80
147
  const absolutePath = storagePath(`framework/${path || ""}`);
@@ -417,7 +484,7 @@ function installedDefaultsVersion(projectRoot = projectPath()) {
417
484
  return manifestVersion(defaultsPackagePath(projectRoot));
418
485
  }
419
486
  function isInside(child, parent) {
420
- const resolved = realpathSync(child);
487
+ const resolved = realpathSync2(child);
421
488
  return resolved === parent || resolved.startsWith(`${parent}${sep2}`);
422
489
  }
423
490
  function inspectDefaultsProvenance(projectRoot = projectPath()) {
@@ -425,10 +492,12 @@ function inspectDefaultsProvenance(projectRoot = projectPath()) {
425
492
  const packageRoot = defaultsPackagePath(projectRoot);
426
493
  if (!existsSync3(targetDefaults) || !existsSync3(join2(packageRoot, "package.json")))
427
494
  return notApplicable();
495
+ if (!usesVendoredDefaults(projectRoot))
496
+ return notApplicable();
428
497
  if (existsSync3(join2(projectRoot, "storage/framework/core/buddy/package.json")))
429
498
  return notApplicable();
430
499
  try {
431
- if (!isInside(packageRoot, join2(realpathSync(projectRoot), "node_modules")))
500
+ if (!isInside(packageRoot, join2(realpathSync2(projectRoot), "node_modules")))
432
501
  return notApplicable();
433
502
  } catch {
434
503
  return notApplicable();
@@ -607,12 +676,12 @@ function mergeDirectoryInto(from, to) {
607
676
  renameSync(source, destination);
608
677
  continue;
609
678
  }
610
- if (lstatSync(source).isDirectory() && lstatSync(destination).isDirectory()) {
679
+ if (lstatSync2(source).isDirectory() && lstatSync2(destination).isDirectory()) {
611
680
  mergeDirectoryInto(source, destination);
612
- rmSync(source, { recursive: true, force: true });
681
+ rmSync2(source, { recursive: true, force: true });
613
682
  continue;
614
683
  }
615
- rmSync(source, { recursive: true, force: true });
684
+ rmSync2(source, { recursive: true, force: true });
616
685
  }
617
686
  }
618
687
  function ensureRuntimeDirectories() {
@@ -621,14 +690,14 @@ function ensureRuntimeDirectories() {
621
690
  const legacyPath = projectPath(legacy);
622
691
  const targetPath = target();
623
692
  try {
624
- const stats = lstatSync(legacyPath, { throwIfNoEntry: false });
693
+ const stats = lstatSync2(legacyPath, { throwIfNoEntry: false });
625
694
  if (!stats) {
626
695
  results.push({ legacy: legacyPath, target: targetPath, cleared: true });
627
696
  continue;
628
697
  }
629
698
  mkdirSync(targetPath, { recursive: true });
630
699
  if (stats.isSymbolicLink()) {
631
- const pointsAtTarget = resolve3(dirname(legacyPath), readlinkSync(legacyPath)) === resolve3(targetPath);
700
+ const pointsAtTarget = resolve3(dirname2(legacyPath), readlinkSync(legacyPath)) === resolve3(targetPath);
632
701
  if (!pointsAtTarget) {
633
702
  results.push({ legacy: legacyPath, target: targetPath, cleared: false });
634
703
  continue;
@@ -636,9 +705,9 @@ function ensureRuntimeDirectories() {
636
705
  unlinkSync(legacyPath);
637
706
  } else if (stats.isDirectory()) {
638
707
  mergeDirectoryInto(legacyPath, targetPath);
639
- rmSync(legacyPath, { recursive: true, force: true });
708
+ rmSync2(legacyPath, { recursive: true, force: true });
640
709
  } else {
641
- rmSync(legacyPath, { force: true });
710
+ rmSync2(legacyPath, { force: true });
642
711
  }
643
712
  results.push({ legacy: legacyPath, target: targetPath, cleared: true });
644
713
  } catch {
@@ -714,6 +783,8 @@ var path = {
714
783
  frameworkPath,
715
784
  browserPath,
716
785
  storagePath,
786
+ frameworkDefaultsRoot,
787
+ usesVendoredDefaults,
717
788
  functionsPath,
718
789
  gitPath,
719
790
  langPath,
@@ -794,7 +865,7 @@ var path = {
794
865
  homeDir,
795
866
  basename,
796
867
  delimiter: () => delimiter,
797
- dirname,
868
+ dirname: dirname2,
798
869
  extname,
799
870
  isAbsolute: isAbsolute2,
800
871
  join: join2,
@@ -846,7 +917,7 @@ export {
846
917
  delimiter,
847
918
  desktopPath,
848
919
  developmentPath,
849
- dirname,
920
+ dirname2 as dirname,
850
921
  dnsPath,
851
922
  docsPath,
852
923
  emailPath,
@@ -862,6 +933,7 @@ export {
862
933
  featuresPath,
863
934
  findProjectPath,
864
935
  frameworkCloudPath,
936
+ frameworkDefaultsRoot,
865
937
  frameworkPath,
866
938
  frameworkRuntimePath,
867
939
  functionsPath,
@@ -872,6 +944,7 @@ export {
872
944
  installedDefaultsVersion,
873
945
  isAbsolute2 as isAbsolute,
874
946
  isCompiledBinary,
947
+ isInstalledDefaultsRoot,
875
948
  jobsPath,
876
949
  join2 as join,
877
950
  langPath,
@@ -879,6 +952,7 @@ export {
879
952
  libraryPackagePath,
880
953
  libsEntriesPath,
881
954
  libsPath,
955
+ linkPackagedDefaults,
882
956
  lintPath,
883
957
  listenersPath,
884
958
  loggingPath,
@@ -893,6 +967,7 @@ export {
893
967
  objectsPath,
894
968
  onboardingPath,
895
969
  ormPath,
970
+ packagedDefaultsRoot,
896
971
  paginationPath,
897
972
  path,
898
973
  pathPath,
@@ -959,6 +1034,7 @@ export {
959
1034
  userNotificationsPath,
960
1035
  userServerPath,
961
1036
  userViewsPath,
1037
+ usesVendoredDefaults,
962
1038
  utilsPath,
963
1039
  validationPath,
964
1040
  viewsPath
package/dist/project.d.ts CHANGED
@@ -2,5 +2,69 @@ import { relative } from 'node:path';
2
2
  export declare function isCompiledBinary(main?: string | undefined): boolean;
3
3
  export declare function projectPath(filePath?: string, options?: { relative: boolean }): string;
4
4
  export declare function appPath(path?: string, options?: { relative?: boolean, cwd?: string }): string;
5
+ /**
6
+ * Whether a resolved `@stacksjs/defaults` is a copy the project installed.
7
+ *
8
+ * With none installed, Bun answers from its own auto-install cache
9
+ * (`~/.bun/install/cache/@stacksjs/defaults@x@@@1`, or
10
+ * `<repo>/pantry/install/cache/...` on CI): a release nobody declared. A test
11
+ * running in a temp directory then loaded that release's models.
12
+ */
13
+ export declare function isInstalledDefaultsRoot(path: string): boolean;
14
+ /**
15
+ * Where the installed `@stacksjs/defaults` lives for a project, or null when
16
+ * it is not installed. Resolved through `package.json` because the package
17
+ * publishes no `.` export, and memoised per project root once found: it
18
+ * cannot move without a reinstall, and this sits under every `storagePath()`
19
+ * call that names the defaults tree.
20
+ */
21
+ export declare function packagedDefaultsRoot(projectRoot?: string): string | null;
22
+ /**
23
+ * Whether this project keeps its own copy of the framework defaults in
24
+ * `storage/framework/defaults`: a real directory, not the link
25
+ * {@link linkPackagedDefaults} makes.
26
+ *
27
+ * A framework checkout always does (it is the source the package is built
28
+ * from), and so does an app created before the defaults moved into
29
+ * `node_modules`, or with `buddy new --vendor-defaults`. A new app does not:
30
+ * the 2,600-odd files are identical to the installed `@stacksjs/defaults`, so
31
+ * committing them only gave every project a copy to drift.
32
+ */
33
+ export declare function usesVendoredDefaults(projectRoot?: string): boolean;
34
+ /**
35
+ * Point `storage/framework/defaults` at the installed `@stacksjs/defaults`
36
+ * when the project does not vendor the tree.
37
+ *
38
+ * The link is gitignored, so it costs the repository nothing, and it keeps
39
+ * every path that names the tree directly working: a `~/storage/framework/
40
+ * defaults/...` import in an app's own template, an editor jumping to a
41
+ * default action, a tool that globs the views. `storagePath()` already falls
42
+ * back to the package without it; the link is for everything that does not
43
+ * ask `@stacksjs/path`.
44
+ *
45
+ * Idempotent and cheap (one lstat when the link is in place), so boot calls it.
46
+ * A vendored directory is never touched. A dangling link, left behind when
47
+ * `node_modules` moved, is replaced. Returns whether a link was written.
48
+ */
49
+ export declare function linkPackagedDefaults(projectRoot?: string): boolean;
50
+ /**
51
+ * The framework defaults tree this project runs: the vendored
52
+ * `storage/framework/defaults` when it is a real directory, otherwise the
53
+ * installed `@stacksjs/defaults` package. The vendored path is returned when
54
+ * neither exists, so a caller reports the path it has always reported.
55
+ *
56
+ * The package's own path even when the link to it is in place. The link is for
57
+ * people and tools; boot creates it, and a module resolved through a link made
58
+ * after the process started fails in Bun, whose resolver has already cached the
59
+ * directory as missing (`Unexpected while resolving package`, for every
60
+ * default model on a fresh clone's first boot).
61
+ */
62
+ export declare function frameworkDefaultsRoot(projectRoot?: string): string;
63
+ /**
64
+ * `storage/<path>`, except that `framework/defaults/...` follows
65
+ * {@link frameworkDefaultsRoot}. Every caller that names a default model,
66
+ * action, view or route through here (and through `frameworkPath`) therefore
67
+ * works the same whether the app vendors the tree or not.
68
+ */
5
69
  export declare function storagePath(path?: string): string;
6
70
  export declare function frameworkPath(path?: string, options?: { relative?: boolean, cwd?: string }): string;
package/dist/project.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // src/project.ts
3
- import { existsSync } from "fs";
4
- import { join, relative, resolve, sep } from "path";
3
+ import { existsSync, lstatSync, realpathSync, rmSync, symlinkSync } from "fs";
4
+ import { dirname, join, relative, resolve, sep } from "path";
5
5
  import process from "process";
6
6
  var cachedCwd;
7
7
  var cachedProjectRoot = "";
@@ -43,8 +43,75 @@ function appPath(path, options) {
43
43
  return relative(options.cwd || process.cwd(), absolutePath);
44
44
  return absolutePath;
45
45
  }
46
+ var VENDORED_DEFAULTS = "framework/defaults";
47
+ var packagedDefaultsRoots = new Map;
48
+ function isInstalledDefaultsRoot(path) {
49
+ return /[/\\]@stacksjs[/\\]defaults$/.test(path) && !/[/\\]install[/\\]cache[/\\]/.test(path);
50
+ }
51
+ function packagedDefaultsRoot(projectRoot = projectPath()) {
52
+ const cached = packagedDefaultsRoots.get(projectRoot);
53
+ if (cached)
54
+ return cached;
55
+ for (const dir of ["node_modules", "pantry"]) {
56
+ const candidate = join(projectRoot, dir, "@stacksjs", "defaults");
57
+ if (existsSync(join(candidate, "package.json"))) {
58
+ packagedDefaultsRoots.set(projectRoot, candidate);
59
+ return candidate;
60
+ }
61
+ }
62
+ if (cached === null)
63
+ return null;
64
+ let root = null;
65
+ try {
66
+ const resolved = dirname(Bun.resolveSync("@stacksjs/defaults/package.json", projectRoot));
67
+ if (isInstalledDefaultsRoot(resolved))
68
+ root = resolved;
69
+ } catch {}
70
+ packagedDefaultsRoots.set(projectRoot, root);
71
+ return root;
72
+ }
73
+ function usesVendoredDefaults(projectRoot = projectPath()) {
74
+ try {
75
+ return lstatSync(join(projectRoot, "storage", VENDORED_DEFAULTS)).isDirectory();
76
+ } catch {
77
+ return false;
78
+ }
79
+ }
80
+ function linkPackagedDefaults(projectRoot = projectPath()) {
81
+ const link = join(projectRoot, "storage", VENDORED_DEFAULTS);
82
+ let existing;
83
+ try {
84
+ existing = lstatSync(link);
85
+ } catch {}
86
+ if (existing && !existing.isSymbolicLink())
87
+ return false;
88
+ if (existing && existsSync(link))
89
+ return false;
90
+ if (!existsSync(dirname(link)))
91
+ return false;
92
+ const target = packagedDefaultsRoot(projectRoot);
93
+ if (!target)
94
+ return false;
95
+ try {
96
+ if (existing)
97
+ rmSync(link, { force: true });
98
+ symlinkSync(relative(realpathSync(dirname(link)), realpathSync(target)), link, "dir");
99
+ return true;
100
+ } catch {
101
+ return false;
102
+ }
103
+ }
104
+ function frameworkDefaultsRoot(projectRoot = projectPath()) {
105
+ const vendored = join(projectRoot, "storage", VENDORED_DEFAULTS);
106
+ if (usesVendoredDefaults(projectRoot))
107
+ return vendored;
108
+ return packagedDefaultsRoot(projectRoot) ?? vendored;
109
+ }
46
110
  function storagePath(path) {
47
- return projectPath(`storage/${path || ""}`);
111
+ const sub = path || "";
112
+ if (sub === VENDORED_DEFAULTS || sub.startsWith(`${VENDORED_DEFAULTS}/`))
113
+ return resolve(frameworkDefaultsRoot(), `.${sub.slice(VENDORED_DEFAULTS.length)}`);
114
+ return projectPath(`storage/${sub}`);
48
115
  }
49
116
  function frameworkPath(path, options) {
50
117
  const absolutePath = storagePath(`framework/${path || ""}`);
@@ -54,8 +121,13 @@ function frameworkPath(path, options) {
54
121
  }
55
122
  export {
56
123
  appPath,
124
+ frameworkDefaultsRoot,
57
125
  frameworkPath,
58
126
  isCompiledBinary,
127
+ isInstalledDefaultsRoot,
128
+ linkPackagedDefaults,
129
+ packagedDefaultsRoot,
59
130
  projectPath,
60
- storagePath
131
+ storagePath,
132
+ usesVendoredDefaults
61
133
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/path",
3
3
  "type": "module",
4
- "version": "0.75.244",
4
+ "version": "0.75.246",
5
5
  "description": "The Stacks path.",
6
6
  "author": "Chris Breuer",
7
7
  "contributors": [