@_linked/server 3.12.1 → 3.13.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @\_linked/server
2
2
 
3
+ ## 3.13.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#219](https://github.com/linked-fw/server/pull/219) [`bc51824`](https://github.com/linked-fw/server/commit/bc51824cd00843498e46d1267b34369e1eea9d5f) Thanks [@flyon](https://github.com/flyon)! - Boot loading decides which installed packages are linked from their `linked.kind` (any kind but `app`), through `linkedKind(json)` in `@_linked/server/utils/linkedDependencies` (the twin of `@_linked/cli`'s). `linkedPackage: true` is no longer read. `discoverLinkedDependencies` takes an optional third argument, the test for a linked package (default `isLinkedPackageJson`). This package's own `package.json` says `"kind": "library"`, merged into its `linked.serverOnly`.
8
+
9
+ - [#219](https://github.com/linked-fw/server/pull/219) [`865740c`](https://github.com/linked-fw/server/commit/865740c5ba110acede9941c208556cbe516dc09b) Thanks [@flyon](https://github.com/flyon)! - Quieter boot log:
10
+
11
+ - The ontology and shape graph sync lines list the packages written and count the unchanged ones (`shape graph sync: written dep; 3 unchanged; app graph unchanged`), instead of listing every skipped package.
12
+ - `shape check: …` is logged only when the check has findings.
13
+ - The routing-pin warning is logged only for a boot sync that runs: `syncPinWarning` takes `{shapeSync, ontologySync}` and watches only the shapes those syncs write, so a boot with `syncShapesOnBoot: false` does not warn. A store without an `id` is named by its endpoint's dataset (`FusekiStore "cn-main"`).
14
+
15
+ - [#219](https://github.com/linked-fw/server/pull/219) [`4580aa7`](https://github.com/linked-fw/server/commit/4580aa76c72e980a902c897a5df9e891cf498556) Thanks [@flyon](https://github.com/flyon)! - The packages an app lists in `linked.unpublishedPackages` (and, transitively, the lists of those packages) are its direct dependencies: boot loading finds them by npm name (npm's workspace link into `packages-local/`, else the checkout there), the shape sync's reload check accepts them, and the shape check reads each list as dependencies. Lists are read with `@_linked/cli/installed-packages`' `unpublishedPackages`, so a malformed list is an error.
16
+
17
+ - [#219](https://github.com/linked-fw/server/pull/219) [`47dc659`](https://github.com/linked-fw/server/commit/47dc6590562fd064b12a9c43b2573912593b9f4d) Thanks [@flyon](https://github.com/flyon)! - `RemoteDataset`'s url form sends the signed-in user's own Solid-OIDC access token instead of their
18
+ WebID: for a query made in a user's HTTP request it asks `@_linked/auth`'s hook
19
+ (`globalThis[Symbol.for('@_linked/auth:userTokenHeaders')]`, exported as `USER_TOKEN_HEADERS_HOOK`)
20
+ and sends `x-linked-user-token` (`USER_TOKEN_HEADER`) with a fresh `DPoP` proof for that request.
21
+ `forwardUserToken: false` turns it off.
22
+
23
+ **Breaking:** `x-linked-end-user` is no longer sent; `forwardEndUser`, `END_USER_HEADER` and
24
+ `currentEndUserWebId` are removed. A data server that read the WebID header verifies the token
25
+ with `@_linked/auth`'s `verifySolidAccessToken` instead.
26
+
27
+ ### Patch Changes
28
+
29
+ - [#219](https://github.com/linked-fw/server/pull/219) [`3d946b4`](https://github.com/linked-fw/server/commit/3d946b41fffdcd2189bdfb1592ed132a95b9ae10) Thanks [@flyon](https://github.com/flyon)! - The boot ontology sync log no longer has a "(default graph: the store has no graph queries)"
30
+ case: core's ontology sync refuses such a store instead of falling back (core report 080), which
31
+ the server reports as a failed ontology sync. The unused `fallback` field is gone from the
32
+ `OntologyCore` type.
33
+
34
+ - [#219](https://github.com/linked-fw/server/pull/219) [`b39cddb`](https://github.com/linked-fw/server/commit/b39cddb14cc904b268edcebcba6a10b2b959b033) Thanks [@flyon](https://github.com/flyon)! - `RemoteDataset`'s url form never follows a redirect: a 3xx answer is a `RemoteDatasetError` with
35
+ its status, so the bearer, the user's token and its proof are sent to the configured data server
36
+ only.
37
+
38
+ - [#219](https://github.com/linked-fw/server/pull/219) [`757655e`](https://github.com/linked-fw/server/commit/757655e5a548eb2129742c7eedbee6b46908b6b8) Thanks [@flyon](https://github.com/flyon)! - Boot loading reads a `package.json` without `linked.kind` by the retired flags (`linkedPackage: true` is a `library`, `linkedApp: true` an `app`), so packages published before `linked.kind` still load until they are republished.
39
+
40
+ - [#219](https://github.com/linked-fw/server/pull/219) [`c457627`](https://github.com/linked-fw/server/commit/c45762703c589d91b52661c820b19f33c711548f) Thanks [@flyon](https://github.com/flyon)! - `POST /admin/sync-shapes` answers 200 with `shapeCheck.failed` when the shape check throws and both syncs succeeded (it answered 500). The sync-pin warning counts a sub-shape under the target class it declares, so a sub-shape with its own class is no longer reported as its parent's; `owl:Restriction` is watched with the ontology term classes.
41
+
3
42
  ## 3.12.1
4
43
 
5
44
  ### Patch Changes
@@ -82,7 +82,7 @@ export declare class LinkedServer extends Shape {
82
82
  * could not be loaded at all.
83
83
  */
84
84
  private linkedPackageDirs;
85
- /** The app's own workspace packages (`linkedPackage: true`), by real path. */
85
+ /** The app's own workspace packages (`linked.kind` of a package), by real path. */
86
86
  private workspacePackageDirs;
87
87
  /** The names of the app's own workspace packages. */
88
88
  private workspacePackageNames;
@@ -136,7 +136,7 @@ export declare class LinkedServer extends Shape {
136
136
  /**
137
137
  * Boot: one warning when routing pins the shape shapes or the ontology term shapes to a dataset
138
138
  * other than the default one, since the syncs write into the default dataset only (see
139
- * {@link syncPinWarning}).
139
+ * {@link syncPinWarning}). Only for the syncs this boot runs.
140
140
  */
141
141
  private warnOfSyncPins;
142
142
  /**
@@ -161,12 +161,13 @@ export declare class LinkedServer extends Shape {
161
161
  * Re-sync the registered ontologies and shapes into app data, as the boot does,
162
162
  * and report what was written: the ontology sync (every registered package,
163
163
  * hash-skipped), the shape check's counts, then the shape sync. A failed ontology
164
- * sync does not stop the shape sync; the run then fails with the ontology error. The host calls it (`POST /admin/sync-shapes`) after it
164
+ * sync does not stop the shape sync; the run then fails with the ontology error. A shape
165
+ * check that throws fails nothing: the answer reports it (`shapeCheck.failed`). The host calls it (`POST /admin/sync-shapes`) after it
165
166
  * changed the app's shape code, so the app — the only process that loads that
166
167
  * code — writes its own shapes and their hashes.
167
168
  *
168
169
  * `packages` names the packages whose source changed: the app itself or its
169
- * direct dependencies, never `@_linked/*` ({@link assertReloadablePackages}). In
170
+ * direct dependencies (its `linked.unpublishedPackages` among them), never `@_linked/*` ({@link assertReloadablePackages}). In
170
171
  * dev (Vite) their modules are invalidated and their backends reloaded first
171
172
  * ({@link onSourceChange}), so a shape added since the boot is registered before
172
173
  * the sync; without Vite (a built app) nothing is reloaded. The answer names the
@@ -178,7 +179,12 @@ export declare class LinkedServer extends Shape {
178
179
  resyncShapes({ packages }?: {
179
180
  packages?: string[];
180
181
  }): Promise<ShapeSyncResult>;
181
- /** The packages a host may ask to reload: the app itself and its direct dependencies. */
182
+ /**
183
+ * The packages a host may ask to reload: the app itself and its direct dependencies, which
184
+ * include every package in its `linked.unpublishedPackages`, transitively
185
+ * ({@link listedPackageNames}). Read from disk on each call: a list written after the boot
186
+ * counts. A malformed list throws.
187
+ */
182
188
  private reloadablePackages;
183
189
  /**
184
190
  * Re-read one package's source from disk (dev only); see {@link resyncShapes}.
@@ -270,7 +276,8 @@ export declare class LinkedServer extends Shape {
270
276
  protected importModule(specifier: string): Promise<any>;
271
277
  /**
272
278
  * Filters local workspace packages to only those reachable from the app's
273
- * dependency tree. Mirrors the logic used by `buildAll` in lincd-cli.
279
+ * dependency tree: `dependencies` and `linked.unpublishedPackages`, of the app
280
+ * and of each package reached. Mirrors the logic used by `buildAll` in the cli.
274
281
  */
275
282
  private filterPackagesByDependencyTree;
276
283
  resizeImage(req: any, res: any): Promise<void>;
@@ -40,7 +40,7 @@ import { getAllShapeClasses, getShapeClass, getSuperShapesClasses, } from '@_lin
40
40
  import path from 'path';
41
41
  import { pathToFileURL } from 'node:url';
42
42
  import { FatalStartupError, isFatalError } from '../utils/fatalError.js';
43
- import { discoverLinkedDependencies, hasModuleEntry, isBundledBySsr, NODE_IMPORT_CONDITIONS, readDependencyLists, readInstalledPackage, resolveBackendEntry, resolveDevBackendEntry, ssrNoExternalOf, } from '../utils/linkedDependencies.js';
43
+ import { discoverLinkedDependencies, listedPackageNames, unpublishedNames, hasModuleEntry, isBundledBySsr, NODE_IMPORT_CONDITIONS, readDependencyLists, readInstalledPackage, resolveBackendEntry, resolveDevBackendEntry, ssrNoExternalOf, } from '../utils/linkedDependencies.js';
44
44
  /**
45
45
  * `instanceof ShapeProvider`, tolerating a second copy of server-utils.
46
46
  *
@@ -285,7 +285,7 @@ let LinkedServer = class LinkedServer extends Shape {
285
285
  * could not be loaded at all.
286
286
  */
287
287
  this.linkedPackageDirs = new Map();
288
- /** The app's own workspace packages (`linkedPackage: true`), by real path. */
288
+ /** The app's own workspace packages (`linked.kind` of a package), by real path. */
289
289
  this.workspacePackageDirs = [];
290
290
  /** The names of the app's own workspace packages. */
291
291
  this.workspacePackageNames = new Set();
@@ -441,10 +441,15 @@ let LinkedServer = class LinkedServer extends Shape {
441
441
  /**
442
442
  * Boot: one warning when routing pins the shape shapes or the ontology term shapes to a dataset
443
443
  * other than the default one, since the syncs write into the default dataset only (see
444
- * {@link syncPinWarning}).
444
+ * {@link syncPinWarning}). Only for the syncs this boot runs.
445
445
  */
446
446
  warnOfSyncPins() {
447
- const warning = syncPinWarning();
447
+ var _a;
448
+ const flag = (_a = this.config) === null || _a === void 0 ? void 0 : _a.syncShapesOnBoot;
449
+ const warning = syncPinWarning({
450
+ shapeSync: shapeSyncOn(process.env, flag),
451
+ ontologySync: bootSyncsOntologies(process.env, flag),
452
+ });
448
453
  if (warning)
449
454
  console.warn(warning);
450
455
  }
@@ -485,12 +490,13 @@ let LinkedServer = class LinkedServer extends Shape {
485
490
  * Re-sync the registered ontologies and shapes into app data, as the boot does,
486
491
  * and report what was written: the ontology sync (every registered package,
487
492
  * hash-skipped), the shape check's counts, then the shape sync. A failed ontology
488
- * sync does not stop the shape sync; the run then fails with the ontology error. The host calls it (`POST /admin/sync-shapes`) after it
493
+ * sync does not stop the shape sync; the run then fails with the ontology error. A shape
494
+ * check that throws fails nothing: the answer reports it (`shapeCheck.failed`). The host calls it (`POST /admin/sync-shapes`) after it
489
495
  * changed the app's shape code, so the app — the only process that loads that
490
496
  * code — writes its own shapes and their hashes.
491
497
  *
492
498
  * `packages` names the packages whose source changed: the app itself or its
493
- * direct dependencies, never `@_linked/*` ({@link assertReloadablePackages}). In
499
+ * direct dependencies (its `linked.unpublishedPackages` among them), never `@_linked/*` ({@link assertReloadablePackages}). In
494
500
  * dev (Vite) their modules are invalidated and their backends reloaded first
495
501
  * ({@link onSourceChange}), so a shape added since the boot is registered before
496
502
  * the sync; without Vite (a built app) nothing is reloaded. The answer names the
@@ -514,22 +520,32 @@ let LinkedServer = class LinkedServer extends Shape {
514
520
  this.shapeSyncQueue = run.catch(() => undefined);
515
521
  return run;
516
522
  }
517
- /** The packages a host may ask to reload: the app itself and its direct dependencies. */
523
+ /**
524
+ * The packages a host may ask to reload: the app itself and its direct dependencies, which
525
+ * include every package in its `linked.unpublishedPackages`, transitively
526
+ * ({@link listedPackageNames}). Read from disk on each call: a list written after the boot
527
+ * counts. A malformed list throws.
528
+ */
518
529
  reloadablePackages() {
519
530
  var _a, _b;
520
531
  const names = new Set();
521
532
  if ((_a = this.package) === null || _a === void 0 ? void 0 : _a.name)
522
533
  names.add(this.package.name);
534
+ let json;
523
535
  try {
524
- const json = JSON.parse(fsNative.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'));
525
- if (json.name)
526
- names.add(json.name);
527
- for (const field of ['dependencies', 'devDependencies']) {
528
- for (const name of Object.keys((_b = json[field]) !== null && _b !== void 0 ? _b : {}))
529
- names.add(name);
530
- }
536
+ json = JSON.parse(fsNative.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'));
531
537
  }
532
- catch (_c) { }
538
+ catch (_c) {
539
+ return names;
540
+ }
541
+ if (json.name)
542
+ names.add(json.name);
543
+ for (const field of ['dependencies', 'devDependencies']) {
544
+ for (const name of Object.keys((_b = json[field]) !== null && _b !== void 0 ? _b : {}))
545
+ names.add(name);
546
+ }
547
+ for (const name of listedPackageNames(process.cwd(), json))
548
+ names.add(name);
533
549
  return names;
534
550
  }
535
551
  /**
@@ -1047,18 +1063,21 @@ let LinkedServer = class LinkedServer extends Shape {
1047
1063
  }
1048
1064
  /**
1049
1065
  * Filters local workspace packages to only those reachable from the app's
1050
- * dependency tree. Mirrors the logic used by `buildAll` in lincd-cli.
1066
+ * dependency tree: `dependencies` and `linked.unpublishedPackages`, of the app
1067
+ * and of each package reached. Mirrors the logic used by `buildAll` in the cli.
1051
1068
  */
1052
1069
  filterPackagesByDependencyTree(allPackages, appPackageJson) {
1070
+ var _a, _b;
1053
1071
  const relevantPackages = new Map();
1054
1072
  const packagesToCheck = new Set();
1055
1073
  const processedPackages = new Set();
1056
- // Start with direct dependencies from the app
1057
- if (appPackageJson.dependencies) {
1058
- for (const dep of Object.keys(appPackageJson.dependencies)) {
1059
- if (allPackages.has(dep)) {
1060
- packagesToCheck.add(dep);
1061
- }
1074
+ // Start with direct dependencies from the app, its linked.unpublishedPackages among them
1075
+ for (const dep of [
1076
+ ...Object.keys((_a = appPackageJson.dependencies) !== null && _a !== void 0 ? _a : {}),
1077
+ ...unpublishedNames(appPackageJson),
1078
+ ]) {
1079
+ if (allPackages.has(dep)) {
1080
+ packagesToCheck.add(dep);
1062
1081
  }
1063
1082
  }
1064
1083
  // Recursively follow each package's dependencies
@@ -1073,11 +1092,12 @@ let LinkedServer = class LinkedServer extends Shape {
1073
1092
  if (packageDetails) {
1074
1093
  relevantPackages.set(packageName, packageDetails);
1075
1094
  const pkg = getPackageJSON(packageDetails.path);
1076
- if (pkg === null || pkg === void 0 ? void 0 : pkg.dependencies) {
1077
- for (const dep of Object.keys(pkg.dependencies)) {
1078
- if (allPackages.has(dep) && !processedPackages.has(dep)) {
1079
- packagesToCheck.add(dep);
1080
- }
1095
+ for (const dep of [
1096
+ ...Object.keys((_b = pkg === null || pkg === void 0 ? void 0 : pkg.dependencies) !== null && _b !== void 0 ? _b : {}),
1097
+ ...unpublishedNames(pkg),
1098
+ ]) {
1099
+ if (allPackages.has(dep) && !processedPackages.has(dep)) {
1100
+ packagesToCheck.add(dep);
1081
1101
  }
1082
1102
  }
1083
1103
  }