@_linked/cli 1.16.0 → 1.18.0

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 (37) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +8 -9
  3. package/defaults/package/package.json +6 -6
  4. package/defaults/setup-publish/github/workflows/pr.yml +29 -0
  5. package/defaults/setup-publish/github/workflows/publish.yml +17 -70
  6. package/lib/esm/cli-methods.d.ts.map +1 -1
  7. package/lib/esm/cli-methods.js +49 -26
  8. package/lib/esm/cli-methods.js.map +1 -1
  9. package/lib/esm/cli.js +3 -3
  10. package/lib/esm/cli.js.map +1 -1
  11. package/lib/esm/commands/build-package.d.ts.map +1 -1
  12. package/lib/esm/commands/build-package.js +18 -10
  13. package/lib/esm/commands/build-package.js.map +1 -1
  14. package/lib/esm/commands/setup-publish.d.ts +39 -4
  15. package/lib/esm/commands/setup-publish.d.ts.map +1 -1
  16. package/lib/esm/commands/setup-publish.js +142 -83
  17. package/lib/esm/commands/setup-publish.js.map +1 -1
  18. package/lib/esm/config-webpack.js +2 -2
  19. package/lib/esm/config-webpack.js.map +1 -1
  20. package/lib/esm/utils/packageManager.d.ts +22 -0
  21. package/lib/esm/utils/packageManager.d.ts.map +1 -0
  22. package/lib/esm/utils/packageManager.js +48 -0
  23. package/lib/esm/utils/packageManager.js.map +1 -0
  24. package/lib/esm/utils/packageSetup.d.ts +6 -1
  25. package/lib/esm/utils/packageSetup.d.ts.map +1 -1
  26. package/lib/esm/utils/packageSetup.js +14 -3
  27. package/lib/esm/utils/packageSetup.js.map +1 -1
  28. package/lib/esm/utils.js +1 -1
  29. package/lib/esm/utils.js.map +1 -1
  30. package/package.json +9 -8
  31. package/defaults/setup-publish/dual-branch/changeset/README.md +0 -20
  32. package/defaults/setup-publish/dual-branch/changeset/config.json +0 -14
  33. package/defaults/setup-publish/dual-branch/github/workflows/changeset-check.yml +0 -43
  34. package/defaults/setup-publish/dual-branch/github/workflows/ci.yml +0 -44
  35. package/defaults/setup-publish/dual-branch/github/workflows/publish.yml +0 -191
  36. package/defaults/setup-publish/github/workflows/changeset-check.yml +0 -44
  37. package/defaults/setup-publish/github/workflows/ci.yml +0 -43
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.18.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#98](https://github.com/linked-fw/cli/pull/98) [`0d2c4c0`](https://github.com/linked-fw/cli/commit/0d2c4c04f7354af8add4a31c2780597b61d27098) Thanks [@flyon](https://github.com/flyon)! - `setup-publish` scaffolds the consolidated pipeline: two thin caller stubs (`pr.yml`, `publish.yml`) for the shared reusable workflows in `linked-fw/.github` instead of three standalone workflows, and `--configure-github` applies the uniform branch-protection profile (required check `checks / Build & Test`, non-strict, admins enforced). `publishConfig.provenance` is no longer stripped now that publishing is OIDC-first, and `--dual-branch` is a deprecated no-op.
8
+
9
+ ## 1.17.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#94](https://github.com/linked-fw/cli/pull/94) [`b4140fd`](https://github.com/linked-fw/cli/commit/b4140fdb7ed0face4978d5436e0cee2876eb1d09) Thanks [@flyon](https://github.com/flyon)! - npm is now the CLI's default package manager; yarn is detected, not assumed.
14
+
15
+ A new `detectPackageManager()` walks up from the directory being acted on and
16
+ only reports `yarn` when the tree actually is a yarn project (`yarn.lock`,
17
+ `.yarnrc.yml`, a vendored `.yarn/releases/`). The nearest marker wins, so an npm
18
+ package checked out inside a yarn workspace is treated as npm. Everything else
19
+ is npm. Existing yarn monorepos keep working; `linked yarn` (safe-yarn) is
20
+ unchanged.
21
+
22
+ What changed per command:
23
+
24
+ - `linked build-workspace` runs each package's build with `npm run build`
25
+ instead of always `yarn build` (still `yarn build` inside a yarn workspace).
26
+ - `linked build <path>` (the editor hook) invokes the `linked` binary via
27
+ `npx --no-install` instead of always `yarn exec` (yarn, including a vendored
28
+ release, is still used inside a yarn workspace).
29
+ - `linked create-package` installs with npm unless the new package lands inside
30
+ an existing yarn project. `planPackageSetup()` gained an
31
+ `insideYarnProject` argument; having yarn on `PATH` no longer selects it. The
32
+ closing hint now names the package manager that was actually used.
33
+ - `linked publish` uses `npm version … --no-git-tag-version && npm publish`
34
+ outside a yarn project (Berry's `yarn version` / `yarn npm publish` is kept
35
+ inside one).
36
+ - The backend TS compile step uses `npx --no-install tsc` outside a yarn
37
+ project.
38
+ - Capacitor setup installs with npm and writes `npx cap …` / `npm run …`
39
+ scripts instead of `yarn cap …`.
40
+ - The `create-package` template (`defaults/package/package.json`) builds with
41
+ `npm run …` and bare local bins, so a scaffolded package no longer needs yarn.
42
+
43
+ Also: the CLI's own `build`, `dev`, `test` and `format` scripts no longer shell
44
+ out to `yarn`, so `npm run build` works without yarn installed (previously it
45
+ failed under Yarn Berry with "the nearest package directory doesn't seem to be
46
+ part of the project", and needed a Yarn 1 shim). Stale yarn mentions in the
47
+ README, help text and comments now say npm.
48
+
49
+ ### Patch Changes
50
+
51
+ - [#94](https://github.com/linked-fw/cli/pull/94) [`2ec3601`](https://github.com/linked-fw/cli/commit/2ec3601cd473ffbcbd6bfd5fdf4031c28efb48ab) Thanks [@flyon](https://github.com/flyon)! - Declare npm as the package manager for this repo and mark `package-lock.json` as a generated file.
52
+
3
53
  ## 1.16.0
4
54
 
5
55
  ### Minor Changes
package/README.md CHANGED
@@ -6,8 +6,6 @@ Command-line tools for the `@_linked/*` packages and apps.
6
6
 
7
7
  ```bash
8
8
  npm install --save-dev @_linked/cli
9
- # or
10
- yarn add -D @_linked/cli
11
9
  ```
12
10
 
13
11
  ## Binaries
@@ -48,15 +46,15 @@ exits 0.
48
46
  ### Publishing / release
49
47
 
50
48
  ```bash
51
- linked setup-publish # install a changesets-based publish workflow in the current repo
52
- linked setup-publish --dual-branch # use main + dev with @next prereleases
53
- linked setup-publish --configure-github # also set branch protection via gh CLI
49
+ linked setup-publish # install the changesets-based publish pipeline in the current repo
50
+ linked setup-publish --configure-github # also apply the uniform branch protection via gh CLI
54
51
  linked setup-publish --scope community # use NPM_AUTH_TOKEN_CM instead of NPM_AUTH_TOKEN
55
52
  ```
56
53
 
57
54
  `setup-publish` writes:
58
55
 
59
- - `.github/workflows/ci.yml`, `publish.yml`, `changeset-check.yml`
56
+ - `.github/workflows/pr.yml` and `publish.yml` — thin callers of the shared reusable workflows in
57
+ `linked-fw/.github`, pinned `@v1`. Any pre-consolidation `ci.yml` / `changeset-check.yml` is removed.
60
58
  - `.changeset/config.json` + `README.md`
61
59
  - `.gitignore` entries
62
60
  - `publishConfig: {access: public}` + `@changesets/cli` devDeps in `package.json`
@@ -129,7 +127,8 @@ API-only mode is never inferred: a web app without a `vite.config.*` and without
129
127
 
130
128
  ```bash
131
129
  cd packages/cli
132
- yarn build
130
+ npm install
131
+ npm run build
133
132
  ```
134
133
 
135
134
  Dual ESM + CJS build via `tsconfig-to-dual-package`. Sources in `src/`, output in `lib/esm/` and `lib/cjs/`.
@@ -141,7 +140,7 @@ Templates live in `defaults/`:
141
140
  - `defaults/app-with-backend/` — used by `linked create-app`
142
141
  - `defaults/app-static/` — minimal static app
143
142
  - `defaults/package/` — used by `linked create-package`
144
- - `defaults/setup-publish/` — workflow + changeset files written by `linked setup-publish` (single-branch default; `dual-branch/` subdirectory for the `--dual-branch` variant)
143
+ - `defaults/setup-publish/` — caller workflows + changeset files written by `linked setup-publish` (`main`-only; `--dual-branch` is a deprecated no-op)
145
144
 
146
145
  ### `linked create-app` template structure
147
146
 
@@ -208,7 +207,7 @@ cd apps/mobile && npx expo export --platform ios --output-dir /tmp/export
208
207
 
209
208
  To run it: `npm run fuseki:up`, `npm run api`, then `cd apps/mobile && npx expo run:ios`.
210
209
 
211
- Tests for this template in this repo: `yarn test:unit` covers the scaffold offline, using the fixture in
210
+ Tests for this template in this repo: `npm run test:unit` covers the scaffold offline, using the fixture in
212
211
  `tests/fixtures/app-react-native-min` and the real template. `npm run test:template` runs the built CLI with
213
212
  install, then checks the generated files, `check:react`, lint, typecheck, `npm test`, the shapes build and a
214
213
  Metro iOS bundle. It builds nothing itself, needs network and takes several minutes.
@@ -17,12 +17,12 @@
17
17
  "types": "lib/esm/index.d.ts",
18
18
  "license": "ISC",
19
19
  "scripts": {
20
- "start": "yarn linked dev",
21
- "build": "rimraf ./lib && yarn build-esm && yarn build-cjs && yarn copy-to-lib && yarn dual-package",
22
- "build-esm": "echo \"compiling ESM\" && rimraf ./lib/esm && yarn tsc -p tsconfig-esm.json",
23
- "build-cjs": "echo \"compiling CJS\" && rimraf ./lib/cjs && yarn tsc -p tsconfig-cjs.json",
24
- "copy-to-lib": "echo 'copying CSS + JSON assets to lib folder' && yarn copyfiles -u 1 'src/**/*.css' 'src/**/*.json' lib/esm && yarn copyfiles -u 1 'src/**/*.css' 'src/**/*.json' lib/cjs",
25
- "dual-package": "echo 'adding package.json to each lib folder for dual output support' && yarn tsconfig-to-dual-package ./tsconfig-cjs.json ./tsconfig-esm.json"
20
+ "start": "linked dev",
21
+ "build": "rimraf ./lib && npm run build-esm && npm run build-cjs && npm run copy-to-lib && npm run dual-package",
22
+ "build-esm": "echo \"compiling ESM\" && rimraf ./lib/esm && tsc -p tsconfig-esm.json",
23
+ "build-cjs": "echo \"compiling CJS\" && rimraf ./lib/cjs && tsc -p tsconfig-cjs.json",
24
+ "copy-to-lib": "echo 'copying CSS + JSON assets to lib folder' && copyfiles -u 1 'src/**/*.css' 'src/**/*.json' lib/esm && copyfiles -u 1 'src/**/*.css' 'src/**/*.json' lib/cjs",
25
+ "dual-package": "echo 'adding package.json to each lib folder for dual output support' && tsconfig-to-dual-package ./tsconfig-cjs.json ./tsconfig-esm.json"
26
26
  },
27
27
  "keywords": [
28
28
  "linked",
@@ -0,0 +1,29 @@
1
+ # Calls the shared workflow in linked-fw/.github, which runs both PR gates — `Build & Test` and
2
+ # `Check for changeset` — as jobs of one workflow. The per-repo ci.yml and changeset-check.yml
3
+ # this replaces shared a trigger and were both PR gates.
4
+ #
5
+ # The required status check on `main` is `checks / Build & Test`: GitHub reports a job invoked
6
+ # through `workflow_call` as `<caller-job-id> / <job name>`, and the caller job below is `checks`.
7
+ # Renaming this job renames the check, and a branch protection still pinning the old name waits
8
+ # forever on a check that no longer reports.
9
+ name: PR
10
+
11
+ on:
12
+ pull_request:
13
+ branches:
14
+ - main
15
+
16
+ jobs:
17
+ checks:
18
+ uses: linked-fw/.github/.github/workflows/pr.yml@v1
19
+ # The changeset reminder posts a PR comment. A reusable workflow only holds what its caller
20
+ # granted it, and the org default is read-only.
21
+ permissions:
22
+ contents: read
23
+ pull-requests: write
24
+ with:
25
+ # Left false so a package with no test script passes instead of failing on a missing one.
26
+ # Set to true — and `test-script` to the unit-only script where `test` is not CI-safe —
27
+ # once this package has a suite that must exist.
28
+ require-tests: false
29
+ run-e2e: false
@@ -1,3 +1,9 @@
1
+ # Calls the shared workflow in linked-fw/.github. That repo is public, so community repos in
2
+ # linked-cm call the same workflow — only the npm secret differs.
3
+ #
4
+ # This FILENAME is what npm's trusted-publisher check validates — not the shared workflow's.
5
+ # Renaming this file invalidates this package's trusted publisher, and the only symptom is
6
+ # that releases quietly start needing manual approval again.
1
7
  name: Publish
2
8
 
3
9
  on:
@@ -9,76 +15,17 @@ concurrency: ${{ github.workflow }}-${{ github.ref }}
9
15
 
10
16
  jobs:
11
17
  release:
12
- name: Publish Release
13
- runs-on: ubuntu-latest
18
+ uses: linked-fw/.github/.github/workflows/publish.yml@v1
14
19
  permissions:
15
20
  contents: write
16
21
  pull-requests: write
17
- steps:
18
- # Author the changesets "Version Packages" PR as the org release App (not the default
19
- # GITHUB_TOKEN) so its CI runs without a manual "Approve and run" gate. Requires the org
20
- # App installed on this repo + org secrets RELEASE_APP_ID / RELEASE_APP_PRIVATE_KEY.
21
- - name: Generate GitHub App token
22
- id: app-token
23
- uses: actions/create-github-app-token@v2
24
- with:
25
- app-id: ${{ secrets.RELEASE_APP_ID }}
26
- private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
27
-
28
- - name: Checkout
29
- uses: actions/checkout@v4
30
- with:
31
- token: ${{ steps.app-token.outputs.token }}
32
-
33
- - name: Setup Node.js
34
- uses: actions/setup-node@v4
35
- with:
36
- node-version: 22.16.0
37
- registry-url: 'https://registry.npmjs.org'
38
-
39
- - name: Install dependencies
40
- run: npm ci --legacy-peer-deps
41
-
42
- - name: Build
43
- run: npm run build
44
-
45
- - name: Create release Pull Request or Publish
46
- id: changesets
47
- uses: changesets/action@v1
48
- with:
49
- publish: npx changeset publish
50
- title: 'chore: release'
51
- commit: 'chore: release'
52
- # npm auth uses the npm token below. Do NOT switch to OIDC trusted publishing
53
- # (id-token: write + publishConfig.provenance) unless you FIRST register this package's
54
- # trusted publisher on npmjs.com — otherwise publishes fail with 404 / permission errors.
55
- env:
56
- GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
57
- NODE_AUTH_TOKEN: ${{ secrets.{{NPM_SECRET_NAME}} }}
58
- NPM_TOKEN: ${{ secrets.{{NPM_SECRET_NAME}} }}
59
-
60
- # When changesets opened/updated the version PR (rather than publishing), merge it so the
61
- # release ships without a manual click. The App token is used so the merge's push to `main`
62
- # re-triggers this workflow, which — now that no changesets remain — runs `changeset publish`.
63
- #
64
- # NB: DIRECT-merge (not `--auto`). If `main` requires a review, GitHub's auto-merge queue does
65
- # NOT honor branch-protection review-bypass allowances and would wait forever on
66
- # REVIEW_REQUIRED; a required *status check* is not bypassable either. This repo's `main` is
67
- # check-only (no required review), so a direct merge succeeds once the required check is
68
- # green — we retry until then.
69
- - name: Merge the version PR to publish
70
- if: steps.changesets.outputs.hasChangesets == 'true' && steps.changesets.outputs.published != 'true'
71
- env:
72
- GH_TOKEN: ${{ steps.app-token.outputs.token }}
73
- run: |
74
- pr=$(gh pr list --base main --head changeset-release/main --state open --json number --jq '.[0].number // empty')
75
- if [ -z "$pr" ]; then echo "No open version PR (nothing to merge)."; exit 0; fi
76
- for i in $(seq 1 40); do
77
- if gh pr merge "$pr" --merge 2>/tmp/merge_err; then
78
- echo "Merged version PR #$pr on attempt $i — publish will run on the resulting push to main."
79
- exit 0
80
- fi
81
- echo "Attempt $i/40: version PR #$pr not mergeable yet ($(tr -d '\n' < /tmp/merge_err)); waiting for the required check…"
82
- sleep 15
83
- done
84
- echo "::warning::Version PR #$pr not merged after retries — merge it manually to publish."
22
+ # Needed HERE as well as in the shared workflow: a reusable workflow cannot widen the
23
+ # permissions its caller was granted, and without this npm never gets an id-token and
24
+ # every release silently falls back to the staged approval queue.
25
+ id-token: write
26
+ # Named rather than `inherit`: `inherit` forwards everything this repo can see, which is
27
+ # how a community repo would end up forwarding a first-party token.
28
+ secrets:
29
+ NPM_TOKEN: ${{ secrets.{{NPM_SECRET_NAME}} }}
30
+ RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
31
+ RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
@@ -1 +1 @@
1
- {"version":3,"file":"cli-methods.d.ts","sourceRoot":"","sources":["../../src/cli-methods.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAgBpD;;;;;;GAMG;AAKH,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAC,uBAAuB,EAAE,wBAAwB,EAAE,gBAAgB,EAAC,CAAC;AAoB7E,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,cAAc,CAAC;AAEjD,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,SAAS,GAAU,SAAI,EAAE,iBAAwB,EAAE,UAAS;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,WAAW,CAAA;CAAM,kBA4LtL,CAAC;AAEF;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAcR;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AAkBrD,2EAA2E;AAC3E,eAAO,MAAM,eAAe,eAAe,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAM3E;AA8BD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EACpB,EAAE,EAAE,WAAW,EACf,OAAO,GAAE;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAM,GAC1D,OAAO,CAAC,IAAI,CAAC,CAkGf;AAGD,eAAO,MAAM,oBAAoB;;CAA2B,CAAC;AAW7D;;;;;;;;;GASG;AACH;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,QASzD;AAuED,wBAAgB,IAAI,CAAC,GAAG,QAAQ,OAAA,QAK/B;AACD,wBAAgB,QAAQ,CAAC,GAAG,MAAM,OAAA,QAIjC;AACD,wBAAgB,cAAc,CAAC,MAAM,KAAA,EAAE,IAAI,KAAA,QAyB1C;AA2CD,wBAAgB,kCAAkC,CAChD,aAAa,KAAA,EACb,YAAY,EAAE,CACZ,YAAY,KAAA,EACZ,YAAY,KAAA,KACT,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,GAAG,CAAC,EAC1C,UAAU,KAAA,EACV,IAAI,UAAQ,GACX,OAAO,CAAC,IAAI,CAAC,CAqNf;AA+ID,wBAAgB,QAAQ,CAAC,OAAO,KAAA,QAkU/B;AA2ED,eAAO,MAAM,cAAc,GACzB,WAAM,EACN,aAAQ,EACR,iBAAwB,kBA6FzB,CAAC;AAmBF,eAAO,MAAM,gBAAgB,GAAa,iBAAiB,MAAM,EAAE,OAAM,MAAsB,WAkB9F,CAAC;AAIF,eAAO,MAAM,cAAc,GACzB,SAAI,EACJ,mBAAmB,MAAM,EACzB,OAAM,MAAsB,EAC5B,gBAAe,OAAe,WAsC/B,CAAC;AA+BF,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,cAAsB,CAAC;AAEhE,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CAI5D;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CAE1D;AAyBD,eAAO,MAAM,gBAAgB,GAAa,SAAI;;;;;CAc7C,CAAC;AAgBF;;GAEG;AACH,eAAO,MAAM,YAAY,cAaxB,CAAC;AACF,eAAO,MAAM,WAAW,GAAU,SAAI,EAAE,iBAAwB,kBA0B/D,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,SAAI,EAAE,iBAAwB,kBAmCtE,CAAC;AACF,eAAO,MAAM,eAAe,GAAU,SAAI,EAAE,iBAAwB,kBAuCnE,CAAC;AAMF,eAAO,MAAM,YAAY,GACvB,eAAc,MAA0B,EACxC,QAAO,MAAU,EAAE,wDAAwD;AAC3E,iBAAgB,GAAG,CAAC,MAAM,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,EAAE,CAAa,qBA2F9E,CAAC;AAEF,eAAO,MAAM,cAAc,qBAuB1B,CAAC;AACF,eAAO,MAAM,QAAQ,GAAU,cAAa,MAAsB,qBAwDjE,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,YAAY,MAAM,EAClB,SAAS;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,mBAoB1B,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,aAAa,MAAM,EACnB,QAAQ,MAAM,EACd,SAAS;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,kBAiH1B,CAAC;AACF,eAAO,MAAM,WAAW,GACtB,WAAU,OAAe,EACzB,iBAAkB,iBA8DnB,CAAC;AACF,eAAO,MAAM,QAAQ,sBAKpB,CAAC;AACF,eAAO,MAAM,aAAa,qBAqHzB,CAAC;AACF,eAAO,MAAM,YAAY,wBAiExB,CAAC;AAEF,eAAO,MAAM,eAAe,qBAoK3B,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,SAAI,EACJ,aAAQ,EACR,iBAAwB,kBA4HzB,CAAC;AAqBF,eAAO,MAAM,QAAQ,GAAa,gBAAW,kBAuD5C,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,WAAM,EACN,YAAO,EACP,oBAA2B,EAC3B,aAAY,OAAc,qBAyK3B,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,MAAM,CAAC;IAGb,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AAMF,eAAO,MAAM,cAAc,GAAI,YAAO,EAAE,aAAa,MAAM,KAAG,SAAS,EA8GtE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,oBAA2B,kBAyB/D,CAAC;AACF,eAAO,MAAM,iBAAiB,GAAU,oBAA2B,qBAWlE,CAAC;AACF,eAAO,MAAM,iBAAiB,GAAU,oBAA2B;;EAelE,CAAC;AAEF,eAAO,IAAI,cAAc,GAAa,OAAM,OAAe,kBA0K1D,CAAC;AAsBF,eAAO,IAAI,cAAc,GACvB,SAAI,EACJ,UAAK,EACL,UAAK,EACL,oBAAe,oBA6DhB,CAAC;AAEF,eAAO,IAAI,YAAY,GACrB,SAAI,EACJ,WAAM,EACN,YAAO,EACP,wBAAuB,OAAe,EACtC,OAAM,OAAe,kBAiHtB,CAAC;AAeF,eAAO,IAAI,4BAA4B,GACrC,aAAQ,EACR,YAAO,EACP,iBAAY,EACZ,gBAAW,qBA4CZ,CAAC;AAOF,eAAO,IAAI,cAAc,GAAa,aAAQ,EAAE,YAAO,SAMtD,CAAC;AACF,eAAO,IAAI,YAAY,GAAmB,iBAAwB,kBA8FjE,CAAC;AAEF,eAAO,IAAI,wBAAwB,GAAa,gBAAW,EAAE,YAAO,SA6BnE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAU,gBAAW,qBA8B/C,CAAC"}
1
+ {"version":3,"file":"cli-methods.d.ts","sourceRoot":"","sources":["../../src/cli-methods.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@ import { createInterface } from 'readline';
17
17
  import { debugInfo, execp, execPromise, getFileImports, getFiles, getLastCommitTime, getPackageJSON, isImportOutsideOfPackage, isInternalLinkedImport, needsRebuilding, } from './utils.js';
18
18
  import { renameShippedDotfiles } from './utils/shippedDotfiles.js';
19
19
  import { planPackageSetup } from './utils/packageSetup.js';
20
+ import { detectPackageManager, execBinCommand, runScriptCommand, } from './utils/packageManager.js';
20
21
  import { rewriteExtensionlessImports } from './utils/esmSpecifiers.js';
21
22
  import { spawn as spawnChild } from 'child_process';
22
23
  import { findNearestPackageJson } from 'find-nearest-package-json';
@@ -433,7 +434,7 @@ function applyAppIdentity(targetFolder, ids) {
433
434
  }
434
435
  }
435
436
  function logHelp() {
436
- execp('yarn exec lincd help');
437
+ execp(execBinCommand(detectPackageManager(), 'linked help'));
437
438
  }
438
439
  function log(...messages) {
439
440
  messages.forEach((message) => {
@@ -884,10 +885,13 @@ export function buildAll(options) {
884
885
  }
885
886
  //unless told otherwise, build the package
886
887
  if (!command) {
887
- // Invoke the package's own `yarn build` script. This lets each package
888
+ // Invoke the package's own `build` script. This lets each package
888
889
  // own its build pipeline — e.g. @_linked/core uses direct tsc, pure-CSS
889
890
  // packages may have no-op builds, and linkedPackage: true packages
890
- // typically call `yarn linked build` internally.
891
+ // typically call `linked build` internally.
892
+ //
893
+ // npm is the default; the package manager is detected per package so
894
+ // packages inside an existing yarn workspace still build with yarn.
891
895
  const pkgDir = path.join(process.cwd(), pkg.path);
892
896
  const pkgJson = getPackageJSON(pkgDir);
893
897
  const hasBuildScript = !!((_a = pkgJson === null || pkgJson === void 0 ? void 0 : pkgJson.scripts) === null || _a === void 0 ? void 0 : _a.build);
@@ -896,7 +900,8 @@ export function buildAll(options) {
896
900
  command = Promise.resolve(true);
897
901
  }
898
902
  else {
899
- command = execPromise('yarn build', false, false, {
903
+ const buildCmd = runScriptCommand(detectPackageManager(pkgDir), 'build');
904
+ command = execPromise(buildCmd, false, false, {
900
905
  cwd: pkgDir,
901
906
  })
902
907
  .then((res) => res === '' || typeof res === 'string')
@@ -1638,7 +1643,7 @@ export const runMethod = (packageName, method, options) => __awaiter(void 0, voi
1638
1643
  if (error.code === 'ECONNREFUSED' ||
1639
1644
  ((_a = error.cause) === null || _a === void 0 ? void 0 : _a.code) === 'ECONNREFUSED') {
1640
1645
  console.error(chalk.red('Could not connect to the backend server. Is it running?'));
1641
- console.error(`Make sure you ${chalk.magenta('run "yarn start" in a separate process')} before calling this method.`);
1646
+ console.error(`Make sure you ${chalk.magenta('run "npm start" in a separate process')} before calling this method.`);
1642
1647
  }
1643
1648
  else {
1644
1649
  console.error('Error during backend call:', error);
@@ -1833,7 +1838,7 @@ export const buildBackend = () => __awaiter(void 0, void 0, void 0, function* ()
1833
1838
  text: 'Compiling backend TS files',
1834
1839
  }).start();
1835
1840
  try {
1836
- yield execPromise(`yarn exec tsc`);
1841
+ yield execPromise(execBinCommand(detectPackageManager(), 'tsc'));
1837
1842
  compileSpinner.succeed('Backend TS files compiled');
1838
1843
  }
1839
1844
  catch (e) {
@@ -2071,11 +2076,17 @@ export const createPackage = (name_1, uriBase_1, ...args_1) => __awaiter(void 0,
2071
2076
  console.log('rename ', path.join(targetFolder, f), path.join(targetFolder, ...newParts, newName));
2072
2077
  fs.renameSync(path.join(targetFolder, f), path.join(targetFolder, ...newParts, newName));
2073
2078
  });
2074
- let version = (yield execPromise('yarn --version').catch((err) => {
2075
- console.log('yarn probably not working');
2076
- return '';
2077
- }));
2078
- const setup = planPackageSetup(version.toString(), path.join(getScriptDir(), 'launch.js'));
2079
+ // npm is the default for a new package. yarn is only consulted when the new
2080
+ // package lands inside an existing yarn project (an mrgit/yarn-3 monorepo),
2081
+ // where adding an npm lockfile would break the workspace.
2082
+ const insideYarnProject = detectPackageManager(path.dirname(path.resolve(targetFolder))) === 'yarn';
2083
+ let version = insideYarnProject
2084
+ ? (yield execPromise('yarn --version').catch(() => {
2085
+ console.log('yarn probably not working');
2086
+ return '';
2087
+ }))
2088
+ : '';
2089
+ const setup = planPackageSetup(version.toString(), path.join(getScriptDir(), 'launch.js'), process.execPath, insideYarnProject);
2079
2090
  if (setup.yarnrc) {
2080
2091
  fs.writeFileSync(path.join(targetFolder, '.yarnrc.yml'), setup.yarnrc);
2081
2092
  }
@@ -2094,7 +2105,7 @@ export const createPackage = (name_1, uriBase_1, ...args_1) => __awaiter(void 0,
2094
2105
  process.exitCode = 1;
2095
2106
  });
2096
2107
  }
2097
- log(`Prepared a new LINCD package in ${chalk.magenta(targetFolder)}`, `Run ${chalk.blueBright('yarn build')} from this directory to build once`, `Or ${chalk.blueBright('yarn dev')} to continuously rebuild on file changes`);
2108
+ log(`Prepared a new LINCD package in ${chalk.magenta(targetFolder)}`, `Run ${chalk.blueBright(runScriptCommand(setup.packageManager, 'build'))} from this directory to build once`, `Or ${chalk.blueBright(runScriptCommand(setup.packageManager, 'start'))} to continuously rebuild on file changes`);
2098
2109
  });
2099
2110
  var getNextVersion = function (version) {
2100
2111
  let parts = version.split('.');
@@ -2649,7 +2660,13 @@ export var publishPackage = function (pkg, test, info, publishVersion) {
2649
2660
  console.log(chalk.blue('publishing ' + pkg.packageName + ' ' + publishVersion));
2650
2661
  //looking for an .env.json file in our workspace, which may store our NPM AUTH key
2651
2662
  let envJsonPath = yield getEnvJsonPath(pkg.path);
2652
- return execPromise(`cd ${pkg.path} && ${envJsonPath ? `env-cmd -f ${envJsonPath} --use-shell "` : ''}yarn version ${publishVersion} && yarn npm publish${envJsonPath ? `"` : ''}`, true, false, {}, true)
2663
+ // `yarn version` / `yarn npm publish` is Yarn Berry syntax. Only use it when
2664
+ // the package really lives in a yarn project; otherwise publish with npm.
2665
+ const publishPm = detectPackageManager(pkg.path);
2666
+ const versionAndPublish = publishPm === 'yarn'
2667
+ ? `yarn version ${publishVersion} && yarn npm publish`
2668
+ : `npm version ${publishVersion} --no-git-tag-version && npm publish`;
2669
+ return execPromise(`cd ${pkg.path} && ${envJsonPath ? `env-cmd -f ${envJsonPath} --use-shell "` : ''}${versionAndPublish}${envJsonPath ? `"` : ''}`, true, false, {}, true)
2653
2670
  .then((res) => {
2654
2671
  if (res.indexOf('Aborted due to warnings') !== -1 ||
2655
2672
  res.indexOf('Could not publish') !== -1 ||
@@ -2858,18 +2875,18 @@ export var addCapacitor = function () {
2858
2875
  'env-cmd -e _main, staging node scripts/build.js';
2859
2876
  pack.scripts['fix-app'] = 'node scripts/fix-namespace.js';
2860
2877
  pack.scripts['app'] =
2861
- 'env-cmd -e _main,production,app-main node scripts/build.js && npx cap sync && yarn run fix-app';
2878
+ 'env-cmd -e _main,production,app-main node scripts/build.js && npx cap sync && npm run fix-app';
2862
2879
  pack.scripts['app-local-ios'] =
2863
- 'env-cmd -e _main,development,app-main,app-local-ios node scripts/build.js && npx cap sync && yarn run fix-app';
2880
+ 'env-cmd -e _main,development,app-main,app-local-ios node scripts/build.js && npx cap sync && npm run fix-app';
2864
2881
  pack.scripts['app-local-android'] =
2865
- 'env-cmd -e _main,development,app-main,app-local-android node scripts/build.js && npx cap sync && yarn run fix-app';
2866
- pack.scripts['cap:android'] = 'yarn cap open android';
2867
- pack.scripts['cap:ios'] = 'yarn cap open ios';
2868
- pack.scripts['cap:sync'] = 'yarn cap sync';
2882
+ 'env-cmd -e _main,development,app-main,app-local-android node scripts/build.js && npx cap sync && npm run fix-app';
2883
+ pack.scripts['cap:android'] = 'npx cap open android';
2884
+ pack.scripts['cap:ios'] = 'npx cap open ios';
2885
+ pack.scripts['cap:sync'] = 'npx cap sync';
2869
2886
  fs.writeFile(path.resolve(basePath, 'package.json'), JSON.stringify(pack, null, 2));
2870
2887
  log('Added new run script to package.json');
2871
- yield execPromise(`yarn add -D @capacitor/cli`, true, false, null, true);
2872
- yield execPromise(`yarn add @capacitor/android @capacitor/core @capacitor/app @capacitor/ios`, false, false, null, true);
2888
+ yield execPromise(`npm install --save-dev @capacitor/cli`, true, false, null, true);
2889
+ yield execPromise(`npm install @capacitor/android @capacitor/core @capacitor/app @capacitor/ios`, false, false, null, true);
2873
2890
  // TODO: Do we need to add `npx cap init`? If yes, we should not copy capacitor config.ts yet
2874
2891
  // await execPromise(`npx cap init`, true, false, null, true);
2875
2892
  // got error:
@@ -2878,21 +2895,27 @@ export var addCapacitor = function () {
2878
2895
  // [error] Non-interactive shell detected.
2879
2896
  // Run the command with --help to see a list of arguments that must be provided.
2880
2897
  log(`Done! Now update your Capacitor configuration by providing an app name, app ID, and web directory at ${chalk.blue('capacitor.config.ts')}`);
2881
- log(`And then run ${chalk.magenta('yarn cap add android')} and/or ${chalk.magenta('yarn cap add ios')}')`);
2882
- log(`Last, run ${chalk.magenta('yarn app')} or ${chalk.magenta('yarn app-local-ios')} or ${chalk.magenta('yarn app-local-android')}`);
2898
+ log(`And then run ${chalk.magenta('npx cap add android')} and/or ${chalk.magenta('npx cap add ios')}')`);
2899
+ log(`Last, run ${chalk.magenta('npm run app')} or ${chalk.magenta('npm run app-local-ios')} or ${chalk.magenta('npm run app-local-android')}`);
2883
2900
  });
2884
2901
  };
2885
2902
  export var executeCommandForPackage = function (packageName, command) {
2886
2903
  let packageDetails = getLincdPackages().find((modDetails) => modDetails.packageName.indexOf(packageName) !== -1 ||
2887
2904
  modDetails.packageName.indexOf(packageName) !== -1);
2888
2905
  if (packageDetails) {
2906
+ // npm is the default; only a package inside a yarn project is driven with
2907
+ // yarn (`yarn linked <cmd>` resolves the bin from the yarn workspace).
2908
+ const pm = detectPackageManager(packageDetails.path);
2909
+ // Windows quirk: the shim is `yarn.cmd` / `npx.cmd`.
2910
+ const isWin = process.platform === 'win32';
2911
+ const runner = pm === 'yarn' ? (isWin ? 'yarn.cmd' : 'yarn') : isWin ? 'npx.cmd' : 'npx';
2912
+ const runnerArgs = pm === 'yarn' ? ['linked'] : ['--no-install', 'linked'];
2889
2913
  log("Executing 'cd " +
2890
2914
  packageDetails.path +
2891
- ' && yarn lincd' +
2915
+ ` && ${runner} linked` +
2892
2916
  (command ? ' ' + command : '') +
2893
2917
  "'");
2894
- spawnChild(process.platform === 'win32' ? 'yarn.cmd' : 'yarn', // Windows quirk
2895
- ['lincd', command || null], {
2918
+ spawnChild(runner, [...runnerArgs, command || null], {
2896
2919
  cwd: packageDetails.path,
2897
2920
  stdio: 'inherit',
2898
2921
  });