@_linked/cli 1.14.0 → 1.16.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 (33) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/README.md +19 -22
  3. package/defaults/app-react-native/README.md +4 -4
  4. package/defaults/app-react-native/apps/mobile/__tests__/composePort.test.ts +33 -0
  5. package/defaults/app-react-native/apps/mobile/__tests__/integration/apiEnv.ts +27 -1
  6. package/defaults/app-react-native/apps/mobile/__tests__/integration/globalSetup.ts +11 -7
  7. package/defaults/app-react-native/apps/mobile/jest.integration.config.js +1 -1
  8. package/defaults/app-react-native/apps/mobile/src/components/PersonOverview.tsx +1 -1
  9. package/defaults/app-react-native/apps/mobile/src/components/PersonPreview.tsx +1 -1
  10. package/defaults/app-react-native/packages/app-shapes/package.json +0 -3
  11. package/lib/esm/cli-methods.d.ts +29 -1
  12. package/lib/esm/cli-methods.d.ts.map +1 -1
  13. package/lib/esm/cli-methods.js +151 -169
  14. package/lib/esm/cli-methods.js.map +1 -1
  15. package/lib/esm/cli.js +18 -8
  16. package/lib/esm/cli.js.map +1 -1
  17. package/lib/esm/commands/start.d.ts +12 -0
  18. package/lib/esm/commands/start.d.ts.map +1 -1
  19. package/lib/esm/commands/start.js +63 -9
  20. package/lib/esm/commands/start.js.map +1 -1
  21. package/lib/esm/utils/esmSpecifiers.d.ts +5 -1
  22. package/lib/esm/utils/esmSpecifiers.d.ts.map +1 -1
  23. package/lib/esm/utils/esmSpecifiers.js +44 -10
  24. package/lib/esm/utils/esmSpecifiers.js.map +1 -1
  25. package/lib/esm/utils.d.ts +16 -7
  26. package/lib/esm/utils.d.ts.map +1 -1
  27. package/lib/esm/utils.js +92 -40
  28. package/lib/esm/utils.js.map +1 -1
  29. package/lib/esm/vite-config.d.ts +17 -0
  30. package/lib/esm/vite-config.d.ts.map +1 -1
  31. package/lib/esm/vite-config.js +42 -8
  32. package/lib/esm/vite-config.js.map +1 -1
  33. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,128 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#93](https://github.com/linked-fw/cli/pull/93) [`4b944dc`](https://github.com/linked-fw/cli/commit/4b944dc5a0a37b7858cb8f34d078879965f8b648) Thanks [@flyon](https://github.com/flyon)! - `create-app` now scaffolds web apps with npm.
8
+
9
+ The web template used to install with yarn (and prompted for a package manager
10
+ when both were on PATH); it now always runs `npm install`, matching the
11
+ react-native template, and the next-steps message prints `npm start`. The empty
12
+ `yarn.lock` that create-app wrote to pin down Yarn's project-root search is no
13
+ longer created, so a new app has a single npm lockfile.
14
+
15
+ create-app also strips every yarn project file from the clone (the legacy
16
+ `yarnrc.yml.template` it used to rename into `.yarnrc.yml`, plus `.yarnrc.yml`,
17
+ `.yarn/` and any `yarn.lock` the template still carries), so a scaffolded app is
18
+ an npm project end to end.
19
+
20
+ ## 1.15.3
21
+
22
+ ### Patch Changes
23
+
24
+ - [#73](https://github.com/linked-cm/cli/pull/73) [`92e8f6b`](https://github.com/linked-cm/cli/commit/92e8f6ba07b80f3a72adae9238bd855fc94869b6) Thanks [@abdipramana](https://github.com/abdipramana)! - `linked start --vite`: widen development config discovery so apps that predate
25
+ the current filenames still start.
26
+
27
+ - The app's linked config is now looked up as `linked.config.js` **or** the
28
+ legacy `lincd.config.js` (current name wins when both exist). Apps that never
29
+ renamed the file silently lost their whole `server` block — `cachePaths`,
30
+ `apiOnly` and the rest of LinkedServer's options — because only the new name
31
+ was read. The lookup is exposed as `resolveLinkedConfigPath()`.
32
+ - SSR page discovery also skips `*.d.ts` files in `src/pages/` (alongside the
33
+ existing `.test` / `.spec` skip). Type declarations have no runtime module,
34
+ so preloading them into the SSR graph only produced errors.
35
+ - The backend storage config is discovered under several legacy filenames
36
+ (`backend-storage-config.*`, `scripts/backend-storage-config.*`,
37
+ `scripts/storage-config.js`) in addition to `linked.backend.storage.*`.
38
+
39
+ ## 1.15.2
40
+
41
+ ### Patch Changes
42
+
43
+ - [#71](https://github.com/linked-cm/cli/pull/71) [`b3e482b`](https://github.com/linked-cm/cli/commit/b3e482bdd55a43fb5fe9a11ab58d06e6bea66f5d) Thanks [@carlenmy](https://github.com/carlenmy)! - `createViteConfig`: give each app a unique HMR websocket port, derived from its
44
+ dev port (`PORT` env override, else `opts.port`), instead of Vite's shared
45
+ default `24678`.
46
+
47
+ Every app built on `createViteConfig` defaulted to `24678` for HMR, so running
48
+ two of them at once (parallel worktrees / multiple `@_linked` apps on one
49
+ machine) collided — `WebSocket server error: Port 24678 is already in use`, and
50
+ HMR silently broke for the loser. The port is now `24678 + (devPort - 4040)`, so
51
+ apps that already use distinct dev ports get distinct HMR ports for free.
52
+
53
+ The derivation lives in the new exported `hmrPortFor()` helper and is defensive
54
+ about its input: a `PORT` that is not a whole port number (`PORT=abc`, a
55
+ negative or out-of-range value) falls back to the `4040` default rather than
56
+ producing `NaN`, and the derived port is clamped into `1024`–`65535`. Apps can
57
+ still override via `server.hmr` in their own merged config.
58
+
59
+ ## 1.15.1
60
+
61
+ ### Patch Changes
62
+
63
+ - [#72](https://github.com/linked-cm/cli/pull/72) [`3bab3ab`](https://github.com/linked-cm/cli/commit/3bab3ab287ad72dff74c21f15d93a6229702b0e6) Thanks [@flyon](https://github.com/flyon)! - Backend provider HMR reloads are now debounced and serialised.
64
+
65
+ `vite.watcher.on('change')` called `server.onSourceChange(pkg)` once per changed
66
+ file with no debounce and no queue. Since `onSourceChange` disposes a package's
67
+ providers and re-registers their Express routes, it mutates the shared router
68
+ stack — and a multi-file save, a format-on-save, or a branch switch ran several
69
+ of those dispose/re-register cycles concurrently against that same stack with
70
+ nothing ordering them.
71
+
72
+ Changed packages are now collected over a 150 ms window and their reload cycles
73
+ run one at a time on a promise chain. Reload failures are still logged per
74
+ package and no longer abort the cycles queued behind them.
75
+
76
+ No API change; dev-server behaviour only.
77
+
78
+ ## 1.15.0
79
+
80
+ ### Minor Changes
81
+
82
+ - [#86](https://github.com/linked-cm/cli/pull/86) [`1f8908f`](https://github.com/linked-cm/cli/commit/1f8908fa276a5b65ed3ffe1c1e3bc23417ef9043) Thanks [@flyon](https://github.com/flyon)! - Always rewrite emitted ESM import specifiers
83
+
84
+ `linked build` appends `.js` (or `/index.js`) to relative specifiers in `lib/esm` for every package, with no
85
+ opt-in. The rewrite covers the emitted `.d.ts` declarations as well as the `.js`, so consumers on TypeScript
86
+ `node16`/`nodenext` resolution get valid declarations. For a package that already writes `.js` specifiers the
87
+ rewrite is a no-op.
88
+
89
+ It runs at the end of the build, after the assets and hand-written declarations have been copied into `lib` and
90
+ after stale output has been removed, so every specifier is resolved against the files the package actually ships.
91
+ Asset imports such as `./styles.scss` resolve and are left as written, copied `.d.ts` files are rewritten too, and
92
+ a leftover `x.js` can no longer make `./x` point at a file the cleanup then deletes.
93
+
94
+ Also in this release:
95
+
96
+ - The `missing_extension` rule is gone from the import check, in the build gate and in `linked check-imports`.
97
+ Extensionless relative imports in source no longer fail the build; the rewrite warns about any relative
98
+ specifier it cannot resolve, and Vite, Metro and `tsc` catch the rest. `outside_package` and the
99
+ internal-import rule remain hard errors for every package.
100
+ - The rule that stops a package reaching into another Linked package's internals now actually fires. It matched
101
+ only import paths containing the literal string `lincd`, so after the rename to the `@_linked/*` scope it was a
102
+ no-op for every current package: `@_linked/core/lib/esm/utils/Shape` passed. It now matches `@_linked/<pkg>/...`
103
+ as well as `lincd`-prefixed package names, on a `/src/` or `/lib/` path segment, and is called
104
+ `isInternalLinkedImport`. This can fail builds that previously passed — which is the point: such an import
105
+ breaks when the other package changes its build layout and bypasses its exports map. Import the public subpath
106
+ instead. Relative specifiers are exempt, so a local `./lib/helpers` is still fine.
107
+ - Both import rules now see every form that names a module — `export ... from`, `import()` in value and type
108
+ position, and `import x = require()` — not just `import ... from`.
109
+ - `linked check-imports` prints the report and exits 1 when an import is invalid, instead of exiting 0.
110
+ - `linked build` reports failures accurately: a step that fails names itself instead of a bare "Build failed",
111
+ and a failed build always exits non-zero, including under `--silent` and when building updated packages.
112
+ - `isImportOutsideOfPackage` normalises the path before judging it, so `./a..b` is no longer flagged and
113
+ `../a/../b` is counted as the one level it actually climbs.
114
+ - A relative specifier with a trailing slash (`./file/`) names a directory, so it resolves to `./file/index.js`
115
+ and never to a sibling `./file.js`.
116
+
117
+ A package without a `tsconfig-esm.json` has no ESM build, so the rewrite step is skipped rather than failing. When
118
+ `tsconfig-esm.json` is present but `lib/esm` was not emitted, the build fails.
119
+
120
+ ## 1.14.1
121
+
122
+ ### Patch Changes
123
+
124
+ - [#83](https://github.com/linked-cm/cli/pull/83) [`566cb44`](https://github.com/linked-cm/cli/commit/566cb44f8728f25e852987ed4426063df9575492) Thanks [@flyon](https://github.com/flyon)! - React Native template: the integration test setup now tells apart "Docker is not installed", "Docker Compose is unavailable" and "Compose Fuseki is not running" (unit-tested in the scaffold); the integration Jest config comment says "Integration tests". README: document that `linked build` exits 1 whenever the build does not succeed (including in a `linkedApp` or a package without `linkedPackage: true`), and 0 with warnings. Reworded a stale migration comment in `linked start`.
125
+
3
126
  ## 1.14.0
4
127
 
5
128
  ### Minor Changes
package/README.md CHANGED
@@ -41,6 +41,10 @@ linked build-updated # incremental: only packages that changed sinc
41
41
  linked build-package <file> # walk up from a file path to find its package and rebuild
42
42
  ```
43
43
 
44
+ `linked build` exits with code 1 whenever the build does not succeed, including when it is run in a `linkedApp` or
45
+ in a package without `"linkedPackage": true` (it used to exit 0 there). A build that finishes with warnings still
46
+ exits 0.
47
+
44
48
  ### Publishing / release
45
49
 
46
50
  ```bash
@@ -89,28 +93,21 @@ The CLI recognizes two flags in `package.json`:
89
93
 
90
94
  The legacy `lincd: true` / `lincdApp: true` flags are no longer read. Migrate to `linkedPackage` / `linkedApp`.
91
95
 
92
- ### `"linked": {"extensionlessImports": true}`
93
-
94
- ```json
95
- {
96
- "linkedPackage": true,
97
- "type": "module",
98
- "linked": {"extensionlessImports": true}
99
- }
100
- ```
96
+ ### Extensionless relative imports
101
97
 
102
- By default `linked build` rejects relative imports without an extension (`./shapes/Example`), because Node's ESM
103
- loader cannot resolve them. Set this flag when the package source must use extensionless imports, for example a
104
- shapes package consumed as TypeScript source by Metro (which does not map `.js` specifiers to `.ts` files).
105
- With the flag, `linked build`:
98
+ Package source may use extensionless relative imports (`./shapes/Example` rather than `./shapes/Example.js`) —
99
+ useful for a shapes package consumed as TypeScript source by Metro, which does not map `.js` specifiers to `.ts`
100
+ files. No configuration is needed. After compiling ESM, `linked build` rewrites every relative specifier in
101
+ `lib/esm` — in the emitted `.js` and in the `.d.ts` declarations beside them, so consumers on TypeScript
102
+ `node16`/`nodenext` resolution get valid declarations — to `./x.js` or `./dir/index.js`, so Node can load the
103
+ output. For a package that already writes `.js` specifiers the rewrite is a no-op.
106
104
 
107
- - skips the import check;
108
- - after compiling ESM, rewrites every relative specifier in `lib/esm` (static imports and exports, `export * as`,
109
- side-effect imports and `import()` with a literal) to `./x.js` or `./dir/index.js`, so Node can load the output;
110
- - fails if `lib/esm` was not emitted;
111
- - finishes "with warnings" and lists each specifier it could not resolve (left unchanged).
105
+ The build finishes "with warnings" and lists each relative specifier it could not resolve (left unchanged), and
106
+ fails when `tsconfig-esm.json` is present but `lib/esm` was not emitted. A package without a `tsconfig-esm.json`
107
+ has no ESM build, so the step is skipped.
112
108
 
113
- Requirements: `"linkedPackage": true`, `"type": "module"` and a `tsconfig-esm.json` in the package.
109
+ The import check (`linked check-imports`, also run as the first build step) still fails the build for imports
110
+ that reach outside the package source root, and for imports into another linked package's `/src/` or `/lib/`.
114
111
 
115
112
  ## API-only backend
116
113
 
@@ -148,7 +145,7 @@ Templates live in `defaults/`:
148
145
 
149
146
  ### `linked create-app` template structure
150
147
 
151
- `linked create-app <name>` copies `defaults/app-with-backend/` to the new app's folder, substitutes `${name}` / `${hyphen_name}` / `${app_prefix}` / `${app_domain}` placeholders in selected files, and copies `linked.backend.datasets.example.json` → `linked.backend.datasets.json` so first boot works zero-config.
148
+ `linked create-app <name>` copies `defaults/app-with-backend/` to the new app's folder, substitutes `${name}` / `${hyphen_name}` / `${app_prefix}` / `${app_domain}` placeholders in selected files, and copies `linked.backend.datasets.example.json` → `linked.backend.datasets.json` so first boot works zero-config. Dependencies are installed with `npm install`, and the next-steps message tells you to run `npm start`.
152
149
 
153
150
  Storage configuration follows the two-layer pattern from [backlog 016](https://github.com/c### `linked create-app --template react-native`
154
151
 
@@ -168,8 +165,8 @@ workspaces monorepo for Expo SDK 57 / React Native 0.86 / React 19.2 with an API
168
165
  src/shell/ env.ts (API URL), storage.ts (BackendAPIStore)
169
166
  src/components/ PersonOverview / PersonPreview: example add/edit/delete screen
170
167
  __tests__/ unit tests; __tests__/integration/ runs against the API and Fuseki
171
- packages/<prefix>-shapes/ Linked shapes package: TypeScript source, extensionless imports,
172
- "linked": {"extensionlessImports": true} so `linked build` emits Node-loadable lib/esm
168
+ packages/<prefix>-shapes/ Linked shapes package: TypeScript source with extensionless imports; `linked build`
169
+ rewrites the emitted specifiers so lib/esm is Node-loadable
173
170
  services/api/ API-only backend (`linked start --api-only`) on @_linked/server, Fuseki through
174
171
  linked.backend.datasets.json, node --test unit tests
175
172
  ```
@@ -1,6 +1,6 @@
1
1
  # Linked React Native monorepo
2
2
 
3
- An npm-workspaces monorepo for a [Linked](https://github.com/linked-cm) app on Expo SDK 57 / React Native 0.86 /
3
+ An npm-workspaces monorepo for a [Linked](https://github.com/linked-fw) app on Expo SDK 57 / React Native 0.86 /
4
4
  React 19.2, with an API-only Linked backend on Fuseki.
5
5
 
6
6
  ```
@@ -87,9 +87,9 @@ cd apps/mobile && npx expo export --platform ios --output-dir /tmp/export
87
87
  `@_linked/server/shapes/quadstores/BackendAPIStore`): the root barrel pulls express, webpack and react-dom.
88
88
  ESLint `no-restricted-imports` enforces it.
89
89
  - **Shapes package imports are extensionless** (`./shapes/Example`, not `./shapes/Example.js`): Metro does not
90
- map `.js` specifiers to `.ts` source. `"linked": {"extensionlessImports": true}` in its `package.json` makes
91
- `linked build` skip the import check and add `.js` to the emitted `lib/esm` specifiers. The app, Jest and the
92
- API in development consume `src/` through the `react-native` and `development` export conditions.
90
+ map `.js` specifiers to `.ts` source. No configuration is needed — `linked build` always adds `.js` to the
91
+ relative specifiers in the emitted `lib/esm` JS and declarations. The app, Jest and the API in development
92
+ consume `src/` through the `react-native` and `development` export conditions.
93
93
  - **Decorators** work with the stock `babel-preset-expo`. The one custom Babel plugin,
94
94
  `apps/mobile/babel/stripJsonImportAttributes.js`, strips `with { type: 'json' }` from dynamic `import()`, which
95
95
  Metro rejects and Linked ontology packages use; `__tests__/stripJsonImportAttributes.test.ts` covers it. After
@@ -0,0 +1,33 @@
1
+ import { describeComposePortFailure } from './integration/apiEnv';
2
+
3
+ describe('describeComposePortFailure', () => {
4
+ test('docker not installed', () => {
5
+ const error = Object.assign(new Error('spawnSync docker ENOENT'), { code: 'ENOENT' });
6
+ expect(describeComposePortFailure({ error, status: null })).toMatch(/^Docker is not installed/);
7
+ });
8
+
9
+ test('docker compose unavailable', () => {
10
+ const message = describeComposePortFailure({
11
+ status: 1,
12
+ stderr: "docker: 'compose' is not a docker command.\nSee 'docker --help'",
13
+ });
14
+ expect(message).toMatch(/^Docker Compose is not available/);
15
+ expect(message).toContain('is not a docker command');
16
+ });
17
+
18
+ test('non-zero exit mentioning compose', () => {
19
+ expect(describeComposePortFailure({ status: 125, stderr: 'unknown command: docker compose' })).toMatch(
20
+ /^Docker Compose is not available/,
21
+ );
22
+ });
23
+
24
+ test('service not running', () => {
25
+ const message = describeComposePortFailure({ status: 1, stderr: 'service "fuseki" is not running' });
26
+ expect(message).toMatch(/Compose Fuseki is not running/);
27
+ expect(message).toContain('npm run fuseki:up');
28
+ });
29
+
30
+ test('exit 0 without a port counts as not running', () => {
31
+ expect(describeComposePortFailure({ status: 0, stdout: '' })).toMatch(/Compose Fuseki is not running/);
32
+ });
33
+ });
@@ -28,7 +28,33 @@ export function readApiEnvFile(): Record<string, string> {
28
28
  return existsSync(envFile) ? parseEnvFile(readFileSync(envFile, 'utf8')) : {};
29
29
  }
30
30
 
31
- export type FusekiEnv = { baseUrl: string; user: string; password: string };
31
+ /** The parts of a `spawnSync('docker', ['compose', 'port', 'fuseki', '3030'])` result that explain a failure. */
32
+ export type ComposePortResult = {
33
+ error?: (Error & { code?: string }) | undefined;
34
+ status: number | null;
35
+ stdout?: string | null;
36
+ stderr?: string | null;
37
+ };
38
+
39
+ /**
40
+ * Why `docker compose port fuseki 3030` gave no port: Docker is not installed, Docker Compose is unavailable, or
41
+ * this repo's Compose Fuseki is not running.
42
+ */
43
+ export function describeComposePortFailure(result: ComposePortResult): string {
44
+ const output = (result.stderr || result.error?.message || result.stdout || '').trim();
45
+ if (result.error?.code === 'ENOENT') {
46
+ return 'Docker is not installed or not on PATH (`docker` could not be started). Install Docker, then run `npm run fuseki:up`.';
47
+ }
48
+ const composeMissing =
49
+ /is not a docker command/i.test(output) ||
50
+ (result.status !== 0 && /compose/i.test(output) && !/not running|no container/i.test(output));
51
+ if (composeMissing) {
52
+ return `Docker Compose is not available (\`docker compose port fuseki 3030\`: ${output}). Install the Docker Compose plugin, then run \`npm run fuseki:up\`.`;
53
+ }
54
+ return `this repo's Compose Fuseki is not running (\`docker compose port fuseki 3030\`: ${output}). Run \`npm run fuseki:up\`.`;
55
+ }
56
+
57
+ export type FusekiEnv ={ baseUrl: string; user: string; password: string };
32
58
 
33
59
  /**
34
60
  * The Fuseki the tests talk to. services/api/.env is the source, and the shell wins: FUSEKI_BASE_URL, or
@@ -4,7 +4,16 @@
4
4
  import { type ChildProcess, spawn, spawnSync } from 'node:child_process';
5
5
  import { resolve } from 'node:path';
6
6
 
7
- import { API_PORT, API_URL, FUSEKI_DATASET, apiDir, readApiEnvFile, repoRoot, resolveFusekiEnv } from './apiEnv';
7
+ import {
8
+ API_PORT,
9
+ API_URL,
10
+ FUSEKI_DATASET,
11
+ apiDir,
12
+ describeComposePortFailure,
13
+ readApiEnvFile,
14
+ repoRoot,
15
+ resolveFusekiEnv,
16
+ } from './apiEnv';
8
17
 
9
18
  // The variables that select S3FileStore (services/api/src/fileStoreEnv.ts); blanked even when unset anywhere.
10
19
  const S3_ENV_KEYS = ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_REGION', 'S3_BUCKET_ENDPOINT', 'S3_FILES_BUCKET_NAME'];
@@ -40,12 +49,7 @@ function assertSafeTarget(baseUrl: string) {
40
49
 
41
50
  const compose = spawnSync('docker', ['compose', 'port', 'fuseki', '3030'], { cwd: repoRoot, encoding: 'utf8' });
42
51
  const composePort = compose.status === 0 ? /:(\d+)\s*$/.exec(compose.stdout.trim())?.[1] : undefined;
43
- if (!composePort) {
44
- refuse(
45
- `this repo's Compose Fuseki is not running (\`docker compose port fuseki 3030\`: ` +
46
- `${(compose.stderr || compose.error?.message || compose.stdout || '').trim()}). Run \`npm run fuseki:up\`.`,
47
- );
48
- }
52
+ if (!composePort) refuse(describeComposePortFailure(compose));
49
53
  if (composePort !== urlPort) {
50
54
  refuse(`port ${urlPort} is not the Compose Fuseki port ${composePort}. Set FUSEKI_PORT=${composePort}.`);
51
55
  }
@@ -1,4 +1,4 @@
1
- // Round-trip tests against a real API and Fuseki: `npm run fuseki:up && npm run test:integration`.
1
+ // Integration tests against a real API and Fuseki: `npm run fuseki:up && npm run test:integration`.
2
2
  // Same preset, transforms and module mapping as the unit config in package.json. jest-expo replaces the global
3
3
  // fetch with a stubbed `expo/fetch` that never sends a request (it is not a jest mock), so the environment saves
4
4
  // Node's fetch and restoreNodeFetch.ts reinstates it.
@@ -2,7 +2,7 @@
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
4
  // After Person.create the form calls _refresh() to re-run the list query.
5
- // A React Native port of the web app-template's example (linked-cm/app-template).
5
+ // A React Native port of the web app-template's example (linked-fw/app-template).
6
6
  //
7
7
  // `linkedSetComponent` checks LinkedStorage when this module loads, so storage is imported first.
8
8
  // Replace or extend this with your own shapes (see https://linked.cm).
@@ -3,7 +3,7 @@
3
3
  // result keys + `source` + `_refresh` into the render function. _refresh
4
4
  // patches local query state for optimistic UI; on delete, the parent
5
5
  // list re-runs via the PersonListRefresh context.
6
- // A React Native port of the web app-template's example (linked-cm/app-template).
6
+ // A React Native port of the web app-template's example (linked-fw/app-template).
7
7
  // Storage is imported first, so the row's queries go to the API store however this module is reached.
8
8
  import '../shell/storage';
9
9
 
@@ -4,9 +4,6 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "linkedPackage": true,
7
- "linked": {
8
- "extensionlessImports": true
9
- },
10
7
  "exports": {
11
8
  ".": {
12
9
  "types": "./src/index.ts",
@@ -52,6 +52,24 @@ export declare function scaffoldReactNativeApp(targetFolder: string, id: AppIden
52
52
  export declare const reactNativeInternals: {
53
53
  scaffoldReactNativeApp: typeof scaffoldReactNativeApp;
54
54
  };
55
+ /**
56
+ * Stamp the new app's identity into the freshly-cloned template. The template
57
+ * ships without `${var}` placeholders (so a raw CN clone boots on defaults), so
58
+ * create-app writes the real per-app values here:
59
+ * - `.env.example` (committed defaults for this app) + `.env` (local): APP_NAME
60
+ * drives the display name; APP_PREFIX names data files.
61
+ * - `package.json`: `name` (hyphenated id) + `displayName` (human name).
62
+ * - `src/package.ts`: the runtime `linkedPackage` id — shape URIs derive from it.
63
+ * - pm2 process names + the VS Code launch name (cosmetic, but should match).
64
+ */
65
+ /**
66
+ * Scaffolded apps are npm apps, so the new app must not also look like a yarn
67
+ * project. Removes every yarn project file a template clone may still carry —
68
+ * including the legacy `yarnrc.yml.template` that create-app used to rename
69
+ * into `.yarnrc.yml`. (No empty `yarn.lock` is written any more either; that
70
+ * file only existed to pin down Yarn's project-root search.)
71
+ */
72
+ export declare function stripYarnProjectFiles(targetFolder: string): void;
55
73
  export declare function warn(...messages: any[]): void;
56
74
  export declare function logError(...errors: any[]): void;
57
75
  export declare function developPackage(target: any, mode: any): void;
@@ -60,6 +78,16 @@ export declare function buildAll(options: any): void;
60
78
  export declare const createOntology: (prefix: any, uriBase?: any, basePath?: string) => Promise<void>;
61
79
  export declare const addShapeToBarrel: (shapeHyphenName: string, root?: string) => string;
62
80
  export declare const addLineToIndex: (line: any, insertMatchString: string, root?: string, insertAtStart?: boolean) => string;
81
+ export type PackageManager = 'npm' | 'yarn';
82
+ /**
83
+ * The package manager `create-app` scaffolds with. Both templates (web and
84
+ * react-native) install with npm, so a scaffolded app has exactly one lockfile.
85
+ */
86
+ export declare const CREATE_APP_PACKAGE_MANAGER: PackageManager;
87
+ /** The shell command that installs a scaffolded app's dependencies. */
88
+ export declare function installCommandFor(pm: PackageManager): string;
89
+ /** The command printed to the user for starting their new app. */
90
+ export declare function startCommandFor(pm: PackageManager): string;
63
91
  export declare const setNameVariables: (name: any) => {
64
92
  hyphenName: any;
65
93
  camelCaseName: any;
@@ -93,7 +121,7 @@ export declare const buildBackend: () => Promise<boolean>;
93
121
  export declare const upgradePackages: () => Promise<void>;
94
122
  export declare const createPackage: (name: any, uriBase?: any, basePath?: string) => Promise<void>;
95
123
  export declare const register: (registryURL: any) => Promise<void>;
96
- export declare const buildPackage: (target: any, target2: any, packagePath?: string, logResults?: boolean) => Promise<any>;
124
+ export declare const buildPackage: (target: any, target2: any, packagePath?: string, logResults?: boolean) => Promise<boolean>;
97
125
  type BuildStep = {
98
126
  name: string;
99
127
  apply: () => Promise<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"cli-methods.d.ts","sourceRoot":"","sources":["../../src/cli-methods.ts"],"names":[],"mappings":"AA4BA,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,kBAgNtL,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;AA0F7D,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;AAiGF,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;AAKF,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,qBA0G9E,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,iBAiJ3B,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AAKF,eAAO,MAAM,cAAc,GAAI,YAAO,EAAE,aAAa,MAAM,KAAG,SAAS,EAwGtE,CAAC;AACF,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,kBAqHtB,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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"}