@_linked/server 3.12.0 → 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 +45 -0
- package/LICENSE +21 -0
- package/lib/esm/shapes/LinkedServer.d.ts +13 -6
- package/lib/esm/shapes/LinkedServer.js +47 -27
- package/lib/esm/shapes/LinkedServer.js.map +1 -1
- package/lib/esm/shapes/quadstores/RemoteDataset.d.ts +17 -14
- package/lib/esm/shapes/quadstores/RemoteDataset.js +57 -20
- package/lib/esm/shapes/quadstores/RemoteDataset.js.map +1 -1
- package/lib/esm/utils/adminChannel.d.ts +7 -6
- package/lib/esm/utils/adminChannel.js +2 -2
- package/lib/esm/utils/adminChannel.js.map +1 -1
- package/lib/esm/utils/graphTargets.d.ts +17 -9
- package/lib/esm/utils/graphTargets.js +34 -20
- package/lib/esm/utils/graphTargets.js.map +1 -1
- package/lib/esm/utils/linkedDependencies.d.ts +53 -7
- package/lib/esm/utils/linkedDependencies.js +130 -12
- package/lib/esm/utils/linkedDependencies.js.map +1 -1
- package/lib/esm/utils/ontologySync.d.ts +19 -12
- package/lib/esm/utils/ontologySync.js +45 -15
- package/lib/esm/utils/ontologySync.js.map +1 -1
- package/lib/esm/utils/syncShapes.d.ts +5 -0
- package/lib/esm/utils/syncShapes.js +17 -5
- package/lib/esm/utils/syncShapes.js.map +1 -1
- package/package.json +7 -6
- package/readme.md +24 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
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
|
+
|
|
42
|
+
## 3.12.1
|
|
43
|
+
|
|
44
|
+
### Patch Changes
|
|
45
|
+
|
|
46
|
+
- [#214](https://github.com/linked-fw/server/pull/214) [`654a3c2`](https://github.com/linked-fw/server/commit/654a3c2941ef49e317dd2ba58324f0221e894ca3) Thanks [@flyon](https://github.com/flyon)! - License: MIT (data under its original license)
|
|
47
|
+
|
|
3
48
|
## 3.12.0
|
|
4
49
|
|
|
5
50
|
### Minor Changes
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Semantu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -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 (`
|
|
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.
|
|
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
|
-
/**
|
|
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
|
|
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 (`
|
|
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
|
-
|
|
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.
|
|
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
|
-
/**
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
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
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
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
|
}
|