@_linked/cli 1.45.6 → 1.46.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.46.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#260](https://github.com/linked-fw/cli/pull/260) [`011395a`](https://github.com/linked-fw/cli/commit/011395a668641ea9fa41d80802eca1b156fe114f) Thanks [@flyon](https://github.com/flyon)! - `linked build-all` now builds `@_linked/cli` first and alone when it is one of the packages to build (a localized checkout). Every other package's build runs `linked build` from that checkout's `lib/`, so building it in parallel with them pulled `lib/` out from under their builds (`ENOENT …/lib/esm/installed-packages.js`) and left their dependents unbuilt, and anything built before it used a stale cli. If the cli fails to build, `build-all` now stops with a clear message instead of building the rest with a broken cli. `--from` a later package skips the cli as before; `--from @_linked/cli` builds it and then everything; `--sync` is unaffected.
8
+
9
+ - [#260](https://github.com/linked-fw/cli/pull/260) [`8e2e54a`](https://github.com/linked-fw/cli/commit/8e2e54ab03319c74d4382944eeeca048c272d242) Thanks [@flyon](https://github.com/flyon)! - `linked build-all`'s end-of-run summary now shows, under each package that failed to build, a short excerpt of why: the lines of its output that look like errors (`error TS…` with file and line, `Error: …` with its first stack frame, `npm ERR!` lines that say something), without npm's lifecycle boilerplate, de-duplicated, truncated and capped at 8 lines, falling back to the last lines of output when nothing looks like an error. The full output is still printed inline when the failure happens; the excerpt makes the cause visible at the end without scrolling back through the interleaved parallel builds.
10
+
11
+ ## 1.46.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [#250](https://github.com/linked-fw/cli/pull/250) [`293c265`](https://github.com/linked-fw/cli/commit/293c265b166a99ca5ebf3ed6d5cc966cd35ca4e0) Thanks [@flyon](https://github.com/flyon)! - `linked create-app --template react-native` now scaffolds an app on `@_linked/react` 2 and the framework releases built on it: `@_linked/react` 2.0.1 (was 1.6.4), `@_linked/schema` 1.5.0 (was 1.4.0), `@_linked/core` 2.28.1 (was 2.26.0; React 2 needs `^2.27.0`), `@_linked/server` 2.24.8, `@_linked/server-utils` 1.12.3, `@_linked/fuseki` 3.4.2, `@_linked/s3` 1.6.2 and `@_linked/cli` 1.45.6. The pins stay exact. `npm ls @_linked/react --all` in a new app shows only 2.0.1; before, `@_linked/primitives` 1.8.0 (through `@_linked/schema`) installed a second copy, 2.0.1, next to the app's 1.6.4.
16
+
17
+ A new app also has one React again. `@_linked/server` 2.24.5 and later take `react` and `react-dom` as peers, and npm resolved the peers of hoisted packages to the newest React (19.3.0) at the root, nesting the app's 19.2.3 under `apps/mobile`, so `npm run check:react` failed and `@_linked/react` loaded a different React from the app. The root `package.json` now pins `react` 19.2.3, `services/api` pins `react` next to its `react-dom`, and `apps/mobile` pins `react-dom` 19.2.3 (without it, `npm install` failed with `ERESOLVE`: `react-dom@19.3.0` wants `react@^19.3.0`).
18
+
19
+ With React 2, mounted components refetch after a mutation and identical queries share one request. The template's `nativeDefaults` test gives its loading and error cases a subject each, because the error case otherwise joined the loading case's request, which never settles. Existing apps are not changed.
20
+
21
+ Minor rather than patch: the CLI's commands do not change, but a newly generated app runs on a new major of `@_linked/react`, with its reactive refetching.
22
+
3
23
  ## 1.45.6
4
24
 
5
25
  ### Patch Changes
@@ -60,9 +60,12 @@ cd apps/mobile && npx expo export --platform ios --output-dir /tmp/export
60
60
 
61
61
  ## React Native specifics
62
62
 
63
- - **One React.** `npm ls react` lists extra React copies nested under `@_linked/server` and
64
- `@_linked/server-utils`; the app never loads them, which `npm run check:react` verifies. Do not use
65
- `--legacy-peer-deps`: it would hide a duplicate React.
63
+ - **One React.** React is a peer of the `@_linked/*` packages, and npm resolves the peers of hoisted packages
64
+ at the repo root. Without a pin there, npm puts the newest React at the root and nests the app's 19.2.3
65
+ under `apps/mobile`, so `@_linked/react` and `react-native` would load a different React from the app.
66
+ The root `package.json` therefore pins `react` to the same version as `apps/mobile`, and every workspace
67
+ that depends on `@_linked/server` pins `react-dom` with it. `npm run check:react` verifies the result. Do
68
+ not use `--legacy-peer-deps`: it would hide a duplicate React.
66
69
  - **Workspaces are enumerated**, never globbed, so foreign repositories checked out under `packages/` are not
67
70
  adopted. `.gitignore` uses `packages/*` plus a negation per workspace package (`packages/` cannot be negated).
68
71
  - **Metro** (`apps/mobile/metro.config.js`) watches the workspace root and searches both `node_modules`
@@ -45,7 +45,7 @@ const flush = () => new Promise((resolve) => setTimeout(resolve, 0));
45
45
  describe('@_linked/react/native render defaults', () => {
46
46
  test('a loading component renders only React Native elements', async () => {
47
47
  mode = 'loading';
48
- await render(<ExampleLabel of={{ id: 'urn:example:1' }} />);
48
+ await render(<ExampleLabel of={{ id: 'urn:example:loading' }} />);
49
49
 
50
50
  expect(lowercaseHostTypes(screen.toJSON() as any)).toEqual([]);
51
51
  expect(screen.getByTestId('linked-loader')).toBeTruthy();
@@ -53,7 +53,9 @@ describe('@_linked/react/native render defaults', () => {
53
53
 
54
54
  test('a failed component renders only React Native elements', async () => {
55
55
  mode = 'error';
56
- await render(<ExampleLabel of={{ id: 'urn:example:1' }} />);
56
+ // A subject of its own: @_linked/react shares one request per query and subject, so reusing the loading
57
+ // test's subject would join its request, which never settles, and never reach the error state.
58
+ await render(<ExampleLabel of={{ id: 'urn:example:error' }} />);
57
59
  // Let the rejected query settle and the component re-render into its error state.
58
60
  await act(flush);
59
61
 
@@ -11,15 +11,16 @@
11
11
  "test:integration": "jest -c jest.integration.config.js --runInBand"
12
12
  },
13
13
  "dependencies": {
14
- "@_linked/core": "2.26.0",
15
- "@_linked/react": "1.6.4",
16
- "@_linked/schema": "1.4.0",
17
- "@_linked/server": "2.24.0",
14
+ "@_linked/core": "2.28.3",
15
+ "@_linked/react": "2.0.1",
16
+ "@_linked/schema": "1.5.0",
17
+ "@_linked/server": "2.24.8",
18
18
  "app-shapes": "*",
19
19
  "expo": "57.0.25",
20
20
  "expo-constants": "57.0.19",
21
21
  "expo-dev-client": "57.0.19",
22
22
  "react": "19.2.3",
23
+ "react-dom": "19.2.3",
23
24
  "react-native": "0.86.3"
24
25
  },
25
26
  "devDependencies": {
@@ -1,7 +1,8 @@
1
1
  // Example PersonOverview — demonstrates @_linked/react's data binding:
2
2
  // linkedSetComponent for the list (auto-runs the query, injects results and
3
3
  // an injected _refresh); linkedComponent for each row (see PersonPreview).
4
- // After Person.create the form calls _refresh() to re-run the list query.
4
+ // The list refetches by itself after Person.create; the form also calls the
5
+ // list's _refresh() through context, to show how to re-run a query by hand.
5
6
  // A React Native port of the web app-template's example (linked-fw/app-template).
6
7
  //
7
8
  // `linkedSetComponent` checks LinkedStorage when this module loads, so storage is imported first.
@@ -1,8 +1,10 @@
1
1
  // Example PersonPreview — single-Person row. Demonstrates @_linked/react's
2
2
  // linkedComponent: the wrapper runs the per-row query and injects query
3
- // result keys + `source` + `_refresh` into the render function. _refresh
4
- // patches local query state for optimistic UI; on delete, the parent
5
- // list re-runs via the PersonListRefresh context.
3
+ // result keys + `source` + `_refresh` into the render function. After a
4
+ // mutation, every mounted component whose query can read the changed data
5
+ // refetches by itself; _refresh patches the shared cached result first, for
6
+ // optimistic UI, and on delete the PersonListRefresh context re-runs the list
7
+ // explicitly.
6
8
  // A React Native port of the web app-template's example (linked-fw/app-template).
7
9
  // Storage is imported first, so the row's queries go to the API store however this module is reached.
8
10
  import '../shell/storage';
@@ -16,9 +16,12 @@
16
16
  "test": "npm test -w apps/mobile && npm test -w services/api",
17
17
  "test:integration": "npm run test:integration -w apps/mobile"
18
18
  },
19
+ "dependencies": {
20
+ "react": "19.2.3"
21
+ },
19
22
  "devDependencies": {
20
23
  "eslint": "9.39.5",
21
24
  "eslint-config-expo": "57.0.2",
22
- "typescript-eslint": "8.70.1"
25
+ "typescript-eslint": "8.71.0"
23
26
  }
24
27
  }
@@ -16,9 +16,9 @@
16
16
  "build": "linked build"
17
17
  },
18
18
  "dependencies": {
19
- "@_linked/core": "2.26.0"
19
+ "@_linked/core": "2.28.3"
20
20
  },
21
21
  "devDependencies": {
22
- "@_linked/cli": "1.40.0"
22
+ "@_linked/cli": "1.46.0"
23
23
  }
24
24
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // One React for the app: `react` resolved from apps/mobile, from the installed @_linked/react and from react-native
3
- // must be the same file. `npm ls react` is not used because @_linked/server and @_linked/server-utils nest their
4
- // own copies, which the app never loads.
3
+ // must be the same file. It checks resolution rather than `npm ls react`, because what matters is the file each
4
+ // of them loads: a second copy nested under apps/mobile (see the README) passes `npm ls` and still splits React.
5
5
  import { existsSync, readFileSync, realpathSync } from 'node:fs';
6
6
  import { createRequire } from 'node:module';
7
7
  import { dirname, join, resolve } from 'node:path';
@@ -39,9 +39,9 @@ that port is the one Docker Compose publishes for this repo's `fuseki` service.
39
39
 
40
40
  ## Dependencies
41
41
 
42
- `react-dom` is a direct dependency although the API renders no pages: `LinkedServer` imports `react-dom/server`
43
- at load time, and the root React is 19.2.3 (for `apps/mobile`), so `@_linked/server`'s own `react-dom` 18 is
44
- nested where Vite SSR cannot resolve it. Pinning `react-dom` 19.2.3 here hoists it next to the root React.
42
+ `react` and `react-dom` are direct dependencies although the API renders no pages: `LinkedServer` imports
43
+ `react-dom/server` at load time, and `@_linked/server` takes both as peers. They are pinned to the React that
44
+ `apps/mobile` uses (19.2.3), so npm installs one copy of each at the root instead of the newest release.
45
45
 
46
46
  `linked start` finds the hoisted `app-shapes` workspace and runs in workspace mode: Vite loads `app-shapes` from
47
47
  `src` through its `development` export condition, while published packages such as `@_linked/core` and
@@ -14,18 +14,19 @@
14
14
  "test": "node --experimental-strip-types --no-warnings=ExperimentalWarning --test test/*.test.mjs"
15
15
  },
16
16
  "dependencies": {
17
- "@_linked/core": "2.26.0",
18
- "@_linked/fuseki": "3.4.0",
19
- "@_linked/s3": "1.6.0",
20
- "@_linked/schema": "1.4.0",
21
- "@_linked/server": "2.24.0",
22
- "@_linked/server-utils": "1.12.0",
17
+ "@_linked/core": "2.28.3",
18
+ "@_linked/fuseki": "3.4.2",
19
+ "@_linked/s3": "1.6.2",
20
+ "@_linked/schema": "1.5.0",
21
+ "@_linked/server": "2.24.8",
22
+ "@_linked/server-utils": "1.12.3",
23
23
  "app-shapes": "*",
24
+ "react": "19.2.3",
24
25
  "react-dom": "19.2.3"
25
26
  },
26
27
  "devDependencies": {
27
- "@_linked/cli": "1.40.0",
28
- "@types/node": "22.20.4",
28
+ "@_linked/cli": "1.46.0",
29
+ "@types/node": "22.20.5",
29
30
  "typescript": "6.0.3"
30
31
  }
31
32
  }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Pick the few lines of a failed build's output that show why it failed.
3
+ *
4
+ * `build-all` builds packages in parallel, so a failure's full output is
5
+ * printed inline, interleaved with everything else. Its end-of-run summary
6
+ * repeats a short excerpt under each failed package so the cause is visible
7
+ * without scrolling back. This is that excerpt: lines that look like errors
8
+ * (`error TS…`, `Error:`, `npm ERR!`, …) with the first stack frame after
9
+ * each, without npm's lifecycle boilerplate, de-duplicated and truncated. When
10
+ * nothing looks like an error, the last meaningful lines are used instead.
11
+ */
12
+ export declare function excerptBuildError(output: string, maxLines?: number, maxWidth?: number): string[];
13
+ //# sourceMappingURL=build-error-excerpt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-error-excerpt.d.ts","sourceRoot":"","sources":["../../src/build-error-excerpt.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,SAAI,EACZ,QAAQ,SAAM,GACb,MAAM,EAAE,CA+CV"}
@@ -0,0 +1,97 @@
1
+ import { stripVTControlCharacters } from 'util';
2
+ /**
3
+ * Pick the few lines of a failed build's output that show why it failed.
4
+ *
5
+ * `build-all` builds packages in parallel, so a failure's full output is
6
+ * printed inline, interleaved with everything else. Its end-of-run summary
7
+ * repeats a short excerpt under each failed package so the cause is visible
8
+ * without scrolling back. This is that excerpt: lines that look like errors
9
+ * (`error TS…`, `Error:`, `npm ERR!`, …) with the first stack frame after
10
+ * each, without npm's lifecycle boilerplate, de-duplicated and truncated. When
11
+ * nothing looks like an error, the last meaningful lines are used instead.
12
+ */
13
+ export function excerptBuildError(output, maxLines = 8, maxWidth = 160) {
14
+ const lines = stripVTControlCharacters(output || '')
15
+ .split(/\r?\n/)
16
+ .map((l) => l.replace(/\s+$/, ''));
17
+ const picked = [];
18
+ let errorLines = 0;
19
+ for (let i = 0; i < lines.length; i++) {
20
+ const line = lines[i];
21
+ if (isNoise(line) || !isErrorLine(line))
22
+ continue;
23
+ picked.push(line.trim());
24
+ errorLines++;
25
+ // Keep the first stack frame of a thrown error: where it came from.
26
+ const next = lines[i + 1];
27
+ if (next !== undefined && isStackFrame(next))
28
+ picked.push(next);
29
+ }
30
+ let chosen;
31
+ if (errorLines > 0) {
32
+ chosen = picked;
33
+ }
34
+ else {
35
+ // Nothing looks like an error: show how the output ended.
36
+ let seenFrame = false;
37
+ chosen = lines.filter((line) => {
38
+ if (isNoise(line))
39
+ return false;
40
+ if (isStackFrame(line)) {
41
+ if (seenFrame)
42
+ return false;
43
+ seenFrame = true;
44
+ }
45
+ return true;
46
+ });
47
+ chosen = chosen.slice(-maxLines);
48
+ }
49
+ const unique = [];
50
+ const seen = new Set();
51
+ for (const line of chosen) {
52
+ const key = line.trim();
53
+ if (seen.has(key))
54
+ continue;
55
+ seen.add(key);
56
+ unique.push(truncate(line, maxWidth));
57
+ }
58
+ if (unique.length <= maxLines)
59
+ return unique;
60
+ const shown = unique.slice(0, maxLines - 1);
61
+ shown.push(`… ${unique.length - shown.length} more`);
62
+ return shown;
63
+ }
64
+ function truncate(line, maxWidth) {
65
+ return line.length > maxWidth ? line.slice(0, maxWidth - 1) + '…' : line;
66
+ }
67
+ function isStackFrame(line) {
68
+ return /^\s+at\s/.test(line);
69
+ }
70
+ /** Error-looking lines worth showing first. */
71
+ function isErrorLine(line) {
72
+ return (/\berror TS\d+\b/.test(line) ||
73
+ /^\s*(Uncaught\s+)?([A-Z]\w*)?(Error|Exception)\b(\s*\[[^\]]*\])?:/.test(line) ||
74
+ /^\s*(npm ERR!|npm error)\s/.test(line) ||
75
+ /^\s*(error|ERROR|✘ \[ERROR\])\b:?\s/.test(line) ||
76
+ /^\s*\S+:\d+(:\d+)?\s*-?\s*error\b/i.test(line) ||
77
+ /\bERR_[A-Z_]+\b/.test(line) ||
78
+ /\b(Cannot find (module|name)|Module not found|Could not resolve)\b/.test(line));
79
+ }
80
+ /** Lines that never explain a failure: npm lifecycle chatter and Node's throw site. */
81
+ function isNoise(line) {
82
+ const t = line.trim();
83
+ if (t === '')
84
+ return true;
85
+ return (/^npm (notice|warn|WARN|info|timing|verb|http)\b/.test(t) ||
86
+ // npm's own report that the script failed, and where its log went.
87
+ /^(npm ERR!|npm error)\s+(code\b|errno\b|path\b|workspace\b|location\b|command\b|syscall\b|signal\b|A complete log|Lifecycle script|Failed at|This is probably|Exit status|Tell the author|You can get|Make sure|Check the|\S+@\S+ build:|$)/.test(t) ||
88
+ /^(npm ERR!|npm error)$/.test(t) ||
89
+ /^>\s/.test(t) ||
90
+ /^node:internal\//.test(t) ||
91
+ /^triggerUncaughtException\(/.test(t) ||
92
+ /^\^+$/.test(t) ||
93
+ /^Node\.js v\d/.test(t) ||
94
+ /^(error )?Command failed with exit code \d+\.?$/.test(t) ||
95
+ /^info Visit https:\/\/yarnpkg\.com/.test(t));
96
+ }
97
+ //# sourceMappingURL=build-error-excerpt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-error-excerpt.js","sourceRoot":"","sources":["../../src/build-error-excerpt.ts"],"names":[],"mappings":"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","sourcesContent":["import {stripVTControlCharacters} from 'util';\n\n/**\n * Pick the few lines of a failed build's output that show why it failed.\n *\n * `build-all` builds packages in parallel, so a failure's full output is\n * printed inline, interleaved with everything else. Its end-of-run summary\n * repeats a short excerpt under each failed package so the cause is visible\n * without scrolling back. This is that excerpt: lines that look like errors\n * (`error TS…`, `Error:`, `npm ERR!`, …) with the first stack frame after\n * each, without npm's lifecycle boilerplate, de-duplicated and truncated. When\n * nothing looks like an error, the last meaningful lines are used instead.\n */\nexport function excerptBuildError(\n output: string,\n maxLines = 8,\n maxWidth = 160,\n): string[] {\n const lines = stripVTControlCharacters(output || '')\n .split(/\\r?\\n/)\n .map((l) => l.replace(/\\s+$/, ''));\n\n const picked: string[] = [];\n let errorLines = 0;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (isNoise(line) || !isErrorLine(line)) continue;\n picked.push(line.trim());\n errorLines++;\n // Keep the first stack frame of a thrown error: where it came from.\n const next = lines[i + 1];\n if (next !== undefined && isStackFrame(next)) picked.push(next);\n }\n\n let chosen: string[];\n if (errorLines > 0) {\n chosen = picked;\n } else {\n // Nothing looks like an error: show how the output ended.\n let seenFrame = false;\n chosen = lines.filter((line) => {\n if (isNoise(line)) return false;\n if (isStackFrame(line)) {\n if (seenFrame) return false;\n seenFrame = true;\n }\n return true;\n });\n chosen = chosen.slice(-maxLines);\n }\n\n const unique: string[] = [];\n const seen = new Set<string>();\n for (const line of chosen) {\n const key = line.trim();\n if (seen.has(key)) continue;\n seen.add(key);\n unique.push(truncate(line, maxWidth));\n }\n\n if (unique.length <= maxLines) return unique;\n const shown = unique.slice(0, maxLines - 1);\n shown.push(`… ${unique.length - shown.length} more`);\n return shown;\n}\n\nfunction truncate(line: string, maxWidth: number): string {\n return line.length > maxWidth ? line.slice(0, maxWidth - 1) + '…' : line;\n}\n\nfunction isStackFrame(line: string): boolean {\n return /^\\s+at\\s/.test(line);\n}\n\n/** Error-looking lines worth showing first. */\nfunction isErrorLine(line: string): boolean {\n return (\n /\\berror TS\\d+\\b/.test(line) ||\n /^\\s*(Uncaught\\s+)?([A-Z]\\w*)?(Error|Exception)\\b(\\s*\\[[^\\]]*\\])?:/.test(line) ||\n /^\\s*(npm ERR!|npm error)\\s/.test(line) ||\n /^\\s*(error|ERROR|✘ \\[ERROR\\])\\b:?\\s/.test(line) ||\n /^\\s*\\S+:\\d+(:\\d+)?\\s*-?\\s*error\\b/i.test(line) ||\n /\\bERR_[A-Z_]+\\b/.test(line) ||\n /\\b(Cannot find (module|name)|Module not found|Could not resolve)\\b/.test(\n line,\n )\n );\n}\n\n/** Lines that never explain a failure: npm lifecycle chatter and Node's throw site. */\nfunction isNoise(line: string): boolean {\n const t = line.trim();\n if (t === '') return true;\n return (\n /^npm (notice|warn|WARN|info|timing|verb|http)\\b/.test(t) ||\n // npm's own report that the script failed, and where its log went.\n /^(npm ERR!|npm error)\\s+(code\\b|errno\\b|path\\b|workspace\\b|location\\b|command\\b|syscall\\b|signal\\b|A complete log|Lifecycle script|Failed at|This is probably|Exit status|Tell the author|You can get|Make sure|Check the|\\S+@\\S+ build:|$)/.test(\n t,\n ) ||\n /^(npm ERR!|npm error)$/.test(t) ||\n /^>\\s/.test(t) ||\n /^node:internal\\//.test(t) ||\n /^triggerUncaughtException\\(/.test(t) ||\n /^\\^+$/.test(t) ||\n /^Node\\.js v\\d/.test(t) ||\n /^(error )?Command failed with exit code \\d+\\.?$/.test(t) ||\n /^info Visit https:\\/\\/yarnpkg\\.com/.test(t)\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cli-methods.d.ts","sourceRoot":"","sources":["../../src/cli-methods.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-methods.d.ts","sourceRoot":"","sources":["../../src/cli-methods.ts"],"names":[],"mappings":"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"}
@@ -76,7 +76,8 @@ function assertInsidePackage(sourceFolder, command) {
76
76
  // have to graph-walk the rest of cli-methods.ts (which contains many
77
77
  // dynamic imports Vite can't analyze). We import for internal callers
78
78
  // AND re-export so external consumers can keep importing from here.
79
- import { ensureEnvironmentLoaded, loadBackendStorageConfig, getLincdPackages, discoverLocalPackages, planBuildAll, } from './lifecycle.js';
79
+ import { ensureEnvironmentLoaded, loadBackendStorageConfig, getLincdPackages, discoverLocalPackages, planBuildAll, orderBuildToolFirst, } from './lifecycle.js';
80
+ import { excerptBuildError } from './build-error-excerpt.js';
80
81
  export { ensureEnvironmentLoaded, loadBackendStorageConfig, getLincdPackages, discoverLocalPackages, planBuildAll, };
81
82
  var variables = {};
82
83
  /**
@@ -762,62 +763,115 @@ function printBuildAllPlan(plan) {
762
763
  console.log(chalk.yellow(` - ${skip.packageName}: ${skip.reason}`));
763
764
  }
764
765
  }
766
+ /**
767
+ * Run one package's own `build` script. Resolves to true when it built, false
768
+ * when it built with warnings, and undefined when it failed (the failure has
769
+ * been printed, and its output is kept in `failureOutput` when given, for the
770
+ * summary).
771
+ */
772
+ function runBuildScript(pkg, failureOutput) {
773
+ var _a;
774
+ // Invoke the package's own `build` script. This lets each package
775
+ // own its build pipeline — e.g. @_linked/core uses direct tsc, pure-CSS
776
+ // packages may have no-op builds, and linkedPackage: true packages
777
+ // typically call `linked build` internally.
778
+ //
779
+ // npm is the default; the package manager is detected per package so
780
+ // packages inside an existing yarn workspace still build with yarn.
781
+ const pkgDir = path.join(process.cwd(), pkg.path);
782
+ const pkgJson = getPackageJSON(pkgDir);
783
+ if (!((_a = pkgJson === null || pkgJson === void 0 ? void 0 : pkgJson.scripts) === null || _a === void 0 ? void 0 : _a.build)) {
784
+ // No build script — skip gracefully (e.g. a pure-assets package).
785
+ return Promise.resolve(true);
786
+ }
787
+ const buildCmd = runScriptCommand(detectPackageManager(pkgDir), 'build');
788
+ return execPromise(buildCmd, false, false, { cwd: pkgDir })
789
+ .then((res) => res === '' || typeof res === 'string')
790
+ .catch((err) => {
791
+ // A non-zero exit is a failed build. Report it and resolve to
792
+ // undefined, which is what the callers read as failure. Resolving to an
793
+ // error object would count as built.
794
+ const output = [err === null || err === void 0 ? void 0 : err.stdout, err === null || err === void 0 ? void 0 : err.stderr].filter(Boolean).join('\n');
795
+ failureOutput === null || failureOutput === void 0 ? void 0 : failureOutput.set(pkg.packageName, output);
796
+ console.error(chalk.red(pkg.packageName + ' build failed') +
797
+ (output ? '\n' + output : ''));
798
+ return undefined;
799
+ });
800
+ }
765
801
  export function buildAll(options) {
766
802
  console.log('Building all linked packages of this repository in order of dependencies');
767
803
  const plan = planBuildAll('./', findAppRoot() || undefined);
768
804
  printBuildAllPlan(plan);
769
- let lincdPackages = plan.build;
770
- if (lincdPackages.size === 0) {
805
+ if (plan.build.size === 0) {
771
806
  console.log(chalk.yellow('Nothing to build.'));
772
807
  return;
773
808
  }
809
+ // The build tool goes first and alone: every other build runs it.
810
+ const order = orderBuildToolFirst(plan.build, options === null || options === void 0 ? void 0 : options.from);
811
+ const sync = (options === null || options === void 0 ? void 0 : options.sync) || false;
812
+ // Successfully built (or deliberately passed over by --from).
813
+ const done = new Set();
814
+ if (!order.tool) {
815
+ return buildInDependencyOrder(order.rest, order.from, sync, done);
816
+ }
817
+ const tool = order.tool;
818
+ if (!order.buildToolFirst) {
819
+ log(chalk.blue('skipping ' + tool.packageName));
820
+ done.add(tool);
821
+ return buildInDependencyOrder(order.rest, order.from, sync, done);
822
+ }
823
+ // This process has already loaded every module `build-all` uses (the
824
+ // command's code is imported statically), so the tool's `rimraf ./lib`
825
+ // cannot pull anything out from under it.
826
+ console.log(chalk.blue(`Building ${tool.packageName} first: the other packages build with it.`));
827
+ return runBuildScript(tool).then((res) => {
828
+ if (typeof res === 'undefined') {
829
+ const others = order.rest.size;
830
+ console.error(chalk.red(`${tool.packageName} failed to build, so build-all stopped before ` +
831
+ `the other ${others} package${others === 1 ? '' : 's'}: they build with it. ` +
832
+ `Fix ${tool.packageName} and run build-all again.`));
833
+ process.exit(1);
834
+ return;
835
+ }
836
+ log(chalk.green('Built ' + tool.packageName) +
837
+ (res === false ? chalk.redBright(' (with warnings)') : ''));
838
+ done.add(tool);
839
+ if (order.rest.size === 0) {
840
+ printBuildAllSummary(done, new Set(), new Map(), [], new Map());
841
+ return;
842
+ }
843
+ return buildInDependencyOrder(order.rest, order.from, sync, done);
844
+ });
845
+ }
846
+ function buildInDependencyOrder(lincdPackages, from, sync, done) {
774
847
  let startFrom;
775
848
  //by default start building
776
849
  let building = true;
777
- let from = options === null || options === void 0 ? void 0 : options.from;
778
- let sync = (options === null || options === void 0 ? void 0 : options.sync) || false;
779
- // console.log('from', from);
780
- // console.log('sync', sync);
781
- // process.exit();
782
850
  //option to start from a specific package in the stack
783
851
  if (from) {
784
852
  startFrom = from;
785
853
  //if we have a startFrom, then we havnt started the build process yet
786
- building = startFrom ? false : true;
787
- //clear targets
788
- // target = '';
789
- // target2 = '';
854
+ building = false;
790
855
  console.log(chalk.blue('Will skip builds until ' + startFrom));
791
- // return async (pkg) => {};
792
856
  }
793
- // if (target2 == 'from') {
794
- // startFrom = target3;
795
- // //if we have a startFrom, then we havnt started the build process yet
796
- // building = startFrom ? false : true;
797
- //
798
- // //clear targets
799
- // target2 = '';
800
- // target3 = '';
801
- // console.log(chalk.blue('Will skip builds until ' + startFrom));
802
- //
803
- // // return async (pkg) => {};
804
- // }
805
- // Successfully built (or deliberately passed over by --from).
806
- let done = new Set();
807
857
  // Packages whose own build script failed.
808
858
  let failed = new Set();
809
859
  // Packages not built because a dependency failed or was itself not built,
810
860
  // mapped to the failed package(s) at the root of that chain.
811
861
  let notBuilt = new Map();
862
+ // The output of each failed build, by package name, for the summary.
863
+ const failureOutput = new Map();
812
864
  progressUpdate(lincdPackages.size + ' packages left');
813
865
  let packagesLeft = lincdPackages.size;
866
+ // `done` may already hold the build tool, built before this ran.
867
+ const doneBefore = done.size;
814
868
  const finished = runOnPackagesGroupedByDependencies(lincdPackages, (packageGroup, dependencies) => {
815
- if (done.size > 0) {
869
+ if (done.size > doneBefore) {
816
870
  debugInfo(chalk.magenta('\n-------\nThese packages are next, since all their dependencies have now been build:'));
817
871
  }
818
872
  debugInfo('Now building: ' + chalk.blue(packageGroup.map((i) => i.packageName)));
819
873
  return (pkg) => __awaiter(this, void 0, void 0, function* () {
820
- var _a, _b;
874
+ var _a;
821
875
  // A package whose dependency failed (directly or further down the
822
876
  // chain) cannot be built against it. Report it instead of building it,
823
877
  // and keep building everything else.
@@ -853,38 +907,7 @@ export function buildAll(options) {
853
907
  }
854
908
  //unless told otherwise, build the package
855
909
  if (!command) {
856
- // Invoke the package's own `build` script. This lets each package
857
- // own its build pipeline — e.g. @_linked/core uses direct tsc, pure-CSS
858
- // packages may have no-op builds, and linkedPackage: true packages
859
- // typically call `linked build` internally.
860
- //
861
- // npm is the default; the package manager is detected per package so
862
- // packages inside an existing yarn workspace still build with yarn.
863
- const pkgDir = path.join(process.cwd(), pkg.path);
864
- const pkgJson = getPackageJSON(pkgDir);
865
- const hasBuildScript = !!((_b = pkgJson === null || pkgJson === void 0 ? void 0 : pkgJson.scripts) === null || _b === void 0 ? void 0 : _b.build);
866
- if (!hasBuildScript) {
867
- // No build script — skip gracefully (e.g. a pure-assets package).
868
- command = Promise.resolve(true);
869
- }
870
- else {
871
- const buildCmd = runScriptCommand(detectPackageManager(pkgDir), 'build');
872
- command = execPromise(buildCmd, false, false, {
873
- cwd: pkgDir,
874
- })
875
- .then((res) => res === '' || typeof res === 'string')
876
- .catch((err) => {
877
- // A non-zero exit is a failed build. Report it and resolve to
878
- // undefined, which is what the result handler below reads as
879
- // failure. Resolving to an error object would count as built.
880
- const output = [err === null || err === void 0 ? void 0 : err.stdout, err === null || err === void 0 ? void 0 : err.stderr]
881
- .filter(Boolean)
882
- .join('\n');
883
- console.error(chalk.red(pkg.packageName + ' build failed') +
884
- (output ? '\n' + output : ''));
885
- return undefined;
886
- });
887
- }
910
+ command = runBuildScript(pkg, failureOutput);
888
911
  log(chalk.cyan('Building ' + pkg.packageName));
889
912
  process.stdout.write(packagesLeft + ' packages left\r');
890
913
  }
@@ -933,7 +956,7 @@ export function buildAll(options) {
933
956
  }
934
957
  }
935
958
  }
936
- printBuildAllSummary(done, failed, notBuilt, unscheduled);
959
+ printBuildAllSummary(done, failed, notBuilt, unscheduled, failureOutput);
937
960
  if (failed.size > 0 || notBuilt.size > 0 || unscheduled.length > 0) {
938
961
  process.exit(1);
939
962
  }
@@ -942,10 +965,21 @@ export function buildAll(options) {
942
965
  }
943
966
  /**
944
967
  * The end-of-run report of `build-all`: what was built, every package whose
945
- * build failed, and every package that was not built because of one.
968
+ * build failed with a few lines of why, and every package that was not built
969
+ * because of one.
946
970
  */
947
- function printBuildAllSummary(done, failed, notBuilt, unscheduled) {
971
+ function printBuildAllSummary(done, failed, notBuilt, unscheduled, failureOutput) {
948
972
  printBuildResults([...failed].map((p) => p.packageName), done);
973
+ for (const pkg of failed) {
974
+ const excerpt = excerptBuildError(failureOutput.get(pkg.packageName) || '');
975
+ console.warn(chalk.red(` ${pkg.packageName}:`) +
976
+ '\n' +
977
+ (excerpt.length > 0 ? excerpt : ['(no output)'])
978
+ .map((line) => chalk.gray(' | ') + line)
979
+ .join('\n'));
980
+ }
981
+ if (failed.size > 0)
982
+ console.warn('');
949
983
  if (notBuilt.size > 0) {
950
984
  warn(`Not built (${notBuilt.size}) because a dependency failed:\n` +
951
985
  [...notBuilt]