@_linked/cli 1.39.0 → 1.40.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +73 -9
  3. package/defaults/app-react-native/apps/mobile/package.json +4 -4
  4. package/defaults/app-react-native/docker-compose.yml +1 -1
  5. package/defaults/app-react-native/packages/app-shapes/package.json +2 -2
  6. package/defaults/app-react-native/services/api/package.json +7 -7
  7. package/lib/esm/cli.js +1 -0
  8. package/lib/esm/cli.js.map +1 -1
  9. package/lib/esm/commands/build-package.d.ts +1 -1
  10. package/lib/esm/commands/build-package.d.ts.map +1 -1
  11. package/lib/esm/commands/build-package.js +3 -2
  12. package/lib/esm/commands/build-package.js.map +1 -1
  13. package/lib/esm/commands/localize.d.ts +19 -0
  14. package/lib/esm/commands/localize.d.ts.map +1 -1
  15. package/lib/esm/commands/localize.js +36 -10
  16. package/lib/esm/commands/localize.js.map +1 -1
  17. package/lib/esm/installed-packages.d.ts +45 -5
  18. package/lib/esm/installed-packages.d.ts.map +1 -1
  19. package/lib/esm/installed-packages.js +90 -5
  20. package/lib/esm/installed-packages.js.map +1 -1
  21. package/lib/esm/lifecycle.d.ts +1 -1
  22. package/lib/esm/lifecycle.d.ts.map +1 -1
  23. package/lib/esm/lifecycle.js +4 -5
  24. package/lib/esm/lifecycle.js.map +1 -1
  25. package/lib/esm/localized-dedupe.d.ts +20 -0
  26. package/lib/esm/localized-dedupe.d.ts.map +1 -0
  27. package/lib/esm/localized-dedupe.js +182 -0
  28. package/lib/esm/localized-dedupe.js.map +1 -0
  29. package/lib/esm/utils.d.ts.map +1 -1
  30. package/lib/esm/utils.js +2 -1
  31. package/lib/esm/utils.js.map +1 -1
  32. package/lib/esm/vite-config.d.ts +8 -0
  33. package/lib/esm/vite-config.d.ts.map +1 -1
  34. package/lib/esm/vite-config.js +67 -48
  35. package/lib/esm/vite-config.js.map +1 -1
  36. package/package.json +3 -8
@@ -1 +1 @@
1
- {"version":3,"file":"localize.js","sourceRoot":"","sources":["../../../src/commands/localize.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `linked localize` / `linked delocalize` — develop an npm dependency from a\n * git checkout.\n *\n * All of the work lives in `@_linked/localize`, which is dependency-free and\n * knows nothing about this framework on purpose: it resolves a package's\n * repository from the registry, clones it, installs inside the checkout and\n * symlinks it into `node_modules`, without touching `package.json` or\n * `package-lock.json`.\n *\n * The one thing it deliberately does not know is how to build what it cloned.\n * That is the seam this module fills: `@_linked/cli` passes `build: 'linked\n * build'`, because in this ecosystem that is what building a package means.\n * A failing build only warns — a package whose build is broken is usually\n * exactly what you localized it to fix.\n *\n * Packages are named exactly as npm names them (`@_linked/rdfs`, `lodash`).\n * There is no short-name expansion and no org probing: the repository comes\n * from the registry's `repository` field, so a name that npm cannot resolve is\n * an error rather than a guess.\n *\n * `--adopt` is the exception to \"clone from the registry\": it links a git\n * checkout that is already in `packages-local/` under its localize name, with\n * no clone and no lookup — a package created locally, or a clone put there by\n * hand. It takes no `--subdir`: an adopted checkout is the package itself.\n */\nimport process from 'node:process';\n\n/** The build command `localize` runs inside a fresh checkout by default. */\nexport const DEFAULT_BUILD_COMMAND = 'linked build';\n\nexport interface LocalizeCommandOptions {\n adopt?: boolean;\n list?: boolean;\n check?: boolean;\n relink?: boolean;\n dir?: string;\n repo?: string;\n subdir?: string;\n build?: string;\n force?: boolean;\n purge?: boolean;\n}\n\n/**\n * `localize` reports failure through an exit code rather than by throwing, so\n * that a partial run still prints what it did. Mirror that: set `exitCode` and\n * return, instead of exiting, so pending output is flushed.\n */\nexport async function runLocalize(\n packages: string[] = [],\n options: LocalizeCommandOptions = {},\n): Promise<void> {\n const {defaultDeps, localize, adopt, list, relink} =\n await import('@_linked/localize');\n const deps = defaultDeps(process.cwd());\n\n if (options.relink) {\n process.exitCode = relink(deps);\n return;\n }\n if (options.adopt && packages.length === 0) {\n console.error('[localize] --adopt needs at least one package name.');\n process.exitCode = 2;\n return;\n }\n if (options.adopt && options.subdir) {\n console.error(\n '[localize] --adopt takes no --subdir: an adopted checkout is the package itself.',\n );\n process.exitCode = 2;\n return;\n }\n if (options.list || packages.length === 0) {\n process.exitCode = list({check: options.check}, deps);\n return;\n }\n // `--build ''` is how you ask for no build at all.\n const build =\n options.build === undefined ? DEFAULT_BUILD_COMMAND : options.build;\n if (options.adopt) {\n process.exitCode = adopt(\n packages,\n {force: options.force, dir: options.dir, repo: options.repo, build},\n deps,\n );\n return;\n }\n process.exitCode = localize(\n packages,\n {\n force: options.force,\n dir: options.dir,\n repo: options.repo,\n subdir: options.subdir,\n build,\n },\n deps,\n );\n}\n\n/**\n * Adopt one checkout that already sits in `packages-local/` under its localize\n * name: install inside it, build it, link it and record it. This is how\n * `create-package` hands a new package with its own repository to localize.\n *\n * @returns localize's exit code, rather than setting `process.exitCode`, so the\n * caller decides what a failure means.\n */\nexport async function adoptPackage(\n name: string,\n options: {appRoot: string; build: string; repo?: string},\n): Promise<number> {\n const {defaultDeps, adopt} = await import('@_linked/localize');\n // Exit codes are localize's public contract; EXIT_WARNED (5) is the one a\n // caller usually tolerates, meaning the build failed but the link is in place.\n return adopt(\n [name],\n {build: options.build, repo: options.repo},\n defaultDeps(options.appRoot),\n );\n}\n\n/** `linked delocalize [packages...]` — unlink and forget; no names means all. */\nexport async function runDelocalize(\n packages: string[] = [],\n options: Pick<LocalizeCommandOptions, 'purge' | 'force'> = {},\n): Promise<void> {\n const {defaultDeps, delocalize} = await import('@_linked/localize');\n const deps = defaultDeps(process.cwd());\n process.exitCode = delocalize(\n packages,\n {purge: options.purge, force: options.force},\n deps,\n );\n}\n"]}
1
+ {"version":3,"file":"localize.js","sourceRoot":"","sources":["../../../src/commands/localize.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `linked localize` / `linked delocalize` — develop an npm dependency from a\n * git checkout.\n *\n * All of the work lives in `@_linked/localize`, which is dependency-free and\n * knows nothing about this framework on purpose: it resolves a package's\n * repository from the registry, clones it, installs inside the checkout and\n * symlinks it into `node_modules`, without touching `package.json` or\n * `package-lock.json`.\n *\n * The one thing it deliberately does not know is how to build what it cloned.\n * That is the seam this module fills: `@_linked/cli` passes `build: 'linked\n * build'`, because in this ecosystem that is what building a package means.\n * A failing build only warns — a package whose build is broken is usually\n * exactly what you localized it to fix.\n *\n * Packages are named exactly as npm names them (`@_linked/rdfs`, `lodash`).\n * There is no short-name expansion and no org probing: the repository comes\n * from the registry's `repository` field, so a name that npm cannot resolve is\n * an error rather than a guess.\n *\n * The other framework knowledge it supplies is what an app PROVIDES. A\n * checkout's own install leaves its own copies of `@_linked/core`, React and\n * any localized sibling in its `node_modules`, and Node loads those instead of\n * the app's: a localized package then never sees a localized sibling, and core\n * loads once per copy. localize removes those copies by default wherever the\n * app's version satisfies the checkout's range (`--no-prune` turns it off);\n * this CLI tells localize what the app provides: `providedByApp`.\n *\n * `--adopt` is the exception to \"clone from the registry\": it links a git\n * checkout that is already in `packages-local/` under its localize name, with\n * no clone and no lookup — a package created locally, or a clone put there by\n * hand. It takes no `--subdir`: an adopted checkout is the package itself.\n */\nimport process from 'node:process';\n\n/** The build command `localize` runs inside a fresh checkout by default. */\nexport const DEFAULT_BUILD_COMMAND = 'linked build';\n\n/**\n * What a linked app provides to its localized checkouts: the names of the\n * linked packages it has installed — by their `linkedPackage` flag, whatever\n * their scope — plus `react` and `react-dom`. Each one either holds\n * module-level state that must exist once (core's shape registry, React's\n * dispatcher, the context objects in server-utils and react) or is a localized\n * sibling the checkout should reach live (see `appProvidedPackages`). localize\n * itself already treats every localized sibling and a checkout's\n * peerDependencies as provided. Vite's `resolve.dedupe` is derived separately,\n * from what is localized (`localized-dedupe.ts`).\n */\nexport async function providedByApp(appRoot: string): Promise<string[]> {\n const {appProvidedPackages} = await import('../installed-packages.js');\n return appProvidedPackages(appRoot);\n}\n\nexport interface LocalizeCommandOptions {\n adopt?: boolean;\n list?: boolean;\n check?: boolean;\n relink?: boolean;\n dir?: string;\n repo?: string;\n subdir?: string;\n build?: string;\n force?: boolean;\n purge?: boolean;\n /** Commander's `--no-prune` sets this to false; absent means on. */\n prune?: boolean;\n}\n\n/** localize's prune options for a run: on unless explicitly turned off. */\nexport async function pruneOptions(\n appRoot: string,\n prune: boolean | undefined = true,\n): Promise<{prune: boolean; provided: string[]}> {\n return {prune: prune !== false, provided: await providedByApp(appRoot)};\n}\n\n/**\n * `localize` reports failure through an exit code rather than by throwing, so\n * that a partial run still prints what it did. Mirror that: set `exitCode` and\n * return, instead of exiting, so pending output is flushed.\n */\nexport async function runLocalize(\n packages: string[] = [],\n options: LocalizeCommandOptions = {},\n): Promise<void> {\n const {defaultDeps, localize, adopt, list, relink} =\n await import('@_linked/localize');\n const deps = defaultDeps(process.cwd());\n const prune = await pruneOptions(process.cwd(), options.prune);\n\n if (options.relink) {\n process.exitCode = relink(deps, prune);\n return;\n }\n if (options.adopt && packages.length === 0) {\n console.error('[localize] --adopt needs at least one package name.');\n process.exitCode = 2;\n return;\n }\n if (options.adopt && options.subdir) {\n console.error(\n '[localize] --adopt takes no --subdir: an adopted checkout is the package itself.',\n );\n process.exitCode = 2;\n return;\n }\n if (options.list || packages.length === 0) {\n process.exitCode = list({check: options.check}, deps);\n return;\n }\n // `--build ''` is how you ask for no build at all.\n const build =\n options.build === undefined ? DEFAULT_BUILD_COMMAND : options.build;\n if (options.adopt) {\n process.exitCode = adopt(\n packages,\n {\n force: options.force,\n dir: options.dir,\n repo: options.repo,\n build,\n ...prune,\n },\n deps,\n );\n return;\n }\n process.exitCode = localize(\n packages,\n {\n force: options.force,\n dir: options.dir,\n repo: options.repo,\n subdir: options.subdir,\n build,\n ...prune,\n },\n deps,\n );\n}\n\n/**\n * Adopt one checkout that already sits in `packages-local/` under its localize\n * name: install inside it, build it, link it and record it. This is how\n * `create-package` hands a new package with its own repository to localize.\n *\n * @returns localize's exit code, rather than setting `process.exitCode`, so the\n * caller decides what a failure means.\n */\nexport async function adoptPackage(\n name: string,\n options: {appRoot: string; build: string; repo?: string},\n): Promise<number> {\n const {defaultDeps, adopt} = await import('@_linked/localize');\n // Exit codes are localize's public contract; EXIT_WARNED (5) is the one a\n // caller usually tolerates, meaning the build failed but the link is in place.\n return adopt(\n [name],\n {\n build: options.build,\n repo: options.repo,\n ...(await pruneOptions(options.appRoot)),\n },\n defaultDeps(options.appRoot),\n );\n}\n\n/** `linked delocalize [packages...]` — unlink and forget; no names means all. */\nexport async function runDelocalize(\n packages: string[] = [],\n options: Pick<LocalizeCommandOptions, 'purge' | 'force'> = {},\n): Promise<void> {\n const {defaultDeps, delocalize} = await import('@_linked/localize');\n const deps = defaultDeps(process.cwd());\n process.exitCode = delocalize(\n packages,\n {purge: options.purge, force: options.force},\n deps,\n );\n}\n"]}
@@ -2,11 +2,12 @@
2
2
  * Framework packages that MUST be single-instance per runtime — they hold
3
3
  * module-level state (`@_linked/core`'s shape registry, `LinkedStorage`, the query
4
4
  * context) or register shapes into it. Two copies in one runtime split that state
5
- * and mangle shape identity (`Person`→`Person2`). This ONE list is the single source
6
- * of truth for the standalone `optimizeDeps.exclude` (`linkedDeps`). In workspace mode
7
- * `ssr.noExternal` is keyed on the discovered source workspaces instead (see
8
- * `ssrNoExternal`), so published framework packages stay external and single-instance
9
- * under Node.
5
+ * and mangle shape identity (`Person`→`Person2`).
6
+ *
7
+ * A NAME check, used only by `client-dep-includes` (alongside the flag). Deciding
8
+ * whether an installed package is linked goes by its `package.json` instead —
9
+ * {@link isLinkedPackageJson} — which is what the source walk, the standalone
10
+ * `optimizeDeps.exclude` and `linked localize` use.
10
11
  */
11
12
  export declare const FRAMEWORK_PKG_PATTERNS: RegExp[];
12
13
  export declare const isFrameworkPkg: (name: string) => boolean;
@@ -15,4 +16,43 @@ export declare function readInstalledPkg(name: string, fromDir: string): Promise
15
16
  root: string;
16
17
  json: any;
17
18
  } | null>;
19
+ /**
20
+ * THE definition of a linked package: its own `package.json` says
21
+ * `"linkedPackage": true`. Not its npm scope — a linked package can be
22
+ * published under any scope, and not everything under `@_linked/` is one
23
+ * (`@_linked/localize` is a plain tool). The pre-rename `"lincd": true` is not
24
+ * read: the packages that still carry it are the old `lincd-*` framework,
25
+ * which cannot share a runtime with `@_linked/core`. `lifecycle.ts`
26
+ * (`build-all`, `getLincdPackages`) and `linked build-package` use this too.
27
+ */
28
+ export declare const isLinkedPackageJson: (json: any) => boolean;
29
+ /** An installed linked package, as {@link discoverInstalledLinkedPackages} finds it. */
30
+ export interface InstalledLinkedPackage {
31
+ name: string;
32
+ /** The installed directory, realpathed: a localized checkout's own path. */
33
+ realRoot: string;
34
+ json: any;
35
+ }
36
+ /**
37
+ * Every installed linked package an app depends on: its `dependencies` and
38
+ * `devDependencies`, and recursively the `dependencies` of each linked package
39
+ * found, keeping those {@link isLinkedPackageJson} says are linked.
40
+ *
41
+ * Walked breadth-first and keyed on the installed directory, not the name, so
42
+ * the app's own copy of a package is settled before any copy a dependency
43
+ * installed for itself. A localized checkout's own `node_modules` holds a
44
+ * published copy of any sibling it depends on; keyed on the name and walked
45
+ * depth-first, reaching that copy first hid the app's localized checkout of
46
+ * it. The same name can therefore appear more than once, once per copy.
47
+ */
48
+ export declare function discoverInstalledLinkedPackages(cwd?: string): Promise<InstalledLinkedPackage[]>;
49
+ /**
50
+ * The names of the linked packages an app itself provides: those
51
+ * {@link discoverInstalledLinkedPackages} finds that resolve from the app root
52
+ * (not only from inside some dependency's own `node_modules`), plus `react` and
53
+ * `react-dom` when they do. These are what must load once per runtime: what
54
+ * `linked localize` tells localize the app provides, so a checkout's own copy of
55
+ * one is removed.
56
+ */
57
+ export declare function appProvidedPackages(cwd?: string): Promise<string[]>;
18
58
  //# sourceMappingURL=installed-packages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"installed-packages.d.ts","sourceRoot":"","sources":["../../src/installed-packages.ts"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,EAA+B,CAAC;AAC3E,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,OACM,CAAC;AAUrD,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAC,GAAG,IAAI,CAAC,CAgB3C"}
1
+ {"version":3,"file":"installed-packages.d.ts","sourceRoot":"","sources":["../../src/installed-packages.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,EAA+B,CAAC;AAC3E,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,OACM,CAAC;AAUrD,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,GAAG,CAAA;CAAC,GAAG,IAAI,CAAC,CAgB3C;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,GAAG,KAAG,OAClB,CAAC;AAE/B,wFAAwF;AACxF,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC;CACX;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,+BAA+B,CACnD,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,sBAAsB,EAAE,CAAC,CA+BnC;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,EAAE,CAAC,CAUnB"}
@@ -15,11 +15,12 @@ import path from 'node:path';
15
15
  * Framework packages that MUST be single-instance per runtime — they hold
16
16
  * module-level state (`@_linked/core`'s shape registry, `LinkedStorage`, the query
17
17
  * context) or register shapes into it. Two copies in one runtime split that state
18
- * and mangle shape identity (`Person`→`Person2`). This ONE list is the single source
19
- * of truth for the standalone `optimizeDeps.exclude` (`linkedDeps`). In workspace mode
20
- * `ssr.noExternal` is keyed on the discovered source workspaces instead (see
21
- * `ssrNoExternal`), so published framework packages stay external and single-instance
22
- * under Node.
18
+ * and mangle shape identity (`Person`→`Person2`).
19
+ *
20
+ * A NAME check, used only by `client-dep-includes` (alongside the flag). Deciding
21
+ * whether an installed package is linked goes by its `package.json` instead —
22
+ * {@link isLinkedPackageJson} — which is what the source walk, the standalone
23
+ * `optimizeDeps.exclude` and `linked localize` use.
23
24
  */
24
25
  export const FRAMEWORK_PKG_PATTERNS = [/^@_linked\//, /^lincd-/];
25
26
  export const isFrameworkPkg = (name) => FRAMEWORK_PKG_PATTERNS.some((re) => re.test(name));
@@ -63,4 +64,88 @@ export function readInstalledPkg(name, fromDir) {
63
64
  }
64
65
  });
65
66
  }
67
+ /**
68
+ * THE definition of a linked package: its own `package.json` says
69
+ * `"linkedPackage": true`. Not its npm scope — a linked package can be
70
+ * published under any scope, and not everything under `@_linked/` is one
71
+ * (`@_linked/localize` is a plain tool). The pre-rename `"lincd": true` is not
72
+ * read: the packages that still carry it are the old `lincd-*` framework,
73
+ * which cannot share a runtime with `@_linked/core`. `lifecycle.ts`
74
+ * (`build-all`, `getLincdPackages`) and `linked build-package` use this too.
75
+ */
76
+ export const isLinkedPackageJson = (json) => (json === null || json === void 0 ? void 0 : json.linkedPackage) === true;
77
+ /**
78
+ * Every installed linked package an app depends on: its `dependencies` and
79
+ * `devDependencies`, and recursively the `dependencies` of each linked package
80
+ * found, keeping those {@link isLinkedPackageJson} says are linked.
81
+ *
82
+ * Walked breadth-first and keyed on the installed directory, not the name, so
83
+ * the app's own copy of a package is settled before any copy a dependency
84
+ * installed for itself. A localized checkout's own `node_modules` holds a
85
+ * published copy of any sibling it depends on; keyed on the name and walked
86
+ * depth-first, reaching that copy first hid the app's localized checkout of
87
+ * it. The same name can therefore appear more than once, once per copy.
88
+ */
89
+ export function discoverInstalledLinkedPackages() {
90
+ return __awaiter(this, arguments, void 0, function* (cwd = process.cwd()) {
91
+ const pkgPath = path.join(cwd, 'package.json');
92
+ if (!(yield fsExtra.pathExists(pkgPath)))
93
+ return [];
94
+ const appPkg = yield fsExtra.readJson(pkgPath);
95
+ const out = [];
96
+ const visited = new Set();
97
+ let level = [
98
+ { deps: appPkg.dependencies, fromDir: cwd },
99
+ { deps: appPkg.devDependencies, fromDir: cwd },
100
+ ];
101
+ while (level.length > 0) {
102
+ const next = [];
103
+ for (const { deps, fromDir } of level) {
104
+ for (const name of Object.keys(deps !== null && deps !== void 0 ? deps : {})) {
105
+ const resolved = yield readInstalledPkg(name, fromDir);
106
+ if (!resolved || !isLinkedPackageJson(resolved.json))
107
+ continue;
108
+ let realRoot = resolved.root;
109
+ try {
110
+ realRoot = yield fsExtra.realpath(resolved.root);
111
+ }
112
+ catch (_a) { }
113
+ if (visited.has(realRoot))
114
+ continue;
115
+ visited.add(realRoot);
116
+ out.push({ name, realRoot, json: resolved.json });
117
+ // Recurse from the real location, so a symlinked clone resolves its own
118
+ // dependencies from its source dir.
119
+ next.push({ deps: resolved.json.dependencies, fromDir: realRoot });
120
+ }
121
+ }
122
+ level = next;
123
+ }
124
+ return out;
125
+ });
126
+ }
127
+ /**
128
+ * The names of the linked packages an app itself provides: those
129
+ * {@link discoverInstalledLinkedPackages} finds that resolve from the app root
130
+ * (not only from inside some dependency's own `node_modules`), plus `react` and
131
+ * `react-dom` when they do. These are what must load once per runtime: what
132
+ * `linked localize` tells localize the app provides, so a checkout's own copy of
133
+ * one is removed.
134
+ */
135
+ export function appProvidedPackages() {
136
+ return __awaiter(this, arguments, void 0, function* (cwd = process.cwd()) {
137
+ const names = new Set();
138
+ for (const pkg of yield discoverInstalledLinkedPackages(cwd)) {
139
+ if (names.has(pkg.name))
140
+ continue;
141
+ if (yield readInstalledPkg(pkg.name, cwd))
142
+ names.add(pkg.name);
143
+ }
144
+ for (const name of ['react', 'react-dom']) {
145
+ if (yield readInstalledPkg(name, cwd))
146
+ names.add(name);
147
+ }
148
+ return [...names].sort();
149
+ });
150
+ }
66
151
  //# sourceMappingURL=installed-packages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"installed-packages.js","sourceRoot":"","sources":["../../src/installed-packages.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2EAA2E;AAC3E,kCAAkC;AAClC,OAAO,OAAO,MAAM,UAAU,CAAC;AAC/B,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAa,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAW,EAAE,CACtD,sBAAsB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAErD,6EAA6E;AAC7E,oEAAoE;AACpE,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,4EAA4E;AAC5E,sEAAsE;AACtE,MAAM,UAAgB,eAAe,CAAC,GAAW;;QAC/C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;YACpE,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QAC3B,CAAC;QAAC,WAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CAAA;AAED,MAAM,UAAgB,gBAAgB,CACpC,IAAY,EACZ,OAAe;;QAEf,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;YAChD,IAAI,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,IAAI,CAAC;oBACH,OAAO,EAAC,IAAI,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAC,CAAC;gBACvD,CAAC;gBAAC,WAAM,CAAC;oBACP,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YAChE,GAAG,GAAG,MAAM,CAAC;QACf,CAAC;IACH,CAAC;CAAA","sourcesContent":["// Locating installed packages the way Node does, shared by the Vite config\n// helper and `linked app-doctor`.\nimport fsExtra from 'fs-extra';\nimport path from 'node:path';\n\n/**\n * Framework packages that MUST be single-instance per runtime — they hold\n * module-level state (`@_linked/core`'s shape registry, `LinkedStorage`, the query\n * context) or register shapes into it. Two copies in one runtime split that state\n * and mangle shape identity (`Person`→`Person2`). This ONE list is the single source\n * of truth for the standalone `optimizeDeps.exclude` (`linkedDeps`). In workspace mode\n * `ssr.noExternal` is keyed on the discovered source workspaces instead (see\n * `ssrNoExternal`), so published framework packages stay external and single-instance\n * under Node.\n */\nexport const FRAMEWORK_PKG_PATTERNS: RegExp[] = [/^@_linked\\//, /^lincd-/];\nexport const isFrameworkPkg = (name: string): boolean =>\n FRAMEWORK_PKG_PATTERNS.some((re) => re.test(name));\n\n// Resolve a dependency name to its installed package.json the way Node does:\n// look in `<dir>/node_modules/<name>`, then each parent directory's\n// node_modules, starting from the requiring package's directory. This finds\n// deps that npm/yarn workspaces HOISTED to the monorepo root (an app under\n// `services/api` whose dep lives in `<root>/node_modules`). The walk stops\n// after the nearest directory whose package.json declares `workspaces` (the\n// workspace root), or at the filesystem root. Returns null when the package\n// isn't installed (e.g. an optional dep) — we skip rather than throw.\nexport async function isWorkspaceRoot(dir: string): Promise<boolean> {\n try {\n const json = await fsExtra.readJson(path.join(dir, 'package.json'));\n return !!json.workspaces;\n } catch {\n return false;\n }\n}\n\nexport async function readInstalledPkg(\n name: string,\n fromDir: string,\n): Promise<{root: string; json: any} | null> {\n let dir = path.resolve(fromDir);\n while (true) {\n const root = path.join(dir, 'node_modules', name);\n const pkgJson = path.join(root, 'package.json');\n if (await fsExtra.pathExists(pkgJson)) {\n try {\n return {root, json: await fsExtra.readJson(pkgJson)};\n } catch {\n return null;\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir || (await isWorkspaceRoot(dir))) return null;\n dir = parent;\n }\n}\n"]}
1
+ {"version":3,"file":"installed-packages.js","sourceRoot":"","sources":["../../src/installed-packages.ts"],"names":[],"mappings":"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","sourcesContent":["// Locating installed packages the way Node does, shared by the Vite config\n// helper and `linked app-doctor`.\nimport fsExtra from 'fs-extra';\nimport path from 'node:path';\n\n/**\n * Framework packages that MUST be single-instance per runtime — they hold\n * module-level state (`@_linked/core`'s shape registry, `LinkedStorage`, the query\n * context) or register shapes into it. Two copies in one runtime split that state\n * and mangle shape identity (`Person`→`Person2`).\n *\n * A NAME check, used only by `client-dep-includes` (alongside the flag). Deciding\n * whether an installed package is linked goes by its `package.json` instead —\n * {@link isLinkedPackageJson} — which is what the source walk, the standalone\n * `optimizeDeps.exclude` and `linked localize` use.\n */\nexport const FRAMEWORK_PKG_PATTERNS: RegExp[] = [/^@_linked\\//, /^lincd-/];\nexport const isFrameworkPkg = (name: string): boolean =>\n FRAMEWORK_PKG_PATTERNS.some((re) => re.test(name));\n\n// Resolve a dependency name to its installed package.json the way Node does:\n// look in `<dir>/node_modules/<name>`, then each parent directory's\n// node_modules, starting from the requiring package's directory. This finds\n// deps that npm/yarn workspaces HOISTED to the monorepo root (an app under\n// `services/api` whose dep lives in `<root>/node_modules`). The walk stops\n// after the nearest directory whose package.json declares `workspaces` (the\n// workspace root), or at the filesystem root. Returns null when the package\n// isn't installed (e.g. an optional dep) — we skip rather than throw.\nexport async function isWorkspaceRoot(dir: string): Promise<boolean> {\n try {\n const json = await fsExtra.readJson(path.join(dir, 'package.json'));\n return !!json.workspaces;\n } catch {\n return false;\n }\n}\n\nexport async function readInstalledPkg(\n name: string,\n fromDir: string,\n): Promise<{root: string; json: any} | null> {\n let dir = path.resolve(fromDir);\n while (true) {\n const root = path.join(dir, 'node_modules', name);\n const pkgJson = path.join(root, 'package.json');\n if (await fsExtra.pathExists(pkgJson)) {\n try {\n return {root, json: await fsExtra.readJson(pkgJson)};\n } catch {\n return null;\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir || (await isWorkspaceRoot(dir))) return null;\n dir = parent;\n }\n}\n\n/**\n * THE definition of a linked package: its own `package.json` says\n * `\"linkedPackage\": true`. Not its npm scope — a linked package can be\n * published under any scope, and not everything under `@_linked/` is one\n * (`@_linked/localize` is a plain tool). The pre-rename `\"lincd\": true` is not\n * read: the packages that still carry it are the old `lincd-*` framework,\n * which cannot share a runtime with `@_linked/core`. `lifecycle.ts`\n * (`build-all`, `getLincdPackages`) and `linked build-package` use this too.\n */\nexport const isLinkedPackageJson = (json: any): boolean =>\n json?.linkedPackage === true;\n\n/** An installed linked package, as {@link discoverInstalledLinkedPackages} finds it. */\nexport interface InstalledLinkedPackage {\n name: string;\n /** The installed directory, realpathed: a localized checkout's own path. */\n realRoot: string;\n json: any;\n}\n\n/**\n * Every installed linked package an app depends on: its `dependencies` and\n * `devDependencies`, and recursively the `dependencies` of each linked package\n * found, keeping those {@link isLinkedPackageJson} says are linked.\n *\n * Walked breadth-first and keyed on the installed directory, not the name, so\n * the app's own copy of a package is settled before any copy a dependency\n * installed for itself. A localized checkout's own `node_modules` holds a\n * published copy of any sibling it depends on; keyed on the name and walked\n * depth-first, reaching that copy first hid the app's localized checkout of\n * it. The same name can therefore appear more than once, once per copy.\n */\nexport async function discoverInstalledLinkedPackages(\n cwd: string = process.cwd(),\n): Promise<InstalledLinkedPackage[]> {\n const pkgPath = path.join(cwd, 'package.json');\n if (!(await fsExtra.pathExists(pkgPath))) return [];\n const appPkg = await fsExtra.readJson(pkgPath);\n const out: InstalledLinkedPackage[] = [];\n const visited = new Set<string>();\n let level: {deps: Record<string, string> | undefined; fromDir: string}[] = [\n {deps: appPkg.dependencies, fromDir: cwd},\n {deps: appPkg.devDependencies, fromDir: cwd},\n ];\n while (level.length > 0) {\n const next: typeof level = [];\n for (const {deps, fromDir} of level) {\n for (const name of Object.keys(deps ?? {})) {\n const resolved = await readInstalledPkg(name, fromDir);\n if (!resolved || !isLinkedPackageJson(resolved.json)) continue;\n let realRoot = resolved.root;\n try {\n realRoot = await fsExtra.realpath(resolved.root);\n } catch {}\n if (visited.has(realRoot)) continue;\n visited.add(realRoot);\n out.push({name, realRoot, json: resolved.json});\n // Recurse from the real location, so a symlinked clone resolves its own\n // dependencies from its source dir.\n next.push({deps: resolved.json.dependencies, fromDir: realRoot});\n }\n }\n level = next;\n }\n return out;\n}\n\n/**\n * The names of the linked packages an app itself provides: those\n * {@link discoverInstalledLinkedPackages} finds that resolve from the app root\n * (not only from inside some dependency's own `node_modules`), plus `react` and\n * `react-dom` when they do. These are what must load once per runtime: what\n * `linked localize` tells localize the app provides, so a checkout's own copy of\n * one is removed.\n */\nexport async function appProvidedPackages(\n cwd: string = process.cwd(),\n): Promise<string[]> {\n const names = new Set<string>();\n for (const pkg of await discoverInstalledLinkedPackages(cwd)) {\n if (names.has(pkg.name)) continue;\n if (await readInstalledPkg(pkg.name, cwd)) names.add(pkg.name);\n }\n for (const name of ['react', 'react-dom']) {\n if (await readInstalledPkg(name, cwd)) names.add(name);\n }\n return [...names].sort();\n}\n"]}
@@ -58,7 +58,7 @@ export declare function loadBackendStorageConfig(): Promise<any>;
58
58
  export interface LocalPackage extends PackageDetails {
59
59
  /** Where the walk found it. */
60
60
  source: 'workspace' | 'local-packages-dir';
61
- /** `linkedPackage: true`, or the legacy `lincd: true`. */
61
+ /** `linkedPackage: true` — see `isLinkedPackageJson`. */
62
62
  isLinkedPackage: boolean;
63
63
  /** `linkedApp: true` — built by `linked build-app`, not `linked build`. */
64
64
  isApp: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,uBAAuB,GAClC,mBAAmB,MAAM,EAAE,KAC1B,OAAO,CAAC,IAAI,CA+Bd,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS;IAC7C,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,KAAG,MAAM,EAeT,CAAC;AAgDF;;;;;GAKG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,CAyB7D;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,+BAA+B;IAC/B,MAAM,EAAE,WAAW,GAAG,oBAAoB,CAAC;IAC3C,0DAA0D;IAC1D,eAAe,EAAE,OAAO,CAAC;IACzB,2EAA2E;IAC3E,KAAK,EAAE,OAAO,CAAC;IACf,0EAA0E;IAC1E,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,SAAgB,GACvB,cAAc,EAAE,CAIlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,SAAgB,EACxB,OAAO,GAAE;IAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAM,GAC3E,YAAY,EAAE,CA4BhB;AAyJD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAYnE;AAED,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,QAAQ,SAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAkD5E"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,uBAAuB,GAClC,mBAAmB,MAAM,EAAE,KAC1B,OAAO,CAAC,IAAI,CA+Bd,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS;IAC7C,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,KAAG,MAAM,EAeT,CAAC;AAgDF;;;;;GAKG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,CAyB7D;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,+BAA+B;IAC/B,MAAM,EAAE,WAAW,GAAG,oBAAoB,CAAC;IAC3C,yDAAyD;IACzD,eAAe,EAAE,OAAO,CAAC;IACzB,2EAA2E;IAC3E,KAAK,EAAE,OAAO,CAAC;IACf,0EAA0E;IAC1E,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,SAAgB,GACvB,cAAc,EAAE,CAIlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,SAAgB,EACxB,OAAO,GAAE;IAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAM,GAC3E,YAAY,EAAE,CA4BhB;AAuJD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAYnE;AAED,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACnC,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,QAAQ,SAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAkD5E"}
@@ -18,6 +18,7 @@ import fs from 'fs-extra';
18
18
  import path from 'path';
19
19
  import chalk from 'chalk';
20
20
  import { getPackageJSON } from './utils.js';
21
+ import { isLinkedPackageJson } from './installed-packages.js';
21
22
  import { parseWorkspacePatterns, isWorkspacePathNegated } from './workspace-globs.js';
22
23
  /**
23
24
  * Load the app's environment into `process.env`, then re-apply the original
@@ -305,10 +306,8 @@ function addPackage(packagePath, source, res, packageJson) {
305
306
  path: packagePath,
306
307
  packageName: pack.name,
307
308
  source,
308
- // `lincd: true` is the pre-rename spelling of the same flag and is still
309
- // honoured by `linked build-package`; honouring it here too keeps the two
310
- // from disagreeing about what a linked package is.
311
- isLinkedPackage: pack.linkedPackage === true || pack.lincd === true,
309
+ // The one definition, shared with `linked build-package`.
310
+ isLinkedPackage: isLinkedPackageJson(pack),
312
311
  isApp: pack.linkedApp === true,
313
312
  hasBuildScript: !!((_a = pack.scripts) === null || _a === void 0 ? void 0 : _a.build),
314
313
  });
@@ -425,7 +424,7 @@ export function planBuildAll(rootPath = './', appRoot) {
425
424
  if (appRoot) {
426
425
  const appPackageJson = getPackageJSON(appRoot);
427
426
  const isAppWithLinkedDeps = appPackageJson &&
428
- appPackageJson.lincd !== true &&
427
+ !isLinkedPackageJson(appPackageJson) &&
429
428
  [
430
429
  ...Object.keys(appPackageJson.dependencies || {}),
431
430
  ...localizedPackageNames(appRoot),
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["// Lifecycle helpers shared by the Vite-based dev orchestrator.\n//\n// Extracted from cli-methods.ts so the SSR module graph (started from\n// `commands/start.ts`) doesn't have to walk the rest of that file. The\n// the older helpers in cli-methods.ts contain many dynamic\n// `import(<variable>)` calls Vite can't analyze statically and would\n// emit warnings about — even though startWithVite never calls them.\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport {getPackageJSON} from './utils.js';\nimport {parseWorkspacePatterns, isWorkspacePathNegated} from './workspace-globs.js';\nimport type {PackageDetails} from './interfaces.js';\n\n/**\n * Load the app's environment into `process.env`, then re-apply the original\n * shell env so it always wins on conflict. Idempotent — runs at most once.\n *\n * Two sources, tried in this order:\n * 1. `.env` (Node-native `process.loadEnvFile`, no dependency) — a flat file.\n * This is what the app template ships and the only form that will survive.\n * `--env` is not consulted here: a flat `.env` has no profiles, so\n * NODE_ENV comes from the file or the shell.\n * 2. `.env-cmdrc.json` (DEPRECATED, via `env-cmd`) — profile-based; honours\n * `--env a,b` and merges `_main` + the named profiles. Still read when it\n * is the only file present, so no existing app breaks, but it warns.\n *\n * `.env` going first is what makes migrating a one-step job: add the flat file\n * and it takes over. The profile file can then be deleted whenever convenient.\n *\n * If neither file exists we skip silently — CN-hosted apps have their env\n * injected into the child process at spawn time, so there's nothing to read\n * from disk.\n */\nexport const ensureEnvironmentLoaded = async (\n environmentNames?: string[],\n): Promise<void> => {\n if (process.env.ENV_VARS_LOADED) return;\n const cwd = process.cwd();\n const envCmdrcPath = path.join(cwd, '.env-cmdrc.json');\n const dotEnvPath = path.join(cwd, '.env');\n\n // Snapshot the original shell env — it should always take priority over\n // whatever a file sets (so injected/production env wins over dev defaults).\n const shellEnv = {...process.env};\n\n const hasDotEnv = fs.existsSync(dotEnvPath);\n const hasEnvCmdrc = fs.existsSync(envCmdrcPath);\n\n for (const notice of envDeprecationNotices({hasEnvCmdrc, hasDotEnv})) {\n console.warn(chalk.yellow(notice));\n }\n\n if (hasDotEnv) {\n // Native flat-file loader (Node 20.12+). Populates process.env from `.env`.\n process.loadEnvFile(dotEnvPath);\n } else if (hasEnvCmdrc) {\n await loadEnvCmdrc(envCmdrcPath, environmentNames);\n } else {\n console.warn(\n 'No .env or .env-cmdrc.json found in this folder — relying on the ambient environment.',\n );\n }\n\n // Re-apply shell env so it always wins over file values.\n process.env = {...process.env, ...shellEnv};\n process.env.ENV_VARS_LOADED = 'true';\n};\n\n/**\n * What to tell an app about where its environment came from.\n *\n * `.env-cmdrc.json` is still read when it is the only file present, so no app\n * breaks today. But it is the only reason `--env` exists, and both are going\n * away.\n *\n * The case worth shouting about is an app holding both files: `.env` wins, so\n * the profile file and every `--env` name passed with it do nothing. That is\n * the intended migration path, but it is invisible from the outside — values\n * an app still believes it is getting from a profile are simply absent.\n *\n * Pure and exported so the messages can be asserted without a chdir.\n */\nexport const envDeprecationNotices = (sources: {\n hasEnvCmdrc: boolean;\n hasDotEnv: boolean;\n}): string[] => {\n if (!sources.hasEnvCmdrc) return [];\n const notices = [\n '.env-cmdrc.json is deprecated and will be removed in a future major release.',\n ' Move its values into a flat `.env`, and supply anything that differs per ' +\n 'deployment from the environment itself. `--env` goes away with it.',\n ];\n if (sources.hasDotEnv) {\n notices.push(\n ' This app has BOTH files. `.env` wins, so `.env-cmdrc.json` — and any ' +\n '`--env` profile named with it — is being ignored entirely. Delete it once ' +\n 'the flat file is complete.',\n );\n }\n return notices;\n};\n\n/**\n * Legacy loader: reads `.env-cmdrc.json`, merges `_main` plus the profile(s)\n * named by `--env a,b` (default `development`). Kept for CN and existing apps\n * until they migrate to a flat `.env`.\n */\nconst loadEnvCmdrc = async (\n envCmdrcPath: string,\n environmentNames?: string[],\n): Promise<void> => {\n // env-cmd ships ESM; literal specifier is fine for Vite's analyzer.\n const {GetEnvVars} = await import('env-cmd');\n const vars = await GetEnvVars({envFile: {filePath: envCmdrcPath}});\n const environments = Object.keys(vars);\n\n if (environments.includes('_main')) {\n process.env = {...process.env, ...vars._main};\n }\n // Callers that parsed `--env` themselves pass the names in. Commands that\n // have not been converted yet still have their names scraped off argv.\n const requested = environmentNames?.length\n ? environmentNames\n : readEnvNamesFromArgv();\n if (requested.length) {\n requested.forEach((name) => {\n if (environments.includes(name)) {\n console.log('Environment: ' + name);\n process.env = {...process.env, ...vars[name]};\n } else {\n console.warn(\n `Environment ${name} not found in .env-cmdrc.json. Available: ${environments.join(', ')}`,\n );\n }\n });\n } else {\n process.env = {...process.env, ...vars.development};\n console.log('No environment specified, using development');\n }\n};\n\nconst readEnvNamesFromArgv = (): string[] => {\n const args = process.argv.slice(2);\n const envIndex = args.indexOf('--env');\n if (envIndex === -1) return [];\n return (args[envIndex + 1] || '').split(',').filter(Boolean);\n};\n\n/**\n * Discover and load the app's storage-config bootstrap file. Tries the\n * canonical `linked.backend.storage.{ts,js}` first, then legacy paths.\n * Returns whatever the file's default export evaluates to, or undefined\n * if no candidate exists.\n */\nexport async function loadBackendStorageConfig(): Promise<any> {\n const cwd = process.cwd();\n const candidates = [\n path.join(cwd, 'linked.backend.storage.ts'),\n path.join(cwd, 'linked.backend.storage.js'),\n path.join(cwd, 'backend-storage-config.ts'),\n path.join(cwd, 'backend-storage-config.js'),\n path.join(cwd, 'scripts', 'backend-storage-config.js'),\n path.join(cwd, 'scripts', 'backend-storage-config.ts'),\n path.join(cwd, 'scripts', 'storage-config.js'),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n // Variable specifier is intentional — we discover the path at\n // runtime by probing the candidate list, so static analysis is\n // impossible.\n return import(/* @vite-ignore */ candidate);\n }\n }\n console.warn(\n chalk.yellow(\n '[linked.backend.storage] no linked.backend.storage.{ts,js} found at app root.',\n ),\n );\n return undefined;\n}\n\n/**\n * A local package directory found by {@link discoverLocalPackages}, together\n * with the facts that decide what can be done with it.\n *\n * The facts are recorded rather than filtered on, because the bug this type\n * exists to fix was a SILENT filter: `build-all` discovered only packages\n * carrying `linkedPackage: true` and printed nothing about the rest, so\n * `@_linked/maps` — a shipped dependency that simply never got the flag — was\n * dropped from a green build for as long as nobody counted the names.\n */\nexport interface LocalPackage extends PackageDetails {\n /** Where the walk found it. */\n source: 'workspace' | 'local-packages-dir';\n /** `linkedPackage: true`, or the legacy `lincd: true`. */\n isLinkedPackage: boolean;\n /** `linkedApp: true` — built by `linked build-app`, not `linked build`. */\n isApp: boolean;\n /** Has a `build` script of its own, which is what `build-all` invokes. */\n hasBuildScript: boolean;\n}\n\n/**\n * Directory holding localized checkouts (`linked localize`). It is\n * deliberately in NO workspace glob — that is the whole point of the design,\n * since npm learning about these checkouts is what made their predecessor\n * under `packages/` a trap — so any walk of `workspaces` alone cannot see it\n * and has to be told about it separately.\n */\nexport const LOCAL_PACKAGES_DIR = 'packages-local';\n\n/**\n * Walk the app's `package.json` `workspaces` field and return every\n * workspace package that declares `\"linkedPackage\": true`.\n *\n * Lives here (not in cli-methods.ts) so consumers like LinkedServer can\n * import it without dragging the rest of the legacy cli-methods flow into\n * Vite's SSR module graph.\n *\n * Kept deliberately narrow: this is the set the dev resolver and the runtime\n * treat as linked packages. Commands that want every *buildable* local\n * package — flag or no flag, workspace or localized checkout — want\n * {@link discoverLocalPackages} instead.\n */\nexport function getLincdPackages(\n rootPath = process.cwd(),\n): PackageDetails[] {\n return discoverLocalPackages(rootPath, {includeLocalPackagesDir: false})\n .filter((pkg) => pkg.isLinkedPackage)\n .map(({path: packagePath, packageName}) => ({path: packagePath, packageName}));\n}\n\n/**\n * Every local package directory this app can see, whether or not it declares\n * `linkedPackage: true`.\n *\n * Two sources, because the workspace globs are not the whole picture any more:\n *\n * 1. the `workspaces` field (negations honoured — see ./workspace-globs.js);\n * 2. `packages-local/`, the localized checkouts, which is in no glob.\n *\n * Nothing is filtered out here. Callers decide what they can act on and are\n * expected to SAY what they skipped and why.\n */\nexport function discoverLocalPackages(\n rootPath = process.cwd(),\n options: {includeLocalPackagesDir?: boolean; localPackagesDir?: string} = {},\n): LocalPackage[] {\n const {includeLocalPackagesDir = true, localPackagesDir = LOCAL_PACKAGES_DIR} =\n options;\n\n let pack = getPackageJSON(rootPath);\n if (!pack || !pack.workspaces) {\n const originalRoot = rootPath;\n for (let i = 0; i <= 3; i++) {\n rootPath = path.join(originalRoot, ...Array(i).fill('..'));\n pack = getPackageJSON(rootPath);\n if (pack && pack.workspaces) break;\n }\n if (!pack || !pack.workspaces) {\n // Standalone apps (scaffolded with `linked create-app`) don't have\n // workspaces — expected. Fall back to the original root so a\n // `packages-local/` beside it is still found.\n rootPath = originalRoot;\n }\n }\n\n const res: LocalPackage[] = [];\n if (pack && pack.workspaces) {\n checkWorkspaces(rootPath, pack.workspaces, res);\n }\n if (includeLocalPackagesDir) {\n checkLocalPackagesDir(rootPath, localPackagesDir, res);\n }\n return res;\n}\n\n/**\n * Add every immediate subdirectory of `packages-local/` that holds a\n * `package.json`. No glob, no negations: the directory has no `workspaces`\n * entry to interpret, its contents are there because a developer localized\n * them on purpose, and each one is a plain checkout.\n */\nfunction checkLocalPackagesDir(\n rootPath: string,\n localPackagesDir: string,\n res: LocalPackage[],\n) {\n const dir = path.join(rootPath, localPackagesDir);\n if (!fs.existsSync(dir)) return;\n const already = new Set(res.map((pkg) => path.resolve(pkg.path)));\n for (const entry of fs.readdirSync(dir)) {\n if (entry.startsWith('.')) continue;\n const packagePath = path.join(dir, entry);\n if (!fs.statSync(packagePath).isDirectory()) continue;\n // A checkout that some glob already picked up must not appear twice —\n // duplicates would be built twice and counted twice.\n if (already.has(path.resolve(packagePath))) continue;\n addPackage(packagePath, 'local-packages-dir', res);\n }\n}\n\nfunction checkWorkspaces(rootPath: string, workspaces: any, res: LocalPackage[]) {\n // Negated entries (\"!packages/core\") are excluded the way npm excludes them\n // — including from the exact-path branch below, which npm also subjects to\n // them. See ./workspace-globs.js.\n const {patterns, negatedPatterns} = parseWorkspacePatterns(workspaces);\n const checkUnlessNegated = (packagePath: string) => {\n const rel = path.relative(rootPath, packagePath).split(path.sep).join('/');\n if (isWorkspacePathNegated(rel, negatedPatterns)) return;\n checkPackagePath(rootPath, packagePath, res);\n };\n patterns.forEach((workspace: string) => {\n const workspacePath = path.join(rootPath, workspace.replace('/*', ''));\n if (workspace.indexOf('/*') !== -1) {\n if (fs.existsSync(workspacePath)) {\n const folders = fs.readdirSync(workspacePath);\n folders.forEach((folder: string) => {\n if (folder !== './' && folder !== '../') {\n checkUnlessNegated(path.join(workspacePath, folder));\n }\n });\n }\n } else {\n checkUnlessNegated(workspacePath);\n }\n });\n}\n\nfunction checkPackagePath(rootPath: string, packagePath: string, res: LocalPackage[]) {\n const packageJsonPath = path.join(packagePath, 'package.json');\n if (!fs.existsSync(packageJsonPath)) return;\n const pack = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n if (pack && pack.workspaces) {\n checkWorkspaces(packagePath, pack.workspaces, res);\n } else if (pack) {\n addPackage(packagePath, 'workspace', res, pack);\n }\n}\n\nfunction addPackage(\n packagePath: string,\n source: LocalPackage['source'],\n res: LocalPackage[],\n packageJson?: any,\n) {\n const pack = packageJson ?? getPackageJSON(packagePath);\n if (!pack || !pack.name) return;\n res.push({\n path: packagePath,\n packageName: pack.name,\n source,\n // `lincd: true` is the pre-rename spelling of the same flag and is still\n // honoured by `linked build-package`; honouring it here too keeps the two\n // from disagreeing about what a linked package is.\n isLinkedPackage: pack.linkedPackage === true || pack.lincd === true,\n isApp: pack.linkedApp === true,\n hasBuildScript: !!pack.scripts?.build,\n });\n}\n\n/**\n * Filters packages to only include those in the dependency tree of the app root\n */\nfunction filterPackagesByDependencyTree(\n allPackages: Map<string, PackageDetails>,\n appRootPath: string,\n): Map<string, PackageDetails> {\n const appPackageJson = getPackageJSON(appRootPath);\n if (!appPackageJson) {\n return allPackages;\n }\n\n const relevantPackages = new Map<string, PackageDetails>();\n const packagesToCheck = new Set<string>();\n\n // Start with direct dependencies from app root, plus everything localized:\n // a package created locally is linked but cannot be declared until it is\n // published (an unpublished range fails `npm install`), and being localized\n // already says this app is developed against it.\n [\n ...Object.keys(appPackageJson.dependencies || {}),\n ...localizedPackageNames(appRootPath),\n ].forEach((dep) => {\n if (allPackages.has(dep)) {\n packagesToCheck.add(dep);\n }\n });\n\n // Recursively add dependencies\n const processedPackages = new Set<string>();\n\n while (packagesToCheck.size > 0) {\n const packageName = Array.from(packagesToCheck)[0];\n packagesToCheck.delete(packageName);\n\n if (processedPackages.has(packageName)) {\n continue;\n }\n\n processedPackages.add(packageName);\n const packageDetails = allPackages.get(packageName);\n\n if (packageDetails) {\n relevantPackages.set(packageName, packageDetails);\n\n // Get this package's dependencies\n const packageJson = getPackageJSON(packageDetails.path);\n if (packageJson && packageJson.dependencies) {\n Object.keys(packageJson.dependencies).forEach((dep) => {\n if (allPackages.has(dep) && !processedPackages.has(dep)) {\n packagesToCheck.add(dep);\n }\n });\n }\n }\n }\n\n return relevantPackages;\n}\n\n/**\n * localize's manifest filename (`MANIFEST_FILENAME` in `@_linked/localize`).\n * Repeated rather than imported: that package is ESM-only and loaded lazily,\n * and this runs synchronously while planning a build.\n */\nconst LOCALIZE_MANIFEST = 'local-packages.json';\n\n/**\n * The package names recorded in the app's `local-packages.json` — what\n * `linked localize` has linked. Read tolerantly: localize owns that file and\n * refuses a malformed one loudly, so here a missing or unreadable file is\n * simply \"nothing localized\".\n */\nexport function localizedPackageNames(appRootPath: string): string[] {\n try {\n const manifest = JSON.parse(\n fs.readFileSync(path.join(appRootPath, LOCALIZE_MANIFEST), 'utf8'),\n );\n const packages = manifest?.packages;\n return packages && typeof packages === 'object' && !Array.isArray(packages)\n ? Object.keys(packages)\n : [];\n } catch {\n return [];\n }\n}\n\n/** A package `build-all` found but will not build, and why not. */\nexport interface SkippedPackage {\n packageName: string;\n path: string;\n reason: string;\n}\n\n/** What `build-all` found, and what it decided to do with each package. */\nexport interface BuildAllPlan {\n build: Map<string, PackageDetails>;\n skipped: SkippedPackage[];\n}\n\n/**\n * Decide what `build-all` builds.\n *\n * Every discovered package lands in exactly one of `build` or `skipped`, and\n * `skipped` carries a reason — because the failure mode this replaces was not\n * a narrow scan, it was a SILENT one. `@_linked/maps` is a shipped Create Now\n * dependency that never got `linkedPackage: true`; `build-all` dropped it and\n * printed nothing, so a build covering half the workspace exited 0 and people\n * acted on it. A skip nobody can see is worse than a failure.\n *\n * What counts as buildable is a CAPABILITY, not a declaration: `build-all`\n * invokes each package's own `build` script, so anything with one can be\n * built whether or not it carries the flag. The flag is still reported when\n * it is missing, since the dev resolver and `linked build` do require it.\n */\nexport function planBuildAll(rootPath = './', appRoot?: string): BuildAllPlan {\n const build = new Map<string, PackageDetails>();\n const skipped: SkippedPackage[] = [];\n const buildable: LocalPackage[] = [];\n\n for (const pkg of discoverLocalPackages(rootPath)) {\n const detail = {path: pkg.path, packageName: pkg.packageName};\n // Packages reached through a `../` workspace glob live outside this\n // repository; building them was never in scope for `build-all`.\n if (pkg.path.indexOf('../') !== -1 || pkg.path.indexOf('..\\\\') !== -1) {\n skipped.push({...detail, reason: 'outside this repository'});\n } else if (pkg.isApp) {\n skipped.push({\n ...detail,\n reason: 'is a linked app — build it with `linked build-app`',\n });\n } else if (!pkg.hasBuildScript) {\n skipped.push({...detail, reason: 'has no `build` script'});\n } else {\n buildable.push(pkg);\n build.set(pkg.packageName, detail);\n }\n }\n\n // Narrow to what this app actually depends on, if we are inside one.\n if (appRoot) {\n const appPackageJson = getPackageJSON(appRoot);\n const isAppWithLinkedDeps =\n appPackageJson &&\n appPackageJson.lincd !== true &&\n [\n ...Object.keys(appPackageJson.dependencies || {}),\n ...localizedPackageNames(appRoot),\n ].some((dep) => build.has(dep));\n\n if (isAppWithLinkedDeps) {\n const inTree = filterPackagesByDependencyTree(build, appRoot);\n for (const pkg of buildable) {\n if (inTree.has(pkg.packageName)) continue;\n build.delete(pkg.packageName);\n skipped.push({\n path: pkg.path,\n packageName: pkg.packageName,\n reason: `not in ${appPackageJson.name || 'this app'}'s dependency tree`,\n });\n }\n }\n }\n\n return {build, skipped};\n}\n\n"]}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/lifecycle.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,2DAA2D;AAC3D,qEAAqE;AACrE,oEAAoE;;;;;;;;;;AAEpE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAC,mBAAmB,EAAC,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAC,sBAAsB,EAAE,sBAAsB,EAAC,MAAM,sBAAsB,CAAC;AAGpF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,gBAA2B,EACZ,EAAE;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;QAAE,OAAO;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAE1C,wEAAwE;IACxE,4EAA4E;IAC5E,MAAM,QAAQ,qBAAO,OAAO,CAAC,GAAG,CAAC,CAAC;IAElC,MAAM,SAAS,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAEhD,KAAK,MAAM,MAAM,IAAI,qBAAqB,CAAC,EAAC,WAAW,EAAE,SAAS,EAAC,CAAC,EAAE,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,4EAA4E;QAC5E,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;SAAM,IAAI,WAAW,EAAE,CAAC;QACvB,MAAM,YAAY,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CACV,uFAAuF,CACxF,CAAC;IACJ,CAAC;IAED,yDAAyD;IACzD,OAAO,CAAC,GAAG,mCAAO,OAAO,CAAC,GAAG,GAAK,QAAQ,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,MAAM,CAAC;AACvC,CAAC,CAAA,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAGrC,EAAY,EAAE;IACb,IAAI,CAAC,OAAO,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG;QACd,8EAA8E;QAC9E,6EAA6E;YAC3E,oEAAoE;KACvE,CAAC;IACF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO,CAAC,IAAI,CACV,yEAAyE;YACvE,4EAA4E;YAC5E,4BAA4B,CAC/B,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,YAAY,GAAG,CACnB,YAAoB,EACpB,gBAA2B,EACZ,EAAE;IACjB,oEAAoE;IACpE,MAAM,EAAC,UAAU,EAAC,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,EAAC,OAAO,EAAE,EAAC,QAAQ,EAAE,YAAY,EAAC,EAAC,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEvC,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,GAAG,mCAAO,OAAO,CAAC,GAAG,GAAK,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IACD,0EAA0E;IAC1E,uEAAuE;IACvE,MAAM,SAAS,GAAG,CAAA,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAE,MAAM;QACxC,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,oBAAoB,EAAE,CAAC;IAC3B,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;QACrB,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;gBACpC,OAAO,CAAC,GAAG,mCAAO,OAAO,CAAC,GAAG,GAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CACV,eAAe,IAAI,6CAA6C,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1F,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,mCAAO,OAAO,CAAC,GAAG,GAAK,IAAI,CAAC,WAAW,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC,CAAA,CAAC;AAEF,MAAM,oBAAoB,GAAG,GAAa,EAAE;IAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,QAAQ,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC/D,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAgB,wBAAwB;;QAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG;YACjB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,2BAA2B,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,2BAA2B,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,2BAA2B,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,2BAA2B,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,2BAA2B,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,2BAA2B,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,mBAAmB,CAAC;SAC/C,CAAC;QACF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC7B,8DAA8D;gBAC9D,+DAA+D;gBAC/D,cAAc;gBACd,OAAO,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QACD,OAAO,CAAC,IAAI,CACV,KAAK,CAAC,MAAM,CACV,+EAA+E,CAChF,CACF,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;CAAA;AAuBD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE;IAExB,OAAO,qBAAqB,CAAC,QAAQ,EAAE,EAAC,uBAAuB,EAAE,KAAK,EAAC,CAAC;SACrE,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC;SACpC,GAAG,CAAC,CAAC,EAAC,IAAI,EAAE,WAAW,EAAE,WAAW,EAAC,EAAE,EAAE,CAAC,CAAC,EAAC,IAAI,EAAE,WAAW,EAAE,WAAW,EAAC,CAAC,CAAC,CAAC;AACnF,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,EACxB,UAA0E,EAAE;IAE5E,MAAM,EAAC,uBAAuB,GAAG,IAAI,EAAE,gBAAgB,GAAG,kBAAkB,EAAC,GAC3E,OAAO,CAAC;IAEV,IAAI,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,QAAQ,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3D,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;YAChC,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU;gBAAE,MAAM;QACrC,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YAC9B,mEAAmE;YACnE,6DAA6D;YAC7D,8CAA8C;YAC9C,QAAQ,GAAG,YAAY,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAC5B,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,uBAAuB,EAAE,CAAC;QAC5B,qBAAqB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAC5B,QAAgB,EAChB,gBAAwB,EACxB,GAAmB;IAEnB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IAClD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO;IAChC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClE,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACpC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE;YAAE,SAAS;QACtD,sEAAsE;QACtE,qDAAqD;QACrD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAAE,SAAS;QACrD,UAAU,CAAC,WAAW,EAAE,oBAAoB,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB,EAAE,UAAe,EAAE,GAAmB;IAC7E,4EAA4E;IAC5E,2EAA2E;IAC3E,kCAAkC;IAClC,MAAM,EAAC,QAAQ,EAAE,eAAe,EAAC,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,kBAAkB,GAAG,CAAC,WAAmB,EAAE,EAAE;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3E,IAAI,sBAAsB,CAAC,GAAG,EAAE,eAAe,CAAC;YAAE,OAAO;QACzD,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;IAC/C,CAAC,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,CAAC,SAAiB,EAAE,EAAE;QACrC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACvE,IAAI,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACnC,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;gBACjC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;gBAC9C,OAAO,CAAC,OAAO,CAAC,CAAC,MAAc,EAAE,EAAE;oBACjC,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;wBACxC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;oBACvD,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,CAAC;YACN,kBAAkB,CAAC,aAAa,CAAC,CAAC;QACpC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB,EAAE,WAAmB,EAAE,GAAmB;IAClF,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC/D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QAC5B,eAAe,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,IAAI,EAAE,CAAC;QAChB,UAAU,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CACjB,WAAmB,EACnB,MAA8B,EAC9B,GAAmB,EACnB,WAAiB;;IAEjB,MAAM,IAAI,GAAG,WAAW,aAAX,WAAW,cAAX,WAAW,GAAI,cAAc,CAAC,WAAW,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO;IAChC,GAAG,CAAC,IAAI,CAAC;QACP,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,IAAI,CAAC,IAAI;QACtB,MAAM;QACN,0DAA0D;QAC1D,eAAe,EAAE,mBAAmB,CAAC,IAAI,CAAC;QAC1C,KAAK,EAAE,IAAI,CAAC,SAAS,KAAK,IAAI;QAC9B,cAAc,EAAE,CAAC,CAAC,CAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,KAAK,CAAA;KACtC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,8BAA8B,CACrC,WAAwC,EACxC,WAAmB;IAEnB,MAAM,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC3D,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAE1C,2EAA2E;IAC3E,yEAAyE;IACzE,4EAA4E;IAC5E,iDAAiD;IACjD;QACE,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,IAAI,EAAE,CAAC;QACjD,GAAG,qBAAqB,CAAC,WAAW,CAAC;KACtC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAChB,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,+BAA+B;IAC/B,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAE5C,OAAO,eAAe,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,eAAe,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAEpC,IAAI,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACvC,SAAS;QACX,CAAC;QAED,iBAAiB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACnC,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAEpD,IAAI,cAAc,EAAE,CAAC;YACnB,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YAElD,kCAAkC;YAClC,MAAM,WAAW,GAAG,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YACxD,IAAI,WAAW,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC;gBAC5C,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;oBACpD,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBACxD,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAC3B,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CACnE,CAAC;QACF,MAAM,QAAQ,GAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,QAAQ,CAAC;QACpC,OAAO,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YACzE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;YACvB,CAAC,CAAC,EAAE,CAAC;IACT,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAeD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAC,QAAQ,GAAG,IAAI,EAAE,OAAgB;IAC5D,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAChD,MAAM,OAAO,GAAqB,EAAE,CAAC;IACrC,MAAM,SAAS,GAAmB,EAAE,CAAC;IAErC,KAAK,MAAM,GAAG,IAAI,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,EAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAC,CAAC;QAC9D,oEAAoE;QACpE,gEAAgE;QAChE,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACtE,OAAO,CAAC,IAAI,iCAAK,MAAM,KAAE,MAAM,EAAE,yBAAyB,IAAE,CAAC;QAC/D,CAAC;aAAM,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,iCACP,MAAM,KACT,MAAM,EAAE,oDAAoD,IAC5D,CAAC;QACL,CAAC;aAAM,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,iCAAK,MAAM,KAAE,MAAM,EAAE,uBAAuB,IAAE,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,cAAc,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,mBAAmB,GACvB,cAAc;YACd,CAAC,mBAAmB,CAAC,cAAc,CAAC;YACpC;gBACE,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,IAAI,EAAE,CAAC;gBACjD,GAAG,qBAAqB,CAAC,OAAO,CAAC;aAClC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAElC,IAAI,mBAAmB,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,8BAA8B,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC9D,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;gBAC5B,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC;oBAAE,SAAS;gBAC1C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBAC9B,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,WAAW,EAAE,GAAG,CAAC,WAAW;oBAC5B,MAAM,EAAE,UAAU,cAAc,CAAC,IAAI,IAAI,UAAU,oBAAoB;iBACxE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAC,KAAK,EAAE,OAAO,EAAC,CAAC;AAC1B,CAAC","sourcesContent":["// Lifecycle helpers shared by the Vite-based dev orchestrator.\n//\n// Extracted from cli-methods.ts so the SSR module graph (started from\n// `commands/start.ts`) doesn't have to walk the rest of that file. The\n// the older helpers in cli-methods.ts contain many dynamic\n// `import(<variable>)` calls Vite can't analyze statically and would\n// emit warnings about — even though startWithVite never calls them.\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport chalk from 'chalk';\nimport {getPackageJSON} from './utils.js';\nimport {isLinkedPackageJson} from './installed-packages.js';\nimport {parseWorkspacePatterns, isWorkspacePathNegated} from './workspace-globs.js';\nimport type {PackageDetails} from './interfaces.js';\n\n/**\n * Load the app's environment into `process.env`, then re-apply the original\n * shell env so it always wins on conflict. Idempotent — runs at most once.\n *\n * Two sources, tried in this order:\n * 1. `.env` (Node-native `process.loadEnvFile`, no dependency) — a flat file.\n * This is what the app template ships and the only form that will survive.\n * `--env` is not consulted here: a flat `.env` has no profiles, so\n * NODE_ENV comes from the file or the shell.\n * 2. `.env-cmdrc.json` (DEPRECATED, via `env-cmd`) — profile-based; honours\n * `--env a,b` and merges `_main` + the named profiles. Still read when it\n * is the only file present, so no existing app breaks, but it warns.\n *\n * `.env` going first is what makes migrating a one-step job: add the flat file\n * and it takes over. The profile file can then be deleted whenever convenient.\n *\n * If neither file exists we skip silently — CN-hosted apps have their env\n * injected into the child process at spawn time, so there's nothing to read\n * from disk.\n */\nexport const ensureEnvironmentLoaded = async (\n environmentNames?: string[],\n): Promise<void> => {\n if (process.env.ENV_VARS_LOADED) return;\n const cwd = process.cwd();\n const envCmdrcPath = path.join(cwd, '.env-cmdrc.json');\n const dotEnvPath = path.join(cwd, '.env');\n\n // Snapshot the original shell env — it should always take priority over\n // whatever a file sets (so injected/production env wins over dev defaults).\n const shellEnv = {...process.env};\n\n const hasDotEnv = fs.existsSync(dotEnvPath);\n const hasEnvCmdrc = fs.existsSync(envCmdrcPath);\n\n for (const notice of envDeprecationNotices({hasEnvCmdrc, hasDotEnv})) {\n console.warn(chalk.yellow(notice));\n }\n\n if (hasDotEnv) {\n // Native flat-file loader (Node 20.12+). Populates process.env from `.env`.\n process.loadEnvFile(dotEnvPath);\n } else if (hasEnvCmdrc) {\n await loadEnvCmdrc(envCmdrcPath, environmentNames);\n } else {\n console.warn(\n 'No .env or .env-cmdrc.json found in this folder — relying on the ambient environment.',\n );\n }\n\n // Re-apply shell env so it always wins over file values.\n process.env = {...process.env, ...shellEnv};\n process.env.ENV_VARS_LOADED = 'true';\n};\n\n/**\n * What to tell an app about where its environment came from.\n *\n * `.env-cmdrc.json` is still read when it is the only file present, so no app\n * breaks today. But it is the only reason `--env` exists, and both are going\n * away.\n *\n * The case worth shouting about is an app holding both files: `.env` wins, so\n * the profile file and every `--env` name passed with it do nothing. That is\n * the intended migration path, but it is invisible from the outside — values\n * an app still believes it is getting from a profile are simply absent.\n *\n * Pure and exported so the messages can be asserted without a chdir.\n */\nexport const envDeprecationNotices = (sources: {\n hasEnvCmdrc: boolean;\n hasDotEnv: boolean;\n}): string[] => {\n if (!sources.hasEnvCmdrc) return [];\n const notices = [\n '.env-cmdrc.json is deprecated and will be removed in a future major release.',\n ' Move its values into a flat `.env`, and supply anything that differs per ' +\n 'deployment from the environment itself. `--env` goes away with it.',\n ];\n if (sources.hasDotEnv) {\n notices.push(\n ' This app has BOTH files. `.env` wins, so `.env-cmdrc.json` — and any ' +\n '`--env` profile named with it — is being ignored entirely. Delete it once ' +\n 'the flat file is complete.',\n );\n }\n return notices;\n};\n\n/**\n * Legacy loader: reads `.env-cmdrc.json`, merges `_main` plus the profile(s)\n * named by `--env a,b` (default `development`). Kept for CN and existing apps\n * until they migrate to a flat `.env`.\n */\nconst loadEnvCmdrc = async (\n envCmdrcPath: string,\n environmentNames?: string[],\n): Promise<void> => {\n // env-cmd ships ESM; literal specifier is fine for Vite's analyzer.\n const {GetEnvVars} = await import('env-cmd');\n const vars = await GetEnvVars({envFile: {filePath: envCmdrcPath}});\n const environments = Object.keys(vars);\n\n if (environments.includes('_main')) {\n process.env = {...process.env, ...vars._main};\n }\n // Callers that parsed `--env` themselves pass the names in. Commands that\n // have not been converted yet still have their names scraped off argv.\n const requested = environmentNames?.length\n ? environmentNames\n : readEnvNamesFromArgv();\n if (requested.length) {\n requested.forEach((name) => {\n if (environments.includes(name)) {\n console.log('Environment: ' + name);\n process.env = {...process.env, ...vars[name]};\n } else {\n console.warn(\n `Environment ${name} not found in .env-cmdrc.json. Available: ${environments.join(', ')}`,\n );\n }\n });\n } else {\n process.env = {...process.env, ...vars.development};\n console.log('No environment specified, using development');\n }\n};\n\nconst readEnvNamesFromArgv = (): string[] => {\n const args = process.argv.slice(2);\n const envIndex = args.indexOf('--env');\n if (envIndex === -1) return [];\n return (args[envIndex + 1] || '').split(',').filter(Boolean);\n};\n\n/**\n * Discover and load the app's storage-config bootstrap file. Tries the\n * canonical `linked.backend.storage.{ts,js}` first, then legacy paths.\n * Returns whatever the file's default export evaluates to, or undefined\n * if no candidate exists.\n */\nexport async function loadBackendStorageConfig(): Promise<any> {\n const cwd = process.cwd();\n const candidates = [\n path.join(cwd, 'linked.backend.storage.ts'),\n path.join(cwd, 'linked.backend.storage.js'),\n path.join(cwd, 'backend-storage-config.ts'),\n path.join(cwd, 'backend-storage-config.js'),\n path.join(cwd, 'scripts', 'backend-storage-config.js'),\n path.join(cwd, 'scripts', 'backend-storage-config.ts'),\n path.join(cwd, 'scripts', 'storage-config.js'),\n ];\n for (const candidate of candidates) {\n if (fs.existsSync(candidate)) {\n // Variable specifier is intentional — we discover the path at\n // runtime by probing the candidate list, so static analysis is\n // impossible.\n return import(/* @vite-ignore */ candidate);\n }\n }\n console.warn(\n chalk.yellow(\n '[linked.backend.storage] no linked.backend.storage.{ts,js} found at app root.',\n ),\n );\n return undefined;\n}\n\n/**\n * A local package directory found by {@link discoverLocalPackages}, together\n * with the facts that decide what can be done with it.\n *\n * The facts are recorded rather than filtered on, because the bug this type\n * exists to fix was a SILENT filter: `build-all` discovered only packages\n * carrying `linkedPackage: true` and printed nothing about the rest, so\n * `@_linked/maps` — a shipped dependency that simply never got the flag — was\n * dropped from a green build for as long as nobody counted the names.\n */\nexport interface LocalPackage extends PackageDetails {\n /** Where the walk found it. */\n source: 'workspace' | 'local-packages-dir';\n /** `linkedPackage: true` — see `isLinkedPackageJson`. */\n isLinkedPackage: boolean;\n /** `linkedApp: true` — built by `linked build-app`, not `linked build`. */\n isApp: boolean;\n /** Has a `build` script of its own, which is what `build-all` invokes. */\n hasBuildScript: boolean;\n}\n\n/**\n * Directory holding localized checkouts (`linked localize`). It is\n * deliberately in NO workspace glob — that is the whole point of the design,\n * since npm learning about these checkouts is what made their predecessor\n * under `packages/` a trap — so any walk of `workspaces` alone cannot see it\n * and has to be told about it separately.\n */\nexport const LOCAL_PACKAGES_DIR = 'packages-local';\n\n/**\n * Walk the app's `package.json` `workspaces` field and return every\n * workspace package that declares `\"linkedPackage\": true`.\n *\n * Lives here (not in cli-methods.ts) so consumers like LinkedServer can\n * import it without dragging the rest of the legacy cli-methods flow into\n * Vite's SSR module graph.\n *\n * Kept deliberately narrow: this is the set the dev resolver and the runtime\n * treat as linked packages. Commands that want every *buildable* local\n * package — flag or no flag, workspace or localized checkout — want\n * {@link discoverLocalPackages} instead.\n */\nexport function getLincdPackages(\n rootPath = process.cwd(),\n): PackageDetails[] {\n return discoverLocalPackages(rootPath, {includeLocalPackagesDir: false})\n .filter((pkg) => pkg.isLinkedPackage)\n .map(({path: packagePath, packageName}) => ({path: packagePath, packageName}));\n}\n\n/**\n * Every local package directory this app can see, whether or not it declares\n * `linkedPackage: true`.\n *\n * Two sources, because the workspace globs are not the whole picture any more:\n *\n * 1. the `workspaces` field (negations honoured — see ./workspace-globs.js);\n * 2. `packages-local/`, the localized checkouts, which is in no glob.\n *\n * Nothing is filtered out here. Callers decide what they can act on and are\n * expected to SAY what they skipped and why.\n */\nexport function discoverLocalPackages(\n rootPath = process.cwd(),\n options: {includeLocalPackagesDir?: boolean; localPackagesDir?: string} = {},\n): LocalPackage[] {\n const {includeLocalPackagesDir = true, localPackagesDir = LOCAL_PACKAGES_DIR} =\n options;\n\n let pack = getPackageJSON(rootPath);\n if (!pack || !pack.workspaces) {\n const originalRoot = rootPath;\n for (let i = 0; i <= 3; i++) {\n rootPath = path.join(originalRoot, ...Array(i).fill('..'));\n pack = getPackageJSON(rootPath);\n if (pack && pack.workspaces) break;\n }\n if (!pack || !pack.workspaces) {\n // Standalone apps (scaffolded with `linked create-app`) don't have\n // workspaces — expected. Fall back to the original root so a\n // `packages-local/` beside it is still found.\n rootPath = originalRoot;\n }\n }\n\n const res: LocalPackage[] = [];\n if (pack && pack.workspaces) {\n checkWorkspaces(rootPath, pack.workspaces, res);\n }\n if (includeLocalPackagesDir) {\n checkLocalPackagesDir(rootPath, localPackagesDir, res);\n }\n return res;\n}\n\n/**\n * Add every immediate subdirectory of `packages-local/` that holds a\n * `package.json`. No glob, no negations: the directory has no `workspaces`\n * entry to interpret, its contents are there because a developer localized\n * them on purpose, and each one is a plain checkout.\n */\nfunction checkLocalPackagesDir(\n rootPath: string,\n localPackagesDir: string,\n res: LocalPackage[],\n) {\n const dir = path.join(rootPath, localPackagesDir);\n if (!fs.existsSync(dir)) return;\n const already = new Set(res.map((pkg) => path.resolve(pkg.path)));\n for (const entry of fs.readdirSync(dir)) {\n if (entry.startsWith('.')) continue;\n const packagePath = path.join(dir, entry);\n if (!fs.statSync(packagePath).isDirectory()) continue;\n // A checkout that some glob already picked up must not appear twice —\n // duplicates would be built twice and counted twice.\n if (already.has(path.resolve(packagePath))) continue;\n addPackage(packagePath, 'local-packages-dir', res);\n }\n}\n\nfunction checkWorkspaces(rootPath: string, workspaces: any, res: LocalPackage[]) {\n // Negated entries (\"!packages/core\") are excluded the way npm excludes them\n // — including from the exact-path branch below, which npm also subjects to\n // them. See ./workspace-globs.js.\n const {patterns, negatedPatterns} = parseWorkspacePatterns(workspaces);\n const checkUnlessNegated = (packagePath: string) => {\n const rel = path.relative(rootPath, packagePath).split(path.sep).join('/');\n if (isWorkspacePathNegated(rel, negatedPatterns)) return;\n checkPackagePath(rootPath, packagePath, res);\n };\n patterns.forEach((workspace: string) => {\n const workspacePath = path.join(rootPath, workspace.replace('/*', ''));\n if (workspace.indexOf('/*') !== -1) {\n if (fs.existsSync(workspacePath)) {\n const folders = fs.readdirSync(workspacePath);\n folders.forEach((folder: string) => {\n if (folder !== './' && folder !== '../') {\n checkUnlessNegated(path.join(workspacePath, folder));\n }\n });\n }\n } else {\n checkUnlessNegated(workspacePath);\n }\n });\n}\n\nfunction checkPackagePath(rootPath: string, packagePath: string, res: LocalPackage[]) {\n const packageJsonPath = path.join(packagePath, 'package.json');\n if (!fs.existsSync(packageJsonPath)) return;\n const pack = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n if (pack && pack.workspaces) {\n checkWorkspaces(packagePath, pack.workspaces, res);\n } else if (pack) {\n addPackage(packagePath, 'workspace', res, pack);\n }\n}\n\nfunction addPackage(\n packagePath: string,\n source: LocalPackage['source'],\n res: LocalPackage[],\n packageJson?: any,\n) {\n const pack = packageJson ?? getPackageJSON(packagePath);\n if (!pack || !pack.name) return;\n res.push({\n path: packagePath,\n packageName: pack.name,\n source,\n // The one definition, shared with `linked build-package`.\n isLinkedPackage: isLinkedPackageJson(pack),\n isApp: pack.linkedApp === true,\n hasBuildScript: !!pack.scripts?.build,\n });\n}\n\n/**\n * Filters packages to only include those in the dependency tree of the app root\n */\nfunction filterPackagesByDependencyTree(\n allPackages: Map<string, PackageDetails>,\n appRootPath: string,\n): Map<string, PackageDetails> {\n const appPackageJson = getPackageJSON(appRootPath);\n if (!appPackageJson) {\n return allPackages;\n }\n\n const relevantPackages = new Map<string, PackageDetails>();\n const packagesToCheck = new Set<string>();\n\n // Start with direct dependencies from app root, plus everything localized:\n // a package created locally is linked but cannot be declared until it is\n // published (an unpublished range fails `npm install`), and being localized\n // already says this app is developed against it.\n [\n ...Object.keys(appPackageJson.dependencies || {}),\n ...localizedPackageNames(appRootPath),\n ].forEach((dep) => {\n if (allPackages.has(dep)) {\n packagesToCheck.add(dep);\n }\n });\n\n // Recursively add dependencies\n const processedPackages = new Set<string>();\n\n while (packagesToCheck.size > 0) {\n const packageName = Array.from(packagesToCheck)[0];\n packagesToCheck.delete(packageName);\n\n if (processedPackages.has(packageName)) {\n continue;\n }\n\n processedPackages.add(packageName);\n const packageDetails = allPackages.get(packageName);\n\n if (packageDetails) {\n relevantPackages.set(packageName, packageDetails);\n\n // Get this package's dependencies\n const packageJson = getPackageJSON(packageDetails.path);\n if (packageJson && packageJson.dependencies) {\n Object.keys(packageJson.dependencies).forEach((dep) => {\n if (allPackages.has(dep) && !processedPackages.has(dep)) {\n packagesToCheck.add(dep);\n }\n });\n }\n }\n }\n\n return relevantPackages;\n}\n\n/**\n * localize's manifest filename (`MANIFEST_FILENAME` in `@_linked/localize`).\n * Repeated rather than imported: that package is ESM-only and loaded lazily,\n * and this runs synchronously while planning a build.\n */\nconst LOCALIZE_MANIFEST = 'local-packages.json';\n\n/**\n * The package names recorded in the app's `local-packages.json` — what\n * `linked localize` has linked. Read tolerantly: localize owns that file and\n * refuses a malformed one loudly, so here a missing or unreadable file is\n * simply \"nothing localized\".\n */\nexport function localizedPackageNames(appRootPath: string): string[] {\n try {\n const manifest = JSON.parse(\n fs.readFileSync(path.join(appRootPath, LOCALIZE_MANIFEST), 'utf8'),\n );\n const packages = manifest?.packages;\n return packages && typeof packages === 'object' && !Array.isArray(packages)\n ? Object.keys(packages)\n : [];\n } catch {\n return [];\n }\n}\n\n/** A package `build-all` found but will not build, and why not. */\nexport interface SkippedPackage {\n packageName: string;\n path: string;\n reason: string;\n}\n\n/** What `build-all` found, and what it decided to do with each package. */\nexport interface BuildAllPlan {\n build: Map<string, PackageDetails>;\n skipped: SkippedPackage[];\n}\n\n/**\n * Decide what `build-all` builds.\n *\n * Every discovered package lands in exactly one of `build` or `skipped`, and\n * `skipped` carries a reason — because the failure mode this replaces was not\n * a narrow scan, it was a SILENT one. `@_linked/maps` is a shipped Create Now\n * dependency that never got `linkedPackage: true`; `build-all` dropped it and\n * printed nothing, so a build covering half the workspace exited 0 and people\n * acted on it. A skip nobody can see is worse than a failure.\n *\n * What counts as buildable is a CAPABILITY, not a declaration: `build-all`\n * invokes each package's own `build` script, so anything with one can be\n * built whether or not it carries the flag. The flag is still reported when\n * it is missing, since the dev resolver and `linked build` do require it.\n */\nexport function planBuildAll(rootPath = './', appRoot?: string): BuildAllPlan {\n const build = new Map<string, PackageDetails>();\n const skipped: SkippedPackage[] = [];\n const buildable: LocalPackage[] = [];\n\n for (const pkg of discoverLocalPackages(rootPath)) {\n const detail = {path: pkg.path, packageName: pkg.packageName};\n // Packages reached through a `../` workspace glob live outside this\n // repository; building them was never in scope for `build-all`.\n if (pkg.path.indexOf('../') !== -1 || pkg.path.indexOf('..\\\\') !== -1) {\n skipped.push({...detail, reason: 'outside this repository'});\n } else if (pkg.isApp) {\n skipped.push({\n ...detail,\n reason: 'is a linked app — build it with `linked build-app`',\n });\n } else if (!pkg.hasBuildScript) {\n skipped.push({...detail, reason: 'has no `build` script'});\n } else {\n buildable.push(pkg);\n build.set(pkg.packageName, detail);\n }\n }\n\n // Narrow to what this app actually depends on, if we are inside one.\n if (appRoot) {\n const appPackageJson = getPackageJSON(appRoot);\n const isAppWithLinkedDeps =\n appPackageJson &&\n !isLinkedPackageJson(appPackageJson) &&\n [\n ...Object.keys(appPackageJson.dependencies || {}),\n ...localizedPackageNames(appRoot),\n ].some((dep) => build.has(dep));\n\n if (isAppWithLinkedDeps) {\n const inTree = filterPackagesByDependencyTree(build, appRoot);\n for (const pkg of buildable) {\n if (inTree.has(pkg.packageName)) continue;\n build.delete(pkg.packageName);\n skipped.push({\n path: pkg.path,\n packageName: pkg.packageName,\n reason: `not in ${appPackageJson.name || 'this app'}'s dependency tree`,\n });\n }\n }\n }\n\n return {build, skipped};\n}\n\n"]}
@@ -0,0 +1,20 @@
1
+ export interface SkippedDedupe {
2
+ name: string;
3
+ reason: 'range' | 'nested';
4
+ /** For `range`: who asks what, and what the app has. */
5
+ asks?: {
6
+ from: string;
7
+ range: string;
8
+ }[];
9
+ appVersion?: string;
10
+ /** For `nested`: one registry install that carries its own copy. */
11
+ nestedAt?: string;
12
+ }
13
+ export interface LocalizedDedupe {
14
+ names: string[];
15
+ skipped: SkippedDedupe[];
16
+ }
17
+ export declare function localizedDedupe(appRoot?: string): Promise<LocalizedDedupe>;
18
+ /** One line for the dev log about the ranges the app does not satisfy; null when there are none. */
19
+ export declare function describeSkipped(skipped: SkippedDedupe[]): string | null;
20
+ //# sourceMappingURL=localized-dedupe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localized-dedupe.d.ts","sourceRoot":"","sources":["../../src/localized-dedupe.ts"],"names":[],"mappings":"AA8CA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC3B,wDAAwD;IACxD,IAAI,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,wBAAsB,eAAe,CACnC,OAAO,GAAE,MAAsB,GAC9B,OAAO,CAAC,eAAe,CAAC,CA2C1B;AAED,oGAAoG;AACpG,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,MAAM,GAAG,IAAI,CAavE"}