@_linked/cli 1.3.2 → 1.4.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 (63) hide show
  1. package/.github/workflows/ci.yml +10 -2
  2. package/CHANGELOG.md +44 -0
  3. package/README.md +20 -1
  4. package/defaults/app-with-backend/.env-cmdrc.json +3 -1
  5. package/defaults/app-with-backend/gitignore.template +1 -0
  6. package/defaults/app-with-backend/linked.backend.datasets.example.json +17 -0
  7. package/defaults/app-with-backend/linked.backend.storage.ts +35 -0
  8. package/defaults/app-with-backend/package.json +13 -29
  9. package/defaults/app-with-backend/readme.md +80 -6
  10. package/jest.config.cjs +29 -0
  11. package/lib/cjs/cli-methods.d.ts.map +1 -1
  12. package/lib/cjs/cli-methods.js +65 -29
  13. package/lib/cjs/cli-methods.js.map +1 -1
  14. package/lib/cjs/cli.js +9 -9
  15. package/lib/cjs/cli.js.map +1 -1
  16. package/lib/cjs/config-webpack-app.d.ts.map +1 -1
  17. package/lib/cjs/config-webpack-app.js +40 -20
  18. package/lib/cjs/config-webpack-app.js.map +1 -1
  19. package/lib/cjs/defineConfig.d.ts.map +1 -1
  20. package/lib/cjs/defineConfig.js +1 -1
  21. package/lib/cjs/defineConfig.js.map +1 -1
  22. package/lib/cjs/index.d.ts.map +1 -1
  23. package/lib/cjs/index.js +5 -3
  24. package/lib/cjs/index.js.map +1 -1
  25. package/lib/cjs/interfaces.d.ts.map +1 -1
  26. package/lib/cjs/package.json +15 -7
  27. package/lib/cjs/tailwind.config.js +2 -2
  28. package/lib/cjs/tailwind.config.js.map +1 -1
  29. package/lib/cjs/utils.d.ts.map +1 -1
  30. package/lib/cjs/utils.js +1 -1
  31. package/lib/cjs/utils.js.map +1 -1
  32. package/lib/esm/cli-methods.d.ts.map +1 -1
  33. package/lib/esm/cli-methods.js +67 -29
  34. package/lib/esm/cli-methods.js.map +1 -1
  35. package/lib/esm/cli.js +9 -9
  36. package/lib/esm/cli.js.map +1 -1
  37. package/lib/esm/config-webpack-app.d.ts.map +1 -1
  38. package/lib/esm/config-webpack-app.js +38 -18
  39. package/lib/esm/config-webpack-app.js.map +1 -1
  40. package/lib/esm/defineConfig.d.ts.map +1 -1
  41. package/lib/esm/defineConfig.js +1 -1
  42. package/lib/esm/defineConfig.js.map +1 -1
  43. package/lib/esm/index.d.ts.map +1 -1
  44. package/lib/esm/index.js +4 -1
  45. package/lib/esm/index.js.map +1 -1
  46. package/lib/esm/interfaces.d.ts.map +1 -1
  47. package/lib/esm/launch.d.ts.map +1 -0
  48. package/lib/esm/launch.js +17 -0
  49. package/lib/esm/launch.js.map +1 -0
  50. package/lib/esm/package.json +15 -7
  51. package/lib/esm/tailwind.config.js +1 -1
  52. package/lib/esm/tailwind.config.js.map +1 -1
  53. package/lib/esm/utils.d.ts.map +1 -1
  54. package/lib/esm/utils.js +1 -1
  55. package/lib/esm/utils.js.map +1 -1
  56. package/package.json +15 -8
  57. package/tsconfig-cjs.json +2 -1
  58. package/defaults/app-with-backend/.husky/post-merge +0 -4
  59. package/defaults/app-with-backend/.husky/pre-commit +0 -4
  60. package/defaults/app-with-backend/mrgit-template.json +0 -3
  61. package/defaults/app-with-backend/scripts/storage-config.js +0 -12
  62. package/preflight.css +0 -137
  63. /package/defaults/app-with-backend/{lincd.config.js → linked.config.js} +0 -0
@@ -38,6 +38,14 @@ jobs:
38
38
  if: steps.rpr.outputs.is_release_pr == 'false'
39
39
  run: npm run build
40
40
 
41
- - name: Test
41
+ - name: Test (unit)
42
42
  if: steps.rpr.outputs.is_release_pr == 'false'
43
- run: npm test --if-present
43
+ run: npm run test:unit --if-present
44
+
45
+ # e2e scaffolds a fresh app, installs deps from npm, starts a Fuseki
46
+ # testcontainer, and drives a browser flow. Requires Docker on the
47
+ # runner. Skipped until @_linked/* companion packages publish with
48
+ # matching versions; set RUN_E2E=1 to opt in once they do.
49
+ - name: Test (e2e)
50
+ if: steps.rpr.outputs.is_release_pr == 'false' && env.RUN_E2E == '1'
51
+ run: npm run test:e2e --if-present
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#23](https://github.com/linked-cm/cli/pull/23) [`a00168d`](https://github.com/linked-cm/cli/commit/a00168d0e55a3f7f8164df1ea90e8fe52aefd5d4) Thanks [@flyon](https://github.com/flyon)! - Rename `LincdConfig` / `LincdWebpackConfig` / `LincdServerConfig` → `LinkedConfig` / `LinkedWebpackConfig` / `LinkedServerConfig`. Function `getLincdConfig` → `getLinkedConfig`. Legacy package.json flags `lincd: true` and `lincdApp: true` are no longer read — migrate to `linkedPackage: true` / `linkedApp: true`. Built loader registration is unaffected.
8
+
9
+ Plus: CLI command help text refresh (`LINCD app` → `Linked app`, etc.). Config file name `lincd.config.{js,json}` → `linked.config.{js,json}` (hard cut, no fallback) — was previously rolled out separately.
10
+
11
+ - [#23](https://github.com/linked-cm/cli/pull/23) [`a00168d`](https://github.com/linked-cm/cli/commit/a00168d0e55a3f7f8164df1ea90e8fe52aefd5d4) Thanks [@flyon](https://github.com/flyon)! - Starter template: CN-branded CSS theme + `@_linked/react` integration in the example components.
12
+
13
+ **Brand defaults.** The `app-with-backend` template now ships with the CN palette (`--color-primary-*` mapped to a teal-blue ramp, `--color-secondary-*` to mint green) as a default-branded baseline. Apps override `@theme { --color-primary-500: ... }` to swap brand.
14
+
15
+ **Semantic-token shell.** `App.module.css`, `DefaultLayout.module.css`, `Header.module.css` rewritten using `@_linked/css` semantic tokens (`--bg-page`, `--bg-card`, `--color-primary-*`) instead of hardcoded hex. Module CSS files using `--spacing(N)` import `@_linked/css/package.css` per the documented pattern.
16
+
17
+ **Person CRUD demo uses `@_linked/react`.** `PersonOverview` is now built with `linkedSetComponent`, and `PersonPreview` with `linkedComponent` — replacing the previous `useEffect` + `useState` query patterns. The wrappers handle loading state via the framework's `.ld-loader` and inject `_refresh` so the form (sibling) and rows (children) can trigger re-fetch. Optimistic UI on inline edit via `_refresh({givenName, familyName})`.
18
+
19
+ **Pages polish.** `Home`, `Signin`, `Page1`, `PageNotFound` get card layouts using semantic tokens — consistent across routes.
20
+
21
+ **`@_linked/react` is now a direct dep** in the scaffolded app's `package.json` so the bindings can be imported. Companion changes ship in `@_linked/react` (loader / errorElement API, `_refresh` on set, factory overloads) and `@_linked/css` (`.ld-loader` / `.ld-error` defaults + `--color-error-*` ramp).
22
+
23
+ **Storage layout.** Template now ships `linked.backend.storage.ts` + `linked.backend.datasets.json` and a mirror `src/linked.frontend.storage.ts` + `src/linked.frontend.datasets.json`. Backend uses `loadStores` (async, dynamic-import). Frontend hardcodes the per-alias store mapping for webpack-friendly bundling.
24
+
25
+ **npm + yarn compatibility.** `create-app` works with either package manager. Lockfile-based detection determines which to invoke for install.
26
+
27
+ No breaking changes. Existing scaffolded apps that don't pull in the template updates keep working.
28
+
29
+ ### Patch Changes
30
+
31
+ - [`67f01ab`](https://github.com/linked-cm/cli/commit/67f01abcbed04625175a5c82e584f09fee41cdea) - Remove `preflight.css` — moved to `@_linked/css`.
32
+
33
+ `preflight.css` is a CSS asset; it belongs in the CSS package alongside `theme-defaults.css` and `utilities.css`. Consumers should update imports from `@_linked/cli/preflight.css` to `@_linked/css/preflight.css`.
34
+
35
+ The exports entry `"./preflight.css": "./preflight.css"` is also removed from `package.json`.
36
+
37
+ - [`2b40588`](https://github.com/linked-cm/cli/commit/2b405880cbb21992c5005cb048f910df79c32145) - Relax `typescript` dep from `^5.7.3` to `^5.4.0` so consumers that pin a lower 5.x version (e.g. CN at 5.4.5) don't end up with a nested `typescript@5.9.x` install in `packages/cli/node_modules/`. The nested 5.9.x was incompatible with `react-refresh-typescript@2.0.12`'s AST walk — crashed frontend builds with `TypeError: Cannot read properties of undefined (reading 'declarations')` inside `VariableStatement.declarationList.declarations` traversal.
38
+
39
+ ## 1.3.3
40
+
41
+ ### Patch Changes
42
+
43
+ - [`8179c96`](https://github.com/linked-cm/cli/commit/8179c9627757be6c67de44e22b6ae7b08e83bcc1) - Remove webpack loader `./plugins/check-imports` from the package barrel (`src/index.ts`). The loader is CJS (uses `require()`) and was crashing ESM consumers at import time with "require is not defined in ES module scope". Webpack loads this file directly by path via `config-webpack.ts`, so no public export is needed. Also fix two relative imports in `tailwind.config.ts` and `utils.ts` that were missing `.js` extensions.
44
+
45
+ - [#19](https://github.com/linked-cm/cli/pull/19) [`eb1224e`](https://github.com/linked-cm/cli/commit/eb1224ea65ae65d7f534923b286d5daa0cdc151d) Thanks [@flyon](https://github.com/flyon)! - Remove `prepack: yarn build && pinst --disable` and `postpack: pinst --enable` scripts. These were conflicting with the CI publish flow (ENEEDAUTH on the actual `npm publish` call). Build now happens only in the dedicated CI "Build" step. Also remove `postinstall: husky install` (not needed for published installs).
46
+
3
47
  ## 1.3.2
4
48
 
5
49
  ### Patch Changes
package/README.md CHANGED
@@ -86,7 +86,7 @@ The CLI recognizes two flags in `package.json`:
86
86
  }
87
87
  ```
88
88
 
89
- The legacy `lincd: true` and `lincdApp: true` flags are still read for the transition period.
89
+ The legacy `lincd: true` / `lincdApp: true` flags are no longer read. Migrate to `linkedPackage` / `linkedApp`.
90
90
 
91
91
  ## Development
92
92
 
@@ -106,6 +106,25 @@ Templates live in `defaults/`:
106
106
  - `defaults/package/` — used by `linked create-package`
107
107
  - `defaults/setup-publish/` — workflow + changeset files written by `linked setup-publish` (single-branch default; `dual-branch/` subdirectory for the `--dual-branch` variant)
108
108
 
109
+ ### `linked create-app` template structure
110
+
111
+ `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.
112
+
113
+ Storage configuration follows the two-layer pattern from [backlog 016](https://github.com/create-now/docs/blob/main/docs/backlog/016-ejection-export-flow.md) (canonical spec) + the symmetric backend/frontend split:
114
+
115
+ | File | Side | Role | Git |
116
+ |---|---|---|---|
117
+ | `linked.backend.storage.ts` | backend | Shape→alias routing. Uses `parseDatasetsConfig` + `loadStores` from `@_linked/core`; calls `LinkedStorage.setDefaultDataset(...)` / `setDatasetForShapes(...)`. | committed |
118
+ | `linked.backend.datasets.json` | backend | Alias → `{ store, config }`. `store` is an npm import path; `config` is the store class's constructor arg. `${VAR:-default}` placeholders resolved at boot. | **gitignored** |
119
+ | `linked.backend.datasets.example.json` | backend | Template / seed for the gitignored file. Has placeholders matching env vars. | committed |
120
+ | `src/linked.frontend.storage.ts` | frontend | Same shape→alias model; imports store classes explicitly (webpack-bundle-safe), constructs per alias. | committed |
121
+ | `src/linked.frontend.datasets.json` | frontend | Frontend alias → `{ store, config }`. Public values only — never put secrets here, it ships in the browser bundle. | committed |
122
+
123
+ Conventions:
124
+ - Aliases on the two sides are **independent**. The framework re-routes by shape on each side; matching alias names between FE and BE is convention, not a framework requirement.
125
+ - The backend dispatcher is registry-free (dynamic `await import(entry.store)`). The frontend hardcodes each `new StoreClass(config)` because webpack can't bundle dynamic imports of arbitrary npm specifiers.
126
+ - Each store class accepts a single config-object constructor argument — `new FusekiStore({ endpoint, credentials? })`, `new BackendAPIStore({ name?, id? })`.
127
+
109
128
  ## Repository
110
129
 
111
130
  `linked-cm/cli` on GitHub. License: MPL-2.0.
@@ -3,7 +3,9 @@
3
3
  "DATA_ROOT": "https://${app_domain}/data",
4
4
  "APP_PREFIX": "${app_prefix}",
5
5
  "APP_NAME": "${app_name}",
6
- "SOURCE_PATH": "./src"
6
+ "SOURCE_PATH": "./src",
7
+ "FUSEKI_USER": "admin",
8
+ "FUSEKI_PASSWORD": "admin"
7
9
  },
8
10
  "development": {
9
11
  "NODE_ENV": "development",
@@ -5,6 +5,7 @@ public/bundles
5
5
  data/uploads
6
6
  data/metadata
7
7
  data/sessions
8
+ linked.backend.datasets.json
8
9
  .yarn/*
9
10
  !.yarn/patches
10
11
  !.yarn/plugins
@@ -0,0 +1,17 @@
1
+ {
2
+ "_note": "Backend datasets config. Copy this file to linked.backend.datasets.json (gitignored) and replace placeholders with literal values, OR set the env vars referenced via ${VAR}. The ${VAR:-default} form falls back to the literal after :- when the env var is unset. Each entry has two keys: `store` (an npm import path string identifying the IDataset class) and `config` (a single JSON object passed verbatim to `new StoreClass(config)` — its fields are whatever that class's constructor expects).",
3
+
4
+ "datasets": {
5
+ "appData": {
6
+ "store": "@_linked/fuseki/shapes/FusekiStore",
7
+ "config": {
8
+ "endpoint": "${FUSEKI_BASE_URL:-http://localhost:3030}/${FUSEKI_DATASET:-${hyphen_name}-main}",
9
+ "credentials": {
10
+ "type": "basic",
11
+ "username": "${FUSEKI_USER:-admin}",
12
+ "password": "${FUSEKI_PASSWORD:-admin}"
13
+ }
14
+ }
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,35 @@
1
+ // Backend storage for ${name}.
2
+ //
3
+ // Reads linked.backend.datasets.json, dynamically imports each alias's
4
+ // store class via its npm path, and instantiates with the entry's `config`
5
+ // verbatim. See the mirror at src/linked.frontend.storage.ts.
6
+ import datasetsConfig from './linked.backend.datasets.json' assert { type: 'json' };
7
+ import { parseDatasetsConfig } from '@_linked/core/utils/parseDatasetsConfig';
8
+ import { loadStores } from '@_linked/core/utils/loadStores';
9
+ import { LinkedStorage } from '@_linked/core/utils/LinkedStorage';
10
+ import { LinkedFileStorage } from '@_linked/core/utils/LinkedFileStorage';
11
+ import type { FusekiStore } from '@_linked/fuseki/shapes/FusekiStore';
12
+ import { LocalFileStore } from '@_linked/server/shapes/filestores/LocalFileStore';
13
+
14
+ // Resolve ${VAR} placeholders against the runtime environment, then
15
+ // instantiate each store class declared in the JSON.
16
+ const config = parseDatasetsConfig(datasetsConfig, process.env);
17
+ const stores = await loadStores(config);
18
+
19
+ // Auto-create the dataset on first boot.
20
+ const appData = stores.appData as FusekiStore;
21
+ appData.ensureDatasetExists().catch((err) =>
22
+ console.warn('dataset ensure failed:', err),
23
+ );
24
+
25
+ // Shape → alias. Single alias → default for every shape. For multi-alias
26
+ // add per-shape pins, e.g.:
27
+ // import { Person } from '@_linked/schema/shapes/Person';
28
+ // LinkedStorage.setDatasetForShapes(stores.appData, [Person]);
29
+ LinkedStorage.setDefaultDataset(appData);
30
+
31
+ // File storage (binary assets). Separate from RDF dataset routing.
32
+ const fileStore = new LocalFileStore(
33
+ (process.env.NODE_ENV || 'development') + '-files',
34
+ );
35
+ LinkedFileStorage.setDefaultDataset(fileStore);
@@ -12,35 +12,20 @@
12
12
  "email": ""
13
13
  },
14
14
  "engines": {
15
- "node": ">=16.0.0"
15
+ "node": ">=20.6.0"
16
16
  },
17
17
  "main": "scripts/start-server.js",
18
18
  "license": "MIT",
19
19
  "scripts": {
20
- "setup": "cp mrgit-template.json mrgit.json && yarn install && yarn mrgit sync && yarn install",
21
- "start": "node --import ./node_modules/@_linked/cli/lib/esm/loaders/register.js node_modules/.bin/linked start --env development",
22
- "build": "yarn linked build-app --env production",
23
- "prepare": "husky",
24
- "prepack": "pinst --disable",
25
- "postpack": "pinst --enable",
26
- "server:prod": "yarn linked start --env production",
20
+ "start": "linked start --env development",
21
+ "build": "linked build-app --env production",
22
+ "server:prod": "linked start --env production",
27
23
  "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
28
- "lint:fix": "yarn lint --fix",
24
+ "lint:fix": "npm run lint -- --fix",
29
25
  "prettier": "prettier \"src/**/*.{js,jsx,ts,tsx,css,scss}\" --check",
30
- "prettier:fix": "yarn prettier --write",
31
- "format": "yarn prettier:fix && yarn lint:fix"
26
+ "prettier:fix": "npm run prettier -- --write",
27
+ "format": "npm run prettier:fix && npm run lint:fix"
32
28
  },
33
- "lint-staged": {
34
- "*.{js,ts,tsx}": [
35
- "prettier --write"
36
- ],
37
- "*.{scss,css,json}": [
38
- "prettier --write"
39
- ]
40
- },
41
- "workspaces": [
42
- "packages/*"
43
- ],
44
29
  "keywords": [
45
30
  "linked",
46
31
  "linked code",
@@ -51,16 +36,20 @@
51
36
  "web3"
52
37
  ],
53
38
  "dependencies": {
54
- "@_linked/core": "^2.0",
39
+ "@_linked/core": "^2.2",
55
40
  "@_linked/auth": "~1.0",
56
41
  "@_linked/server": "~1.0",
57
42
  "@_linked/server-utils": "~1.0",
43
+ "@_linked/schema": "^1.0",
44
+ "@_linked/fuseki": "^1.0",
45
+ "@_linked/react": "^1.2",
58
46
  "react": "^18.2",
59
47
  "react-dom": "^18.2",
60
48
  "react-error-boundary": "^3.1.3",
61
49
  "react-router-dom": "^6.3.0"
62
50
  },
63
51
  "devDependencies": {
52
+ "@_linked/cli": "^1.3",
64
53
  "@types/node": "^20.12.7",
65
54
  "@types/react": "^18.0.17",
66
55
  "@types/react-dom": "^18.0.6",
@@ -73,14 +62,9 @@
73
62
  "eslint-plugin-prettier": "^5.0.0",
74
63
  "eslint-plugin-react": "latest",
75
64
  "eslint-plugin-react-hooks": "^4.6.0",
76
- "husky": "^8.0.0",
77
- "@_linked/cli": "^1.2",
78
- "mrgit": "latest",
79
65
  "nodemon": "^2.0.22",
80
- "pinst": "^3.0.0",
81
66
  "pm2": "^5.3.0",
82
67
  "typescript-plugin-css-modules": "^5.1.0",
83
68
  "which": "^3.0.1"
84
- },
85
- "packageManager": "yarn@3.6.1"
69
+ }
86
70
  }
@@ -1,19 +1,93 @@
1
- # installation
1
+ # ${name}
2
2
 
3
- Optional: to work on source of any `@_linked/*` packages locally, edit `mrgit-template.json` to list the packages you want cloned into `packages/`. Then run:
3
+ A standalone [Linked](https://linked.cm) app generated with `@_linked/cli`. Requires **Node 20.6**.
4
+
5
+ ## What is Linked
6
+
7
+ Linked is a TypeScript framework for building apps on top of a graph database (RDF / SPARQL). You write your domain as **shape classes**, query them with a **typed DSL**, and render with **linked React components** that subscribe to the query results.
8
+
9
+ ```ts
10
+ // 1. A shape — domain class + SHACL metadata, generated from TypeScript decorators
11
+ @linkedShape
12
+ export class Person extends Shape {
13
+ static targetClass = schema.Person;
14
+
15
+ @literalProperty({ path: schema.givenName }) givenName: string;
16
+ @literalProperty({ path: schema.familyName }) familyName: string;
17
+ }
18
+
19
+ // 2. A query — TypeScript-embedded, type-inferred, executed against any IDataset
20
+ const people = await Person.select((p) => [p.givenName, p.familyName]);
21
+
22
+ // 3. A linked component — re-renders when its query result changes
23
+ const PersonCard = linkedComponent(
24
+ Person.select((p) => [p.givenName, p.familyName]),
25
+ ({ givenName, familyName }) => <span>{givenName} {familyName}</span>,
26
+ );
27
+ ```
28
+
29
+ The home page in this app demonstrates the full chain end-to-end with `@_linked/schema`'s shipped `Person` shape.
30
+
31
+ - **[@_linked/core](https://github.com/linked-cm/core)** — query DSL, Shape classes, storage routing.
32
+ - **[@_linked/react](https://github.com/Semantu/linked-react)** — `linkedComponent`, `linkedSetComponent`.
33
+
34
+ ## Install + run
35
+
36
+ With npm:
4
37
 
5
38
  ```bash
6
- yarn setup
39
+ npm install
40
+ npm start
7
41
  ```
8
42
 
9
- Otherwise just install dependencies:
43
+ Or with yarn:
10
44
 
11
45
  ```bash
12
46
  yarn install
47
+ yarn start
48
+ ```
49
+
50
+ The home page demonstrates the `@_linked` query DSL with a small Person CRUD — see `src/components/PersonOverview.tsx` and `src/components/PersonPreview.tsx`.
51
+
52
+ > If you scaffolded this app **inside an existing Yarn-workspace monorepo** (e.g. `create_now/packages/`), use `yarn install` — `npm install` walks up to the workspace root and may hit peer-dep conflicts there. Outside a workspace, either tool works.
53
+
54
+ ## Storage
55
+
56
+ This app talks to an Apache Jena Fuseki SPARQL endpoint. Start a local Fuseki container:
57
+
58
+ ```bash
59
+ docker run -d --rm -p 3030:3030 --name fuseki stain/jena-fuseki
13
60
  ```
14
61
 
15
- Start the app:
62
+ The app auto-creates its dataset on first boot.
63
+
64
+ **Storage config lives in three files**, per the spec in [`@_linked/cli` docs](https://www.npmjs.com/package/@_linked/cli):
65
+
66
+ | File | Purpose |
67
+ |---|---|
68
+ | `linked.backend.datasets.json` | Backend Layer 2 — alias → store class + config. Gitignored. Copy of `linked.backend.datasets.example.json`. |
69
+ | `linked.backend.storage.ts` | Backend Layer 1 — shape → alias routing. Parses the JSON, instantiates stores via `loadStores`, calls `LinkedStorage.setDefaultDataset(...)` / `setDatasetForShapes(...)`. |
70
+ | `src/linked.frontend.{storage.ts,datasets.json}` | Frontend mirror — same JSON shape, public values only; storage TS imports store classes explicitly and constructs one per alias. |
71
+
72
+ Defaults shipped:
73
+
74
+ - `FUSEKI_BASE_URL` — `http://localhost:3030`
75
+ - `FUSEKI_DATASET` — `${hyphen_name}-main`
76
+ - `FUSEKI_USER` / `FUSEKI_PASSWORD` — `admin` / `admin` (matches the `stain/jena-fuseki` Docker image default)
77
+ - `FUSEKI_DB_TYPE` — `tdb2` (persistent). Set to `mem` for in-memory.
78
+
79
+ All of these are referenced as `${VAR:-default}` placeholders in `linked.backend.datasets.json`, so you can either edit the JSON directly or set env vars.
80
+
81
+ ## Build for production
16
82
 
17
83
  ```bash
18
- yarn start
84
+ npm run build
85
+ npm run server:prod
19
86
  ```
87
+
88
+ ## Learn more
89
+
90
+ - [@_linked/core](https://www.npmjs.com/package/@_linked/core) — query DSL, Shape classes, storage routing. See `parseDatasetsConfig` + `loadStores` for the dataset-config helpers.
91
+ - [@_linked/react](https://www.npmjs.com/package/@_linked/react) — `linkedComponent`, `linkedSetComponent`.
92
+ - [@_linked/schema](https://www.npmjs.com/package/@_linked/schema) — shipped Shape classes (Person, Place, Organization, …).
93
+ - [@_linked/css](https://www.npmjs.com/package/@_linked/css) — design tokens, Tailwind v4 theme primitives, `@utility` mixins. See `src/theme.css` for the wiring.
@@ -0,0 +1,29 @@
1
+ // Jest config for @_linked/cli unit tests.
2
+ //
3
+ // Tests target the compiled CJS output in lib/cjs, not raw src/. This avoids
4
+ // configuring jest's ESM mode (notoriously fiddly with our mixed tsx/ESM
5
+ // runtime) and keeps the test runner identical to what npm consumers see.
6
+ // Run `yarn build` before `yarn test:unit` so lib/cjs exists.
7
+ //
8
+ // E2E specs live in tests/e2e/ and run under Playwright (see
9
+ // playwright.config.ts), not Jest.
10
+ module.exports = {
11
+ testEnvironment: 'node',
12
+ rootDir: '.',
13
+ roots: ['<rootDir>/tests/unit'],
14
+ testMatch: ['**/*.test.{ts,js}'],
15
+ transform: {
16
+ '^.+\\.tsx?$': [
17
+ 'babel-jest',
18
+ {
19
+ configFile: false,
20
+ babelrc: false,
21
+ presets: [
22
+ ['@babel/preset-env', { targets: { node: 'current' } }],
23
+ '@babel/preset-typescript',
24
+ ],
25
+ },
26
+ ],
27
+ },
28
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
29
+ };
@@ -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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"}
@@ -66,6 +66,35 @@ let dirname__ = typeof __dirname !== 'undefined'
66
66
  ? __dirname
67
67
  : //@ts-ignore
68
68
  (0, path_1.dirname)(import.meta.url).replace('file:/', '');
69
+ /**
70
+ * Dynamically import the app's backend storage configuration. Tries the
71
+ * canonical `linked.backend.storage.{ts,js}` at app root first, then the
72
+ * earlier `backend-storage-config.{ts,js}` (Iter3), then the legacy
73
+ * `scripts/storage-config.js` (pre-rename). The fallback chain lets older
74
+ * app clones keep booting through the rename.
75
+ */
76
+ async function loadBackendStorageConfig() {
77
+ const cwd = process.cwd();
78
+ const candidates = [
79
+ // Iter4 canonical:
80
+ path_1.default.join(cwd, 'linked.backend.storage.ts'),
81
+ path_1.default.join(cwd, 'linked.backend.storage.js'),
82
+ // Iter3:
83
+ path_1.default.join(cwd, 'backend-storage-config.ts'),
84
+ path_1.default.join(cwd, 'backend-storage-config.js'),
85
+ path_1.default.join(cwd, 'scripts', 'backend-storage-config.js'),
86
+ path_1.default.join(cwd, 'scripts', 'backend-storage-config.ts'),
87
+ // legacy pre-rename:
88
+ path_1.default.join(cwd, 'scripts', 'storage-config.js'),
89
+ ];
90
+ for (const candidate of candidates) {
91
+ if (fs_extra_1.default.existsSync(candidate)) {
92
+ return Promise.resolve(`${candidate}`).then(s => __importStar(require(s)));
93
+ }
94
+ }
95
+ console.warn(chalk_1.default.yellow('[linked.backend.storage] no linked.backend.storage.{ts,js} found at app root.'));
96
+ return undefined;
97
+ }
69
98
  var variables = {};
70
99
  /**
71
100
  * Prompt user for input
@@ -136,8 +165,15 @@ const createApp = async (name, basePath = process.cwd(), options = {}) => {
136
165
  });
137
166
  fs_extra_1.default.renameSync(path_1.default.join(targetFolder, 'gitignore.template'), path_1.default.join(targetFolder, '.gitignore'));
138
167
  fs_extra_1.default.renameSync(path_1.default.join(targetFolder, 'yarnrc.yml.template'), path_1.default.join(targetFolder, '.yarnrc.yml'));
168
+ // Seed the real (gitignored) Layer 2 config from the committed example so
169
+ // the scaffolded app boots first try. Users can edit either file later.
170
+ const datasetsExample = path_1.default.join(targetFolder, 'linked.backend.datasets.example.json');
171
+ const datasetsReal = path_1.default.join(targetFolder, 'linked.backend.datasets.json');
172
+ if (fs_extra_1.default.existsSync(datasetsExample) && !fs_extra_1.default.existsSync(datasetsReal)) {
173
+ fs_extra_1.default.copySync(datasetsExample, datasetsReal);
174
+ }
139
175
  // fs.copySync(path.join(__dirname, '..', 'defaults', 'app'), targetFolder);
140
- log("Creating new LINCD application '" + appName + "'");
176
+ log("Creating new Linked app '" + appName + "'");
141
177
  //replace variables in some copied files
142
178
  await replaceVariablesInFolder(targetFolder);
143
179
  if (!options.skipInstall) {
@@ -149,7 +185,7 @@ const createApp = async (name, basePath = process.cwd(), options = {}) => {
149
185
  console.warn('Could not install dependencies or start application');
150
186
  });
151
187
  }
152
- log(`Your LINCD App is ready at ${chalk_1.default.blueBright(targetFolder)}`, `To start, run\n${chalk_1.default.blueBright(`cd ${hyphenName}`)} and then ${chalk_1.default.blueBright('yarn start')}`);
188
+ log(`Your Linked app is ready at ${chalk_1.default.blueBright(targetFolder)}`, `\nStorage: linked.backend.storage.ts wires aliases to stores; linked.backend.datasets.json holds endpoints.`, `Defaults to Fuseki at ${chalk_1.default.cyan('http://localhost:3030')} (auto-creates the dataset on first boot).`, `Make sure Fuseki is running, e.g.:`, ` ${chalk_1.default.blueBright('docker run -d --rm -p 3030:3030 --name fuseki stain/jena-fuseki')}`, `Edit ${chalk_1.default.cyan('linked.backend.datasets.json')} to change endpoints or credentials.`, `Mirror file for the frontend: ${chalk_1.default.cyan('src/linked.frontend.storage.ts')} + ${chalk_1.default.cyan('src/linked.frontend.datasets.json')}.`, `\nTo start (with npm or yarn):`, ` ${chalk_1.default.blueBright(`cd ${hyphenName} && npm start`)}`, ` ${chalk_1.default.gray('# or: yarn start')}`);
153
189
  };
154
190
  exports.createApp = createApp;
155
191
  function logHelp() {
@@ -232,7 +268,7 @@ function checkPackagePath(rootPath, packagePath, res) {
232
268
  if (pack && pack.workspaces) {
233
269
  checkWorkspaces(packagePath, pack.workspaces, res);
234
270
  }
235
- else if (pack && (pack.linkedPackage === true || pack.lincd === true)) {
271
+ else if (pack && pack.linkedPackage === true) {
236
272
  res.push({
237
273
  path: packagePath,
238
274
  packageName: pack.name,
@@ -443,7 +479,7 @@ function findAppRoot(startPath = process.cwd()) {
443
479
  candidateRoots.push({
444
480
  path: currentPath,
445
481
  hasWorkspaces: !!packageJson.workspaces,
446
- isLincd: packageJson.linkedPackage === true || packageJson.lincd === true,
482
+ isLinked: packageJson.linkedPackage === true,
447
483
  });
448
484
  }
449
485
  const parentPath = path_1.default.join(currentPath, '..');
@@ -454,16 +490,16 @@ function findAppRoot(startPath = process.cwd()) {
454
490
  currentPath = parentPath;
455
491
  }
456
492
  // Find the topmost package.json that has workspaces
457
- // Prefer non-lincd packages (app roots) over lincd packages
493
+ // Prefer non-linked packages (app roots) over linked packages
458
494
  let appRoot = null;
459
495
  for (let i = candidateRoots.length - 1; i >= 0; i--) {
460
496
  const candidate = candidateRoots[i];
461
- if (candidate.hasWorkspaces && !candidate.isLincd) {
497
+ if (candidate.hasWorkspaces && !candidate.isLinked) {
462
498
  appRoot = candidate.path;
463
499
  break;
464
500
  }
465
501
  }
466
- // If no non-lincd workspace found, use the topmost workspace
502
+ // If no non-linked workspace found, use the topmost workspace
467
503
  if (!appRoot) {
468
504
  for (let i = candidateRoots.length - 1; i >= 0; i--) {
469
505
  if (candidateRoots[i].hasWorkspaces) {
@@ -1307,23 +1343,23 @@ exports.runScript = runScript;
1307
1343
  const runMethod = async (packageName, method, options) => {
1308
1344
  await (0, exports.ensureEnvironmentLoaded)();
1309
1345
  if (options.spawn) {
1310
- let lincdConfig = (await Promise.resolve(`${path_1.default.join(process.cwd(), 'lincd.config.js')}`).then(s => __importStar(require(s)))).default;
1346
+ let linkedConfig = (await Promise.resolve(`${path_1.default.join(process.cwd(), 'linked.config.js')}`).then(s => __importStar(require(s)))).default;
1311
1347
  // Set default loadAppComponent if not provided
1312
- if (!lincdConfig.server) {
1313
- lincdConfig.server = {};
1348
+ if (!linkedConfig.server) {
1349
+ linkedConfig.server = {};
1314
1350
  }
1315
- if (!lincdConfig.server.loadAppComponent) {
1316
- lincdConfig.server.loadAppComponent = async () => (await Promise.resolve(`${path_1.default.join(process.cwd(), 'src', 'App')}`).then(s => __importStar(require(s)))).default;
1351
+ if (!linkedConfig.server.loadAppComponent) {
1352
+ linkedConfig.server.loadAppComponent = async () => (await Promise.resolve(`${path_1.default.join(process.cwd(), 'src', 'App')}`).then(s => __importStar(require(s)))).default;
1317
1353
  }
1318
1354
  // Set default loadRoutes if not provided
1319
- if (!lincdConfig.server.loadRoutes) {
1320
- lincdConfig.server.loadRoutes = async () => await Promise.resolve(`${path_1.default.join(process.cwd(), 'src', 'routes.tsx')}`).then(s => __importStar(require(s)));
1355
+ if (!linkedConfig.server.loadRoutes) {
1356
+ linkedConfig.server.loadRoutes = async () => await Promise.resolve(`${path_1.default.join(process.cwd(), 'src', 'routes.tsx')}`).then(s => __importStar(require(s)));
1321
1357
  }
1322
1358
  //@ts-ignore
1323
1359
  const ServerClass = (await Promise.resolve().then(() => __importStar(require('@_linked/server/shapes/LincdServer'))))
1324
1360
  .LincdServer;
1325
- await Promise.resolve(`${path_1.default.join(process.cwd(), 'scripts', 'storage-config.js')}`).then(s => __importStar(require(s)));
1326
- let server = new ServerClass(lincdConfig);
1361
+ await loadBackendStorageConfig();
1362
+ let server = new ServerClass(linkedConfig);
1327
1363
  //init the server
1328
1364
  console.log('Initializing server...');
1329
1365
  server.initOnly().then(() => {
@@ -1396,7 +1432,7 @@ const runMethod = async (packageName, method, options) => {
1396
1432
  exports.runMethod = runMethod;
1397
1433
  const startServer = async (initOnly = false, ServerClass = null) => {
1398
1434
  await (0, exports.ensureEnvironmentLoaded)();
1399
- let lincdConfig = (await Promise.resolve(`${path_1.default.join(process.cwd(), 'lincd.config.js')}`).then(s => __importStar(require(s))))
1435
+ let linkedConfig = (await Promise.resolve(`${path_1.default.join(process.cwd(), 'linked.config.js')}`).then(s => __importStar(require(s))))
1400
1436
  .default;
1401
1437
  // function scssLoadcall(source, filename) {
1402
1438
  // return 'console.log("SCSS CALL: ' + filename + '");\n' + source;
@@ -1412,12 +1448,12 @@ const startServer = async (initOnly = false, ServerClass = null) => {
1412
1448
  //@ts-ignore
1413
1449
  ServerClass = (await Promise.resolve().then(() => __importStar(require('@_linked/server/shapes/LincdServer')))).LincdServer;
1414
1450
  }
1415
- await Promise.resolve(`${path_1.default.join(process.cwd(), 'scripts', 'storage-config.js')}`).then(s => __importStar(require(s)));
1451
+ await loadBackendStorageConfig();
1416
1452
  // Set default loadAppComponent if not provided
1417
- if (!lincdConfig.server) {
1418
- lincdConfig.server = {};
1453
+ if (!linkedConfig.server) {
1454
+ linkedConfig.server = {};
1419
1455
  }
1420
- if (!lincdConfig.server.loadAppComponent) {
1456
+ if (!linkedConfig.server.loadAppComponent) {
1421
1457
  let appPromise;
1422
1458
  if (process.env.NODE_ENV !== 'development') {
1423
1459
  appPromise = (await Promise.resolve(`${path_1.default.join(process.cwd(), 'lib', 'App.js')}`).then(s => __importStar(require(s))))
@@ -1427,13 +1463,13 @@ const startServer = async (initOnly = false, ServerClass = null) => {
1427
1463
  appPromise = (await Promise.resolve(`${path_1.default.join(process.cwd(), 'src', 'App.tsx')}`).then(s => __importStar(require(s))))
1428
1464
  .default;
1429
1465
  }
1430
- lincdConfig.server.loadAppComponent = async () => {
1466
+ linkedConfig.server.loadAppComponent = async () => {
1431
1467
  return appPromise;
1432
1468
  };
1433
1469
  }
1434
1470
  // Set default loadRoutes if not provided
1435
- if (!lincdConfig.server.loadRoutes) {
1436
- lincdConfig.server.loadRoutes = async () => {
1471
+ if (!linkedConfig.server.loadRoutes) {
1472
+ linkedConfig.server.loadRoutes = async () => {
1437
1473
  if (process.env.NODE_ENV !== 'development') {
1438
1474
  return await Promise.resolve(`${path_1.default.join(process.cwd(), 'lib', 'routes.js')}`).then(s => __importStar(require(s)));
1439
1475
  }
@@ -1442,7 +1478,7 @@ const startServer = async (initOnly = false, ServerClass = null) => {
1442
1478
  }
1443
1479
  };
1444
1480
  }
1445
- let server = new ServerClass(lincdConfig);
1481
+ let server = new ServerClass(linkedConfig);
1446
1482
  //Important to use slice, because when using clusers, child processes need to be able to read the same arguments
1447
1483
  let args = process.argv.slice(2);
1448
1484
  //if --initOnly is passed, only initialize the server and don't start it
@@ -1513,10 +1549,10 @@ const buildFrontend = async () => {
1513
1549
  // process.exit();
1514
1550
  }
1515
1551
  // load the storage config
1516
- const storageConfig = await Promise.resolve(`${path_1.default.join(process.cwd(), 'scripts', 'storage-config.js')}`).then(s => __importStar(require(s)));
1552
+ const storageConfig = await loadBackendStorageConfig();
1517
1553
  // check if LincdFileStorage has a default FileStore
1518
1554
  // if yes: copy all the files in the build folder over with LincdFileStorage
1519
- if (LinkedFileStorage_1.LinkedFileStorage.getDefaultStore()) {
1555
+ if (LinkedFileStorage_1.LinkedFileStorage.getDefaultDataset()) {
1520
1556
  // get public directory
1521
1557
  const rootDirectory = 'public';
1522
1558
  const pathDir = path_1.default.join(process.cwd(), rootDirectory);
@@ -1917,8 +1953,8 @@ const buildPackage = async (target, target2, packagePath = process.cwd(), logRes
1917
1953
  // `linked build-app`. Plain packages (no linked flag) have no build pipeline
1918
1954
  // defined here and should have their own build script.
1919
1955
  const pkgJson = JSON.parse(fs_extra_1.default.readFileSync(path_1.default.join(packagePath, 'package.json'), 'utf8'));
1920
- const isPackage = pkgJson.linkedPackage === true || pkgJson.lincd === true;
1921
- const isApp = pkgJson.linkedApp === true || pkgJson.lincdApp === true;
1956
+ const isPackage = pkgJson.linkedPackage === true;
1957
+ const isApp = pkgJson.linkedApp === true;
1922
1958
  if (!isPackage) {
1923
1959
  if (isApp) {
1924
1960
  console.error(chalk_1.default.red(`'${pkgJson.name || packagePath}' is a linkedApp, not a linkedPackage. Use 'linked build-app' instead of 'linked build'.`));