@stacksjs/path 0.75.244 → 0.75.245

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, 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,63 @@ 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 packagedDefaultsRoot(projectRoot = projectPath()) {
79
+ const cached = packagedDefaultsRoots.get(projectRoot);
80
+ if (cached !== undefined)
81
+ return cached;
82
+ let root = null;
83
+ try {
84
+ const resolved = dirname(Bun.resolveSync("@stacksjs/defaults/package.json", projectRoot));
85
+ if (/[/\\](?:node_modules|pantry)[/\\]/.test(resolved))
86
+ root = resolved;
87
+ } catch {}
88
+ packagedDefaultsRoots.set(projectRoot, root);
89
+ return root;
90
+ }
91
+ function usesVendoredDefaults(projectRoot = projectPath()) {
92
+ try {
93
+ return lstatSync(join(projectRoot, "storage", VENDORED_DEFAULTS)).isDirectory();
94
+ } catch {
95
+ return false;
96
+ }
97
+ }
98
+ function linkPackagedDefaults(projectRoot = projectPath()) {
99
+ const link = join(projectRoot, "storage", VENDORED_DEFAULTS);
100
+ let existing;
101
+ try {
102
+ existing = lstatSync(link);
103
+ } catch {}
104
+ if (existing && !existing.isSymbolicLink())
105
+ return false;
106
+ if (existing && existsSync(link))
107
+ return false;
108
+ if (!existsSync(dirname(link)))
109
+ return false;
110
+ const target = packagedDefaultsRoot(projectRoot);
111
+ if (!target)
112
+ return false;
113
+ try {
114
+ if (existing)
115
+ rmSync(link, { force: true });
116
+ symlinkSync(relative(realpathSync(dirname(link)), realpathSync(target)), link, "dir");
117
+ return true;
118
+ } catch {
119
+ return false;
120
+ }
121
+ }
122
+ function frameworkDefaultsRoot(projectRoot = projectPath()) {
123
+ const vendored = join(projectRoot, "storage", VENDORED_DEFAULTS);
124
+ if (usesVendoredDefaults(projectRoot))
125
+ return vendored;
126
+ return packagedDefaultsRoot(projectRoot) ?? vendored;
127
+ }
76
128
  function storagePath(path) {
77
- return projectPath(`storage/${path || ""}`);
129
+ const sub = path || "";
130
+ if (sub === VENDORED_DEFAULTS || sub.startsWith(`${VENDORED_DEFAULTS}/`))
131
+ return resolve(frameworkDefaultsRoot(), `.${sub.slice(VENDORED_DEFAULTS.length)}`);
132
+ return projectPath(`storage/${sub}`);
78
133
  }
79
134
  function frameworkPath(path, options) {
80
135
  const absolutePath = storagePath(`framework/${path || ""}`);
@@ -417,7 +472,7 @@ function installedDefaultsVersion(projectRoot = projectPath()) {
417
472
  return manifestVersion(defaultsPackagePath(projectRoot));
418
473
  }
419
474
  function isInside(child, parent) {
420
- const resolved = realpathSync(child);
475
+ const resolved = realpathSync2(child);
421
476
  return resolved === parent || resolved.startsWith(`${parent}${sep2}`);
422
477
  }
423
478
  function inspectDefaultsProvenance(projectRoot = projectPath()) {
@@ -425,10 +480,12 @@ function inspectDefaultsProvenance(projectRoot = projectPath()) {
425
480
  const packageRoot = defaultsPackagePath(projectRoot);
426
481
  if (!existsSync3(targetDefaults) || !existsSync3(join2(packageRoot, "package.json")))
427
482
  return notApplicable();
483
+ if (!usesVendoredDefaults(projectRoot))
484
+ return notApplicable();
428
485
  if (existsSync3(join2(projectRoot, "storage/framework/core/buddy/package.json")))
429
486
  return notApplicable();
430
487
  try {
431
- if (!isInside(packageRoot, join2(realpathSync(projectRoot), "node_modules")))
488
+ if (!isInside(packageRoot, join2(realpathSync2(projectRoot), "node_modules")))
432
489
  return notApplicable();
433
490
  } catch {
434
491
  return notApplicable();
@@ -607,12 +664,12 @@ function mergeDirectoryInto(from, to) {
607
664
  renameSync(source, destination);
608
665
  continue;
609
666
  }
610
- if (lstatSync(source).isDirectory() && lstatSync(destination).isDirectory()) {
667
+ if (lstatSync2(source).isDirectory() && lstatSync2(destination).isDirectory()) {
611
668
  mergeDirectoryInto(source, destination);
612
- rmSync(source, { recursive: true, force: true });
669
+ rmSync2(source, { recursive: true, force: true });
613
670
  continue;
614
671
  }
615
- rmSync(source, { recursive: true, force: true });
672
+ rmSync2(source, { recursive: true, force: true });
616
673
  }
617
674
  }
618
675
  function ensureRuntimeDirectories() {
@@ -621,14 +678,14 @@ function ensureRuntimeDirectories() {
621
678
  const legacyPath = projectPath(legacy);
622
679
  const targetPath = target();
623
680
  try {
624
- const stats = lstatSync(legacyPath, { throwIfNoEntry: false });
681
+ const stats = lstatSync2(legacyPath, { throwIfNoEntry: false });
625
682
  if (!stats) {
626
683
  results.push({ legacy: legacyPath, target: targetPath, cleared: true });
627
684
  continue;
628
685
  }
629
686
  mkdirSync(targetPath, { recursive: true });
630
687
  if (stats.isSymbolicLink()) {
631
- const pointsAtTarget = resolve3(dirname(legacyPath), readlinkSync(legacyPath)) === resolve3(targetPath);
688
+ const pointsAtTarget = resolve3(dirname2(legacyPath), readlinkSync(legacyPath)) === resolve3(targetPath);
632
689
  if (!pointsAtTarget) {
633
690
  results.push({ legacy: legacyPath, target: targetPath, cleared: false });
634
691
  continue;
@@ -636,9 +693,9 @@ function ensureRuntimeDirectories() {
636
693
  unlinkSync(legacyPath);
637
694
  } else if (stats.isDirectory()) {
638
695
  mergeDirectoryInto(legacyPath, targetPath);
639
- rmSync(legacyPath, { recursive: true, force: true });
696
+ rmSync2(legacyPath, { recursive: true, force: true });
640
697
  } else {
641
- rmSync(legacyPath, { force: true });
698
+ rmSync2(legacyPath, { force: true });
642
699
  }
643
700
  results.push({ legacy: legacyPath, target: targetPath, cleared: true });
644
701
  } catch {
@@ -714,6 +771,8 @@ var path = {
714
771
  frameworkPath,
715
772
  browserPath,
716
773
  storagePath,
774
+ frameworkDefaultsRoot,
775
+ usesVendoredDefaults,
717
776
  functionsPath,
718
777
  gitPath,
719
778
  langPath,
@@ -794,7 +853,7 @@ var path = {
794
853
  homeDir,
795
854
  basename,
796
855
  delimiter: () => delimiter,
797
- dirname,
856
+ dirname: dirname2,
798
857
  extname,
799
858
  isAbsolute: isAbsolute2,
800
859
  join: join2,
@@ -846,7 +905,7 @@ export {
846
905
  delimiter,
847
906
  desktopPath,
848
907
  developmentPath,
849
- dirname,
908
+ dirname2 as dirname,
850
909
  dnsPath,
851
910
  docsPath,
852
911
  emailPath,
@@ -862,6 +921,7 @@ export {
862
921
  featuresPath,
863
922
  findProjectPath,
864
923
  frameworkCloudPath,
924
+ frameworkDefaultsRoot,
865
925
  frameworkPath,
866
926
  frameworkRuntimePath,
867
927
  functionsPath,
@@ -879,6 +939,7 @@ export {
879
939
  libraryPackagePath,
880
940
  libsEntriesPath,
881
941
  libsPath,
942
+ linkPackagedDefaults,
882
943
  lintPath,
883
944
  listenersPath,
884
945
  loggingPath,
@@ -893,6 +954,7 @@ export {
893
954
  objectsPath,
894
955
  onboardingPath,
895
956
  ormPath,
957
+ packagedDefaultsRoot,
896
958
  paginationPath,
897
959
  path,
898
960
  pathPath,
@@ -959,6 +1021,7 @@ export {
959
1021
  userNotificationsPath,
960
1022
  userServerPath,
961
1023
  userViewsPath,
1024
+ usesVendoredDefaults,
962
1025
  utilsPath,
963
1026
  validationPath,
964
1027
  viewsPath
package/dist/project.d.ts CHANGED
@@ -2,5 +2,60 @@ 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
+ * Where the installed `@stacksjs/defaults` lives for a project, or null when
7
+ * it is not installed. Resolved through `package.json` because the package
8
+ * publishes no `.` export, and memoised per project root: it cannot move
9
+ * without a reinstall, and this sits under every `storagePath()` call that
10
+ * names the defaults tree.
11
+ */
12
+ export declare function packagedDefaultsRoot(projectRoot?: string): string | null;
13
+ /**
14
+ * Whether this project keeps its own copy of the framework defaults in
15
+ * `storage/framework/defaults`: a real directory, not the link
16
+ * {@link linkPackagedDefaults} makes.
17
+ *
18
+ * A framework checkout always does (it is the source the package is built
19
+ * from), and so does an app created before the defaults moved into
20
+ * `node_modules`, or with `buddy new --vendor-defaults`. A new app does not:
21
+ * the 2,600-odd files are identical to the installed `@stacksjs/defaults`, so
22
+ * committing them only gave every project a copy to drift.
23
+ */
24
+ export declare function usesVendoredDefaults(projectRoot?: string): boolean;
25
+ /**
26
+ * Point `storage/framework/defaults` at the installed `@stacksjs/defaults`
27
+ * when the project does not vendor the tree.
28
+ *
29
+ * The link is gitignored, so it costs the repository nothing, and it keeps
30
+ * every path that names the tree directly working: a `~/storage/framework/
31
+ * defaults/...` import in an app's own template, an editor jumping to a
32
+ * default action, a tool that globs the views. `storagePath()` already falls
33
+ * back to the package without it; the link is for everything that does not
34
+ * ask `@stacksjs/path`.
35
+ *
36
+ * Idempotent and cheap (one lstat when the link is in place), so boot calls it.
37
+ * A vendored directory is never touched. A dangling link, left behind when
38
+ * `node_modules` moved, is replaced. Returns whether a link was written.
39
+ */
40
+ export declare function linkPackagedDefaults(projectRoot?: string): boolean;
41
+ /**
42
+ * The framework defaults tree this project runs: the vendored
43
+ * `storage/framework/defaults` when it is a real directory, otherwise the
44
+ * installed `@stacksjs/defaults` package. The vendored path is returned when
45
+ * neither exists, so a caller reports the path it has always reported.
46
+ *
47
+ * The package's own path even when the link to it is in place. The link is for
48
+ * people and tools; boot creates it, and a module resolved through a link made
49
+ * after the process started fails in Bun, whose resolver has already cached the
50
+ * directory as missing (`Unexpected while resolving package`, for every
51
+ * default model on a fresh clone's first boot).
52
+ */
53
+ export declare function frameworkDefaultsRoot(projectRoot?: string): string;
54
+ /**
55
+ * `storage/<path>`, except that `framework/defaults/...` follows
56
+ * {@link frameworkDefaultsRoot}. Every caller that names a default model,
57
+ * action, view or route through here (and through `frameworkPath`) therefore
58
+ * works the same whether the app vendors the tree or not.
59
+ */
5
60
  export declare function storagePath(path?: string): string;
6
61
  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,63 @@ 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 packagedDefaultsRoot(projectRoot = projectPath()) {
49
+ const cached = packagedDefaultsRoots.get(projectRoot);
50
+ if (cached !== undefined)
51
+ return cached;
52
+ let root = null;
53
+ try {
54
+ const resolved = dirname(Bun.resolveSync("@stacksjs/defaults/package.json", projectRoot));
55
+ if (/[/\\](?:node_modules|pantry)[/\\]/.test(resolved))
56
+ root = resolved;
57
+ } catch {}
58
+ packagedDefaultsRoots.set(projectRoot, root);
59
+ return root;
60
+ }
61
+ function usesVendoredDefaults(projectRoot = projectPath()) {
62
+ try {
63
+ return lstatSync(join(projectRoot, "storage", VENDORED_DEFAULTS)).isDirectory();
64
+ } catch {
65
+ return false;
66
+ }
67
+ }
68
+ function linkPackagedDefaults(projectRoot = projectPath()) {
69
+ const link = join(projectRoot, "storage", VENDORED_DEFAULTS);
70
+ let existing;
71
+ try {
72
+ existing = lstatSync(link);
73
+ } catch {}
74
+ if (existing && !existing.isSymbolicLink())
75
+ return false;
76
+ if (existing && existsSync(link))
77
+ return false;
78
+ if (!existsSync(dirname(link)))
79
+ return false;
80
+ const target = packagedDefaultsRoot(projectRoot);
81
+ if (!target)
82
+ return false;
83
+ try {
84
+ if (existing)
85
+ rmSync(link, { force: true });
86
+ symlinkSync(relative(realpathSync(dirname(link)), realpathSync(target)), link, "dir");
87
+ return true;
88
+ } catch {
89
+ return false;
90
+ }
91
+ }
92
+ function frameworkDefaultsRoot(projectRoot = projectPath()) {
93
+ const vendored = join(projectRoot, "storage", VENDORED_DEFAULTS);
94
+ if (usesVendoredDefaults(projectRoot))
95
+ return vendored;
96
+ return packagedDefaultsRoot(projectRoot) ?? vendored;
97
+ }
46
98
  function storagePath(path) {
47
- return projectPath(`storage/${path || ""}`);
99
+ const sub = path || "";
100
+ if (sub === VENDORED_DEFAULTS || sub.startsWith(`${VENDORED_DEFAULTS}/`))
101
+ return resolve(frameworkDefaultsRoot(), `.${sub.slice(VENDORED_DEFAULTS.length)}`);
102
+ return projectPath(`storage/${sub}`);
48
103
  }
49
104
  function frameworkPath(path, options) {
50
105
  const absolutePath = storagePath(`framework/${path || ""}`);
@@ -54,8 +109,12 @@ function frameworkPath(path, options) {
54
109
  }
55
110
  export {
56
111
  appPath,
112
+ frameworkDefaultsRoot,
57
113
  frameworkPath,
58
114
  isCompiledBinary,
115
+ linkPackagedDefaults,
116
+ packagedDefaultsRoot,
59
117
  projectPath,
60
- storagePath
118
+ storagePath,
119
+ usesVendoredDefaults
61
120
  };
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.245",
5
5
  "description": "The Stacks path.",
6
6
  "author": "Chris Breuer",
7
7
  "contributors": [