@_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.
@@ -12,7 +12,7 @@
12
12
  * store expands it under this setting.
13
13
  *
14
14
  * The syncs write into the default dataset only. {@link syncPinWarning} names the shapes whose
15
- * routing sends their reads elsewhere.
15
+ * routing sends their reads elsewhere, when the boot runs those syncs.
16
16
  */
17
17
  import { GRAPH_TARGET_ENV, graphTargetOptionsFromEnv, setGraphTargets, } from '@_linked/core/utils/graphTargets';
18
18
  import { LinkedStorage } from '@_linked/core/utils/LinkedStorage';
@@ -50,46 +50,60 @@ export const SHAPE_SHAPE_CLASSES = [`${SH}NodeShape`, `${SH}PropertyShape`];
50
50
  export const ONTOLOGY_TERM_CLASSES = [
51
51
  `${RDFS}Class`,
52
52
  `${OWL}Class`,
53
+ `${OWL}Restriction`,
53
54
  `${RDF}Property`,
54
55
  `${OWL}ObjectProperty`,
55
56
  `${OWL}DatatypeProperty`,
56
57
  `${OWL}AnnotationProperty`,
57
58
  ];
58
- /** A dataset as `GET /admin/routes` tells it apart: its store class, and its `id` when it has one. */
59
+ /**
60
+ * A dataset as a log line tells it apart: its store class, and its `id` when it has one, else the
61
+ * dataset name a SPARQL store keeps from its endpoint (`FusekiStore`'s `dataset`).
62
+ */
59
63
  function datasetName(dataset) {
60
64
  var _a;
61
- const id = dataset.id;
65
+ const { id, dataset: name } = dataset;
62
66
  const store = ((_a = dataset === null || dataset === void 0 ? void 0 : dataset.constructor) === null || _a === void 0 ? void 0 : _a.name) || 'unknown';
63
- return typeof id === 'string' && id ? `${store} "${id}"` : store;
67
+ const label = typeof id === 'string' && id ? id : typeof name === 'string' && name ? name : undefined;
68
+ return label ? `${store} "${label}"` : store;
64
69
  }
65
70
  /**
66
- * The watched class `shapeClass` or one of its super-shapes targets (a sub-shape of `owl:Class`,
67
- * say `owl:Restriction`, goes where its parent is pinned), else undefined.
71
+ * The class the instances of `shapeClass` carry, when it is watched, else undefined: the
72
+ * `targetClass` of the shape itself or, when it declares none of its own, of the nearest
73
+ * super-shape that does. A sub-shape with its own target class is not its parent's class: the
74
+ * syncs' data of the parent's class never reads through it.
68
75
  */
69
76
  function watchedClassOf(shapeClass, watched) {
70
77
  var _a;
71
78
  for (let current = shapeClass; typeof current === 'function' && current !== Function.prototype; current = Object.getPrototypeOf(current)) {
79
+ if (!Object.prototype.hasOwnProperty.call(current, 'targetClass'))
80
+ continue;
72
81
  const id = (_a = current.targetClass) === null || _a === void 0 ? void 0 : _a.id;
73
- if (typeof id === 'string' && watched.has(id))
74
- return id;
82
+ return typeof id === 'string' && watched.has(id) ? id : undefined;
75
83
  }
76
84
  return undefined;
77
85
  }
78
86
  /**
79
- * One warning when routing pins a shape the boot syncs write (the shape shapes `NodeShape` /
80
- * `PropertyShape`, or an ontology term shape such as `rdfs:Class` / `owl:ObjectProperty`) to a
81
- * dataset other than the default one: the syncs write into the default dataset only, so reads of
82
- * those shapes on the pinned dataset miss what they wrote. Names each such shape (sub-shapes of a
83
- * watched shape included) and its dataset. Undefined when there is nothing to warn about (or no
84
- * default dataset). Reads the registered shapes outside any shape catalog (run it at boot, never
85
- * inside `withShapeCatalog`).
87
+ * One warning when routing pins a shape a boot sync that runs writes (the shape shapes
88
+ * `NodeShape` / `PropertyShape` for the shape sync, an ontology term shape such as `rdfs:Class` /
89
+ * `owl:ObjectProperty` for the ontology sync) to a dataset other than the default one: the syncs
90
+ * write into the default dataset only, so reads of those shapes on the pinned dataset miss what
91
+ * they wrote. Names each such shape and its dataset; a sub-shape counts under the target class it
92
+ * declares, or its parent's when it declares none.
93
+ * Undefined when there is nothing to warn about (no sync runs, or no default dataset). Reads the
94
+ * registered shapes outside any shape catalog (run it at boot, never inside `withShapeCatalog`).
86
95
  */
87
- export function syncPinWarning() {
96
+ export function syncPinWarning(syncs) {
88
97
  var _a;
89
98
  const defaultDataset = LinkedStorage.getDefaultDataset();
90
99
  if (!defaultDataset)
91
100
  return undefined;
92
- const watched = new Set([...SHAPE_SHAPE_CLASSES, ...ONTOLOGY_TERM_CLASSES]);
101
+ const watched = new Set([
102
+ ...(syncs.shapeSync ? SHAPE_SHAPE_CLASSES : []),
103
+ ...(syncs.ontologySync ? ONTOLOGY_TERM_CLASSES : []),
104
+ ]);
105
+ if (watched.size === 0)
106
+ return undefined;
93
107
  const pinned = new Map();
94
108
  for (const [iri, shapeClass] of getAllShapeClasses()) {
95
109
  const targetClass = watchedClassOf(shapeClass, watched);
@@ -105,9 +119,9 @@ export function syncPinWarning() {
105
119
  if (pinned.size === 0)
106
120
  return undefined;
107
121
  const parts = [...pinned].map(([dataset, shapes]) => `${shapes.sort().join(', ')} → ${datasetName(dataset)}`);
122
+ const writers = syncs.ontologySync && syncs.shapeSync ? 'ontology and shape syncs write' : `${syncs.shapeSync ? 'shape' : 'ontology'} sync writes`;
108
123
  return (`[LinkedServer] Routing pins shapes the boot syncs write to a dataset other than the default ` +
109
- `one: ${parts.join('; ')}. The ontology and shape syncs, when they run, write into the default dataset ` +
110
- `(${datasetName(defaultDataset)}) only, so reads of these shapes on the pinned dataset do not ` +
111
- `see what the syncs wrote.`);
124
+ `one: ${parts.join('; ')}. The ${writers} into the default dataset (${datasetName(defaultDataset)}) ` +
125
+ `only, so reads of these shapes on the pinned dataset do not see what the boot wrote.`);
112
126
  }
113
127
  //# sourceMappingURL=graphTargets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graphTargets.js","sourceRoot":"","sources":["../../../src/utils/graphTargets.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Where the boot syncs keep the registered packages' ontology data and shapes: core's graph\n * targets (`ontologyGraph`, `shapeGraph`; `@_linked/core/utils/graphTargets`), one global setting\n * of the process. `LINKED_ONTOLOGY_GRAPH` and `LINKED_SHAPE_GRAPH` each take `'package'` (the\n * default, one graph per package), `'default'` (the default graph) or the absolute IRI of one\n * shared graph.\n *\n * The server reads them once at boot, checks them (an invalid value stops the boot, naming the\n * variable) and calls core's `setGraphTargets` before the stores are initialised and before the\n * syncs. No store takes a setting of its own, and the frontend needs none: its\n * `.from(graphs.allOntologies)` reaches the backend as the portable name, and the backend's\n * store expands it under this setting.\n *\n * The syncs write into the default dataset only. {@link syncPinWarning} names the shapes whose\n * routing sends their reads elsewhere.\n */\nimport {\n GRAPH_TARGET_ENV,\n graphTargetOptionsFromEnv,\n setGraphTargets,\n type GraphTargets,\n} from '@_linked/core/utils/graphTargets';\nimport { LinkedStorage } from '@_linked/core/utils/LinkedStorage';\nimport { getAllShapeClasses } from '@_linked/core/utils/ShapeClass';\nimport type { IDataset } from '@_linked/core/interfaces/IDataset';\n\n/**\n * Read `LINKED_ONTOLOGY_GRAPH` / `LINKED_SHAPE_GRAPH` from `env` (checked: an invalid value throws,\n * naming the variable) and set them as the process's graph targets (core's `setGraphTargets`;\n * unset ones are `'package'`). Returns the settings the env gave.\n */\nexport function applyGraphTargetsFromEnv(env: Record<string, string | undefined>): Partial<GraphTargets> {\n const fromEnv = graphTargetOptionsFromEnv(env);\n setGraphTargets(fromEnv);\n return fromEnv;\n}\n\n/** The env variables as set (unset and empty ones left out), for `GET /admin/routes`. */\nexport function graphTargetEnv(env: Record<string, string | undefined>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of [GRAPH_TARGET_ENV.ontologyGraph, GRAPH_TARGET_ENV.shapeGraph]) {\n const value = env[name];\n if (value) out[name] = value;\n }\n return out;\n}\n\nconst SH = 'http://www.w3.org/ns/shacl#';\nconst RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';\nconst RDFS = 'http://www.w3.org/2000/01/rdf-schema#';\nconst OWL = 'http://www.w3.org/2002/07/owl#';\n\n/** The classes of the shape shapes: what the shape sync writes. */\nexport const SHAPE_SHAPE_CLASSES: readonly string[] = [`${SH}NodeShape`, `${SH}PropertyShape`];\n\n/**\n * The classes of the ontology term shapes (the class and property shapes core, `@_linked/rdfs`\n * and `@_linked/owl` register): what the ontology sync writes and the hierarchy reads.\n */\nexport const ONTOLOGY_TERM_CLASSES: readonly string[] = [\n `${RDFS}Class`,\n `${OWL}Class`,\n `${RDF}Property`,\n `${OWL}ObjectProperty`,\n `${OWL}DatatypeProperty`,\n `${OWL}AnnotationProperty`,\n];\n\n/** A dataset as `GET /admin/routes` tells it apart: its store class, and its `id` when it has one. */\nfunction datasetName(dataset: IDataset): string {\n const id = (dataset as { id?: unknown }).id;\n const store = dataset?.constructor?.name || 'unknown';\n return typeof id === 'string' && id ? `${store} \"${id}\"` : store;\n}\n\n/**\n * The watched class `shapeClass` or one of its super-shapes targets (a sub-shape of `owl:Class`,\n * say `owl:Restriction`, goes where its parent is pinned), else undefined.\n */\nfunction watchedClassOf(shapeClass: Function, watched: ReadonlySet<string>): string | undefined {\n for (let current: unknown = shapeClass; typeof current === 'function' && current !== Function.prototype; current = Object.getPrototypeOf(current)) {\n const id = (current as { targetClass?: { id?: unknown } }).targetClass?.id;\n if (typeof id === 'string' && watched.has(id)) return id;\n }\n return undefined;\n}\n\n/**\n * One warning when routing pins a shape the boot syncs write (the shape shapes `NodeShape` /\n * `PropertyShape`, or an ontology term shape such as `rdfs:Class` / `owl:ObjectProperty`) to a\n * dataset other than the default one: the syncs write into the default dataset only, so reads of\n * those shapes on the pinned dataset miss what they wrote. Names each such shape (sub-shapes of a\n * watched shape included) and its dataset. Undefined when there is nothing to warn about (or no\n * default dataset). Reads the registered shapes outside any shape catalog (run it at boot, never\n * inside `withShapeCatalog`).\n */\nexport function syncPinWarning(): string | undefined {\n const defaultDataset = LinkedStorage.getDefaultDataset();\n if (!defaultDataset) return undefined;\n const watched = new Set([...SHAPE_SHAPE_CLASSES, ...ONTOLOGY_TERM_CLASSES]);\n const pinned = new Map<IDataset, string[]>();\n for (const [iri, shapeClass] of getAllShapeClasses()) {\n const targetClass = watchedClassOf(shapeClass, watched);\n if (!targetClass) continue;\n const dataset = LinkedStorage.getDatasetForShapeClass(shapeClass);\n if (!dataset || dataset === defaultDataset) continue;\n const list = pinned.get(dataset) ?? [];\n list.push(`${shapeClass.name || iri} (${targetClass})`);\n pinned.set(dataset, list);\n }\n if (pinned.size === 0) return undefined;\n const parts = [...pinned].map(([dataset, shapes]) => `${shapes.sort().join(', ')} → ${datasetName(dataset)}`);\n return (\n `[LinkedServer] Routing pins shapes the boot syncs write to a dataset other than the default ` +\n `one: ${parts.join('; ')}. The ontology and shape syncs, when they run, write into the default dataset ` +\n `(${datasetName(defaultDataset)}) only, so reads of these shapes on the pinned dataset do not ` +\n `see what the syncs wrote.`\n );\n}\n"]}
1
+ {"version":3,"file":"graphTargets.js","sourceRoot":"","sources":["../../../src/utils/graphTargets.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Where the boot syncs keep the registered packages' ontology data and shapes: core's graph\n * targets (`ontologyGraph`, `shapeGraph`; `@_linked/core/utils/graphTargets`), one global setting\n * of the process. `LINKED_ONTOLOGY_GRAPH` and `LINKED_SHAPE_GRAPH` each take `'package'` (the\n * default, one graph per package), `'default'` (the default graph) or the absolute IRI of one\n * shared graph.\n *\n * The server reads them once at boot, checks them (an invalid value stops the boot, naming the\n * variable) and calls core's `setGraphTargets` before the stores are initialised and before the\n * syncs. No store takes a setting of its own, and the frontend needs none: its\n * `.from(graphs.allOntologies)` reaches the backend as the portable name, and the backend's\n * store expands it under this setting.\n *\n * The syncs write into the default dataset only. {@link syncPinWarning} names the shapes whose\n * routing sends their reads elsewhere, when the boot runs those syncs.\n */\nimport {\n GRAPH_TARGET_ENV,\n graphTargetOptionsFromEnv,\n setGraphTargets,\n type GraphTargets,\n} from '@_linked/core/utils/graphTargets';\nimport { LinkedStorage } from '@_linked/core/utils/LinkedStorage';\nimport { getAllShapeClasses } from '@_linked/core/utils/ShapeClass';\nimport type { IDataset } from '@_linked/core/interfaces/IDataset';\n\n/**\n * Read `LINKED_ONTOLOGY_GRAPH` / `LINKED_SHAPE_GRAPH` from `env` (checked: an invalid value throws,\n * naming the variable) and set them as the process's graph targets (core's `setGraphTargets`;\n * unset ones are `'package'`). Returns the settings the env gave.\n */\nexport function applyGraphTargetsFromEnv(env: Record<string, string | undefined>): Partial<GraphTargets> {\n const fromEnv = graphTargetOptionsFromEnv(env);\n setGraphTargets(fromEnv);\n return fromEnv;\n}\n\n/** The env variables as set (unset and empty ones left out), for `GET /admin/routes`. */\nexport function graphTargetEnv(env: Record<string, string | undefined>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const name of [GRAPH_TARGET_ENV.ontologyGraph, GRAPH_TARGET_ENV.shapeGraph]) {\n const value = env[name];\n if (value) out[name] = value;\n }\n return out;\n}\n\nconst SH = 'http://www.w3.org/ns/shacl#';\nconst RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';\nconst RDFS = 'http://www.w3.org/2000/01/rdf-schema#';\nconst OWL = 'http://www.w3.org/2002/07/owl#';\n\n/** The classes of the shape shapes: what the shape sync writes. */\nexport const SHAPE_SHAPE_CLASSES: readonly string[] = [`${SH}NodeShape`, `${SH}PropertyShape`];\n\n/**\n * The classes of the ontology term shapes (the class and property shapes core, `@_linked/rdfs`\n * and `@_linked/owl` register): what the ontology sync writes and the hierarchy reads.\n */\nexport const ONTOLOGY_TERM_CLASSES: readonly string[] = [\n `${RDFS}Class`,\n `${OWL}Class`,\n `${OWL}Restriction`,\n `${RDF}Property`,\n `${OWL}ObjectProperty`,\n `${OWL}DatatypeProperty`,\n `${OWL}AnnotationProperty`,\n];\n\n/**\n * A dataset as a log line tells it apart: its store class, and its `id` when it has one, else the\n * dataset name a SPARQL store keeps from its endpoint (`FusekiStore`'s `dataset`).\n */\nfunction datasetName(dataset: IDataset): string {\n const { id, dataset: name } = dataset as { id?: unknown; dataset?: unknown };\n const store = dataset?.constructor?.name || 'unknown';\n const label = typeof id === 'string' && id ? id : typeof name === 'string' && name ? name : undefined;\n return label ? `${store} \"${label}\"` : store;\n}\n\n/**\n * The class the instances of `shapeClass` carry, when it is watched, else undefined: the\n * `targetClass` of the shape itself or, when it declares none of its own, of the nearest\n * super-shape that does. A sub-shape with its own target class is not its parent's class: the\n * syncs' data of the parent's class never reads through it.\n */\nfunction watchedClassOf(shapeClass: Function, watched: ReadonlySet<string>): string | undefined {\n for (let current: unknown = shapeClass; typeof current === 'function' && current !== Function.prototype; current = Object.getPrototypeOf(current)) {\n if (!Object.prototype.hasOwnProperty.call(current, 'targetClass')) continue;\n const id = (current as { targetClass?: { id?: unknown } }).targetClass?.id;\n return typeof id === 'string' && watched.has(id) ? id : undefined;\n }\n return undefined;\n}\n\n/** Which boot syncs run: only the shapes a running sync writes are worth a warning. */\nexport interface BootSyncs {\n /** The shape sync runs (`shapeSyncOn`): it writes the shape shapes. */\n shapeSync: boolean;\n /** The ontology sync runs (`bootSyncsOntologies`): it writes the ontology term shapes. */\n ontologySync: boolean;\n}\n\n/**\n * One warning when routing pins a shape a boot sync that runs writes (the shape shapes\n * `NodeShape` / `PropertyShape` for the shape sync, an ontology term shape such as `rdfs:Class` /\n * `owl:ObjectProperty` for the ontology sync) to a dataset other than the default one: the syncs\n * write into the default dataset only, so reads of those shapes on the pinned dataset miss what\n * they wrote. Names each such shape and its dataset; a sub-shape counts under the target class it\n * declares, or its parent's when it declares none.\n * Undefined when there is nothing to warn about (no sync runs, or no default dataset). Reads the\n * registered shapes outside any shape catalog (run it at boot, never inside `withShapeCatalog`).\n */\nexport function syncPinWarning(syncs: BootSyncs): string | undefined {\n const defaultDataset = LinkedStorage.getDefaultDataset();\n if (!defaultDataset) return undefined;\n const watched = new Set([\n ...(syncs.shapeSync ? SHAPE_SHAPE_CLASSES : []),\n ...(syncs.ontologySync ? ONTOLOGY_TERM_CLASSES : []),\n ]);\n if (watched.size === 0) return undefined;\n const pinned = new Map<IDataset, string[]>();\n for (const [iri, shapeClass] of getAllShapeClasses()) {\n const targetClass = watchedClassOf(shapeClass, watched);\n if (!targetClass) continue;\n const dataset = LinkedStorage.getDatasetForShapeClass(shapeClass);\n if (!dataset || dataset === defaultDataset) continue;\n const list = pinned.get(dataset) ?? [];\n list.push(`${shapeClass.name || iri} (${targetClass})`);\n pinned.set(dataset, list);\n }\n if (pinned.size === 0) return undefined;\n const parts = [...pinned].map(([dataset, shapes]) => `${shapes.sort().join(', ')} → ${datasetName(dataset)}`);\n const writers =\n syncs.ontologySync && syncs.shapeSync ? 'ontology and shape syncs write' : `${syncs.shapeSync ? 'shape' : 'ontology'} sync writes`;\n return (\n `[LinkedServer] Routing pins shapes the boot syncs write to a dataset other than the default ` +\n `one: ${parts.join('; ')}. The ${writers} into the default dataset (${datasetName(defaultDataset)}) ` +\n `only, so reads of these shapes on the pinned dataset do not see what the boot wrote.`\n );\n}\n"]}
@@ -20,12 +20,26 @@ export interface LinkedDependency {
20
20
  version?: string;
21
21
  }[];
22
22
  }
23
+ /** What a `package.json` is, by its `linked.kind`. */
24
+ export type LinkedKind = 'app' | 'ontology' | 'assets' | 'library';
25
+ /** Every value `linked.kind` may take. */
26
+ export declare const LINKED_KINDS: readonly LinkedKind[];
23
27
  /**
24
- * A package whose backend providers the server loads at boot: one whose
25
- * package.json declares `"linkedPackage": true`. That flag is the only test —
28
+ * THE way to tell what a `package.json` is: its `"linked": {"kind": …}`. `app` is an app (built
29
+ * by `linked build-app`); `ontology`, `assets` and `library` are linked packages (an ontology
30
+ * package may carry shapes for its own terms; `library` is framework code). Undefined for
31
+ * anything else: no `linked` object and a kind that is not one of these.
32
+ *
33
+ * Until every published package carries `linked.kind`, a `package.json` without one is still
34
+ * read by the retired flags: `linkedApp: true` is an `app`, `linkedPackage: true` a `library`.
35
+ */
36
+ export declare function linkedKind(json: unknown): LinkedKind | undefined;
37
+ /**
38
+ * A package whose backend providers the server loads at boot: a named package
39
+ * whose `linked.kind` is not `app` ({@link linkedKind}). That is the only test —
26
40
  * not the package's scope. `@_linked/localize` is in the `@_linked` scope and
27
- * is a CLI tool, not a linked package; a custom-scope package with the flag is
28
- * a linked package. The CLI's workspace discovery uses the same flag.
41
+ * is a CLI tool, not a linked package; a custom-scope package with a kind is
42
+ * a linked package. The CLI's workspace discovery uses the same test.
29
43
  *
30
44
  * The legacy `"lincd": true` flag is deliberately NOT enough. Those packages
31
45
  * import the old `lincd` core, and loading them at boot is what produced
@@ -50,7 +64,34 @@ export declare function readInstalledPackage(name: string, fromDir: string): {
50
64
  json: any;
51
65
  } | null;
52
66
  /**
53
- * Every linked package reachable from the app's `dependencies`, each one AFTER
67
+ * The npm names a `package.json` lists in `linked.unpublishedPackages` (K-unpublished): packages
68
+ * it uses that are not on npm, localized into the app's `packages-local/`. The server treats them
69
+ * as direct dependencies of whoever lists them. Read with the cli's one reader, so a malformed
70
+ * list throws rather than shrinking silently.
71
+ */
72
+ export declare function unpublishedNames(json: unknown): string[];
73
+ /**
74
+ * A package the app lists in `linked.unpublishedPackages`, found by its npm name: first the
75
+ * way Node finds it (`node_modules/<name>` from `fromDir` up, which is npm's workspace link into
76
+ * `packages-local/` once the app is installed), else among `<appDir>/packages-local/<dir>`
77
+ * by the `name` in each `package.json` (a checkout not yet installed). Null when there is no
78
+ * checkout of it.
79
+ */
80
+ export declare function findListedPackage(name: string, fromDir: string, appDir: string): {
81
+ root: string;
82
+ json: any;
83
+ } | null;
84
+ /**
85
+ * Every name in the app's `linked.unpublishedPackages`, and transitively in the lists of the
86
+ * listed packages it finds ({@link findListedPackage}): the packages the server treats as the
87
+ * app's own direct dependencies. A listed package without a checkout still counts; only its own
88
+ * list cannot be read.
89
+ */
90
+ export declare function listedPackageNames(appDir: string, appPackageJson: any): Set<string>;
91
+ /**
92
+ * Every linked package reachable from the app's `dependencies` and its
93
+ * `linked.unpublishedPackages` (transitively, through each package's own
94
+ * `dependencies` and list), each one AFTER
54
95
  * the linked packages it depends on. Providers register middleware in the
55
96
  * order they are indexed, so a package's middleware must not run before that
56
97
  * of a package it builds on (e.g. anything reading `request.linkedAuth` after
@@ -68,10 +109,15 @@ export declare function readInstalledPackage(name: string, fromDir: string): {
68
109
  * is the one the app itself resolves, so it is the same module instance the
69
110
  * app's own imports reach; when the app cannot resolve the package at all
70
111
  * (it is only installed nested) it is the first copy found.
112
+ *
113
+ * `isLinked` decides which installed packages are linked ones (default
114
+ * {@link isLinkedPackageJson}); a caller reading installs of another
115
+ * generation passes its own.
71
116
  */
72
- export declare function discoverLinkedDependencies(appDir: string, appPackageJson: any): LinkedDependency[];
117
+ export declare function discoverLinkedDependencies(appDir: string, appPackageJson: any, isLinked?: (json: any) => boolean): LinkedDependency[];
73
118
  /**
74
- * Package name → the names of its direct `dependencies` and `peerDependencies`, for the app
119
+ * Package name → the names of its direct `dependencies`, `peerDependencies` and
120
+ * `linked.unpublishedPackages`, for the app
75
121
  * (`appPackageJson`) and every package in `packageDirs` (name → package root, as discovery
76
122
  * found it). The shape check scopes its direction-I errors with it. A package whose
77
123
  * `package.json` cannot be read is left out.
@@ -1,11 +1,48 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
+ import { unpublishedPackages } from '@_linked/cli/installed-packages';
4
+ /** Every value `linked.kind` may take. */
5
+ export const LINKED_KINDS = [
6
+ 'app',
7
+ 'ontology',
8
+ 'assets',
9
+ 'library',
10
+ ];
3
11
  /**
4
- * A package whose backend providers the server loads at boot: one whose
5
- * package.json declares `"linkedPackage": true`. That flag is the only test —
12
+ * THE way to tell what a `package.json` is: its `"linked": {"kind": …}`. `app` is an app (built
13
+ * by `linked build-app`); `ontology`, `assets` and `library` are linked packages (an ontology
14
+ * package may carry shapes for its own terms; `library` is framework code). Undefined for
15
+ * anything else: no `linked` object and a kind that is not one of these.
16
+ *
17
+ * Until every published package carries `linked.kind`, a `package.json` without one is still
18
+ * read by the retired flags: `linkedApp: true` is an `app`, `linkedPackage: true` a `library`.
19
+ */
20
+ export function linkedKind(json) {
21
+ var _a;
22
+ if (!json || typeof json !== 'object')
23
+ return undefined;
24
+ const linked = json.linked;
25
+ if (!linked || typeof linked !== 'object')
26
+ return retiredFlagKind(json);
27
+ const kind = linked.kind;
28
+ return (_a = LINKED_KINDS.find((k) => k === kind)) !== null && _a !== void 0 ? _a : retiredFlagKind(json);
29
+ }
30
+ /** The kind a `package.json` published before `linked.kind` declares by its retired flags. */
31
+ function retiredFlagKind(json) {
32
+ const flags = json;
33
+ if (flags.linkedApp === true)
34
+ return 'app';
35
+ if (flags.linkedPackage === true)
36
+ return 'library';
37
+ return undefined;
38
+ }
39
+ // end of the linkedKind twin.
40
+ /**
41
+ * A package whose backend providers the server loads at boot: a named package
42
+ * whose `linked.kind` is not `app` ({@link linkedKind}). That is the only test —
6
43
  * not the package's scope. `@_linked/localize` is in the `@_linked` scope and
7
- * is a CLI tool, not a linked package; a custom-scope package with the flag is
8
- * a linked package. The CLI's workspace discovery uses the same flag.
44
+ * is a CLI tool, not a linked package; a custom-scope package with a kind is
45
+ * a linked package. The CLI's workspace discovery uses the same test.
9
46
  *
10
47
  * The legacy `"lincd": true` flag is deliberately NOT enough. Those packages
11
48
  * import the old `lincd` core, and loading them at boot is what produced
@@ -15,7 +52,8 @@ import * as path from 'path';
15
52
  export function isLinkedPackageJson(json) {
16
53
  if (!json || typeof json.name !== 'string')
17
54
  return false;
18
- return json.linkedPackage === true;
55
+ const kind = linkedKind(json);
56
+ return kind !== undefined && kind !== 'app';
19
57
  }
20
58
  /**
21
59
  * Find an installed package the way Node does: `<dir>/node_modules/<name>`,
@@ -66,7 +104,73 @@ export function readInstalledPackage(name, fromDir) {
66
104
  }
67
105
  }
68
106
  /**
69
- * Every linked package reachable from the app's `dependencies`, each one AFTER
107
+ * The npm names a `package.json` lists in `linked.unpublishedPackages` (K-unpublished): packages
108
+ * it uses that are not on npm, localized into the app's `packages-local/`. The server treats them
109
+ * as direct dependencies of whoever lists them. Read with the cli's one reader, so a malformed
110
+ * list throws rather than shrinking silently.
111
+ */
112
+ export function unpublishedNames(json) {
113
+ return unpublishedPackages(json).map((p) => p.name);
114
+ }
115
+ /** Where a listed package's checkout lives in the app, when npm has not linked it yet. */
116
+ const LOCAL_DIR = 'packages-local';
117
+ /**
118
+ * A package the app lists in `linked.unpublishedPackages`, found by its npm name: first the
119
+ * way Node finds it (`node_modules/<name>` from `fromDir` up, which is npm's workspace link into
120
+ * `packages-local/` once the app is installed), else among `<appDir>/packages-local/<dir>`
121
+ * by the `name` in each `package.json` (a checkout not yet installed). Null when there is no
122
+ * checkout of it.
123
+ */
124
+ export function findListedPackage(name, fromDir, appDir) {
125
+ const installed = readInstalledPackage(name, fromDir);
126
+ if (installed)
127
+ return installed;
128
+ const localDir = path.join(appDir, LOCAL_DIR);
129
+ let entries = [];
130
+ try {
131
+ entries = fs.readdirSync(localDir).sort();
132
+ }
133
+ catch (_a) {
134
+ return null;
135
+ }
136
+ for (const entry of entries) {
137
+ const root = path.join(localDir, entry);
138
+ try {
139
+ const json = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf-8'));
140
+ if ((json === null || json === void 0 ? void 0 : json.name) === name)
141
+ return { root, json };
142
+ }
143
+ catch (_b) { }
144
+ }
145
+ return null;
146
+ }
147
+ /**
148
+ * Every name in the app's `linked.unpublishedPackages`, and transitively in the lists of the
149
+ * listed packages it finds ({@link findListedPackage}): the packages the server treats as the
150
+ * app's own direct dependencies. A listed package without a checkout still counts; only its own
151
+ * list cannot be read.
152
+ */
153
+ export function listedPackageNames(appDir, appPackageJson) {
154
+ const names = new Set();
155
+ const queue = unpublishedNames(appPackageJson).map((name) => ({ name, fromDir: appDir }));
156
+ while (queue.length) {
157
+ const { name, fromDir } = queue.shift();
158
+ if (names.has(name) || name === (appPackageJson === null || appPackageJson === void 0 ? void 0 : appPackageJson.name))
159
+ continue;
160
+ names.add(name);
161
+ const found = findListedPackage(name, fromDir, appDir);
162
+ if (!found)
163
+ continue;
164
+ const root = realpathOr(found.root);
165
+ for (const next of unpublishedNames(found.json))
166
+ queue.push({ name: next, fromDir: root });
167
+ }
168
+ return names;
169
+ }
170
+ /**
171
+ * Every linked package reachable from the app's `dependencies` and its
172
+ * `linked.unpublishedPackages` (transitively, through each package's own
173
+ * `dependencies` and list), each one AFTER
70
174
  * the linked packages it depends on. Providers register middleware in the
71
175
  * order they are indexed, so a package's middleware must not run before that
72
176
  * of a package it builds on (e.g. anything reading `request.linkedAuth` after
@@ -84,19 +188,25 @@ export function readInstalledPackage(name, fromDir) {
84
188
  * is the one the app itself resolves, so it is the same module instance the
85
189
  * app's own imports reach; when the app cannot resolve the package at all
86
190
  * (it is only installed nested) it is the first copy found.
191
+ *
192
+ * `isLinked` decides which installed packages are linked ones (default
193
+ * {@link isLinkedPackageJson}); a caller reading installs of another
194
+ * generation passes its own.
87
195
  */
88
- export function discoverLinkedDependencies(appDir, appPackageJson) {
196
+ export function discoverLinkedDependencies(appDir, appPackageJson, isLinked = isLinkedPackageJson) {
89
197
  var _a;
90
198
  const out = [];
91
199
  const byName = new Map();
92
200
  const visitedRoots = new Set();
93
201
  const appName = appPackageJson === null || appPackageJson === void 0 ? void 0 : appPackageJson.name;
94
- const visit = (name, fromDir) => {
202
+ const visit = (name, fromDir, listed = false) => {
95
203
  var _a;
96
204
  if (name === appName)
97
205
  return;
98
- const installed = readInstalledPackage(name, fromDir);
99
- if (!installed || !isLinkedPackageJson(installed.json))
206
+ const installed = listed
207
+ ? findListedPackage(name, fromDir, appDir)
208
+ : readInstalledPackage(name, fromDir);
209
+ if (!installed || !isLinked(installed.json))
100
210
  return;
101
211
  const realRoot = realpathOr(installed.root);
102
212
  if (visitedRoots.has(realRoot))
@@ -111,6 +221,9 @@ export function discoverLinkedDependencies(appDir, appPackageJson) {
111
221
  for (const dep of Object.keys((_a = installed.json.dependencies) !== null && _a !== void 0 ? _a : {})) {
112
222
  visit(dep, realRoot);
113
223
  }
224
+ for (const dep of unpublishedNames(installed.json)) {
225
+ visit(dep, realRoot, true);
226
+ }
114
227
  // Pushed after its dependencies, once per name: the first copy found
115
228
  // fixes the package's place in the order.
116
229
  if (!out.includes(entry))
@@ -119,11 +232,14 @@ export function discoverLinkedDependencies(appDir, appPackageJson) {
119
232
  for (const name of Object.keys((_a = appPackageJson === null || appPackageJson === void 0 ? void 0 : appPackageJson.dependencies) !== null && _a !== void 0 ? _a : {})) {
120
233
  visit(name, appDir);
121
234
  }
235
+ for (const name of unpublishedNames(appPackageJson)) {
236
+ visit(name, appDir, true);
237
+ }
122
238
  for (const entry of out) {
123
239
  if (entry.copies.length < 2)
124
240
  continue;
125
241
  const fromApp = readInstalledPackage(entry.packageName, appDir);
126
- if (fromApp && isLinkedPackageJson(fromApp.json)) {
242
+ if (fromApp && isLinked(fromApp.json)) {
127
243
  const appCopy = realpathOr(fromApp.root);
128
244
  if (entry.copies.some((c) => c.path === appCopy))
129
245
  entry.path = appCopy;
@@ -132,7 +248,8 @@ export function discoverLinkedDependencies(appDir, appPackageJson) {
132
248
  return out;
133
249
  }
134
250
  /**
135
- * Package name → the names of its direct `dependencies` and `peerDependencies`, for the app
251
+ * Package name → the names of its direct `dependencies`, `peerDependencies` and
252
+ * `linked.unpublishedPackages`, for the app
136
253
  * (`appPackageJson`) and every package in `packageDirs` (name → package root, as discovery
137
254
  * found it). The shape check scopes its direction-I errors with it. A package whose
138
255
  * `package.json` cannot be read is left out.
@@ -147,6 +264,7 @@ export function readDependencyLists(packageDirs, appPackageJson) {
147
264
  ...new Set([
148
265
  ...Object.keys((_a = json === null || json === void 0 ? void 0 : json.dependencies) !== null && _a !== void 0 ? _a : {}),
149
266
  ...Object.keys((_b = json === null || json === void 0 ? void 0 : json.peerDependencies) !== null && _b !== void 0 ? _b : {}),
267
+ ...unpublishedNames(json),
150
268
  ]),
151
269
  ].sort();
152
270
  };
@@ -1 +1 @@
1
- {"version":3,"file":"linkedDependencies.js","sourceRoot":"","sources":["../../../src/utils/linkedDependencies.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * A linked package found in the app's dependency tree, wherever it is\n * installed: a workspace member, a localized checkout, or a registry install.\n */\nexport interface LinkedDependency {\n packageName: string;\n /**\n * Realpath of the package root whose backend the server loads: the copy the\n * app itself resolves when that copy is a linked package, otherwise the\n * first copy the walk found.\n */\n path: string;\n /**\n * Every distinct installed copy of this package in the tree (realpaths),\n * in the order the walk found them. More than one means the install is not\n * deduplicated; only `path`'s backend is ever loaded.\n */\n copies: { path: string; version?: string }[];\n}\n\n/**\n * A package whose backend providers the server loads at boot: one whose\n * package.json declares `\"linkedPackage\": true`. That flag is the only test —\n * not the package's scope. `@_linked/localize` is in the `@_linked` scope and\n * is a CLI tool, not a linked package; a custom-scope package with the flag is\n * a linked package. The CLI's workspace discovery uses the same flag.\n *\n * The legacy `\"lincd\": true` flag is deliberately NOT enough. Those packages\n * import the old `lincd` core, and loading them at boot is what produced\n * \"Multiple versions of LINCD are loaded\" before boot loading was narrowed to\n * workspace members.\n */\nexport function isLinkedPackageJson(json: any): boolean {\n if (!json || typeof json.name !== 'string') return false;\n return json.linkedPackage === true;\n}\n\n/**\n * Find an installed package the way Node does: `<dir>/node_modules/<name>`,\n * then each parent directory's `node_modules`. Returns null when it is not\n * installed (an optional dependency, say) rather than throwing.\n */\n/**\n * Whether a package has a JavaScript entry the server can import: `main`,\n * `module`, or an `exports` map with a root (`.`) entry or a single string.\n * A linked package can be pure CSS (`@_linked/css`); importing that whole\n * fails with \"Failed to resolve entry\", so the server skips it.\n */\nexport function hasModuleEntry(json: any): boolean {\n if (!json) return false;\n if (typeof json.main === 'string' || typeof json.module === 'string') {\n return true;\n }\n const exp = json.exports;\n if (typeof exp === 'string') return true;\n if (exp && typeof exp === 'object') {\n const keys = Object.keys(exp);\n // Conditions only ({import, require, ...}) describe the root entry.\n if (keys.length > 0 && keys.every((k) => !k.startsWith('.'))) return true;\n return '.' in exp;\n }\n return false;\n}\n\nexport function readInstalledPackage(\n name: string,\n fromDir: string\n): { root: string; json: any } | null {\n let dir = path.resolve(fromDir);\n while (true) {\n const root = path.join(dir, 'node_modules', name);\n const pkgJsonPath = path.join(root, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {\n try {\n return { root, json: JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) };\n } catch {\n return null;\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Every linked package reachable from the app's `dependencies`, each one AFTER\n * the linked packages it depends on. Providers register middleware in the\n * order they are indexed, so a package's middleware must not run before that\n * of a package it builds on (e.g. anything reading `request.linkedAuth` after\n * @_linked/auth's JWT middleware).\n *\n * Only linked packages are recursed into — the same rule the workspace-only\n * filter used — so the walk reads a few dozen package.json files, not the\n * whole of node_modules. Each package's dependencies are resolved from its\n * REAL location, so a symlinked workspace or localized checkout resolves its\n * own dependencies the way Node will when it loads it — which is how a\n * package installed only nested (`owl/node_modules/@_linked/rdfs`) is found.\n *\n * The walk is keyed by real path, not name, so every installed copy of a\n * package is recorded (`copies`). The copy whose backend is loaded (`path`)\n * is the one the app itself resolves, so it is the same module instance the\n * app's own imports reach; when the app cannot resolve the package at all\n * (it is only installed nested) it is the first copy found.\n */\nexport function discoverLinkedDependencies(\n appDir: string,\n appPackageJson: any\n): LinkedDependency[] {\n const out: LinkedDependency[] = [];\n const byName = new Map<string, LinkedDependency>();\n const visitedRoots = new Set<string>();\n const appName = appPackageJson?.name;\n\n const visit = (name: string, fromDir: string) => {\n if (name === appName) return;\n const installed = readInstalledPackage(name, fromDir);\n if (!installed || !isLinkedPackageJson(installed.json)) return;\n const realRoot = realpathOr(installed.root);\n if (visitedRoots.has(realRoot)) return;\n visitedRoots.add(realRoot);\n let entry = byName.get(name);\n if (!entry) {\n entry = { packageName: name, path: realRoot, copies: [] };\n byName.set(name, entry);\n }\n entry.copies.push({ path: realRoot, version: installed.json.version });\n for (const dep of Object.keys(installed.json.dependencies ?? {})) {\n visit(dep, realRoot);\n }\n // Pushed after its dependencies, once per name: the first copy found\n // fixes the package's place in the order.\n if (!out.includes(entry)) out.push(entry);\n };\n\n for (const name of Object.keys(appPackageJson?.dependencies ?? {})) {\n visit(name, appDir);\n }\n\n for (const entry of out) {\n if (entry.copies.length < 2) continue;\n const fromApp = readInstalledPackage(entry.packageName, appDir);\n if (fromApp && isLinkedPackageJson(fromApp.json)) {\n const appCopy = realpathOr(fromApp.root);\n if (entry.copies.some((c) => c.path === appCopy)) entry.path = appCopy;\n }\n }\n return out;\n}\n\n/**\n * Package name → the names of its direct `dependencies` and `peerDependencies`, for the app\n * (`appPackageJson`) and every package in `packageDirs` (name → package root, as discovery\n * found it). The shape check scopes its direction-I errors with it. A package whose\n * `package.json` cannot be read is left out.\n */\nexport function readDependencyLists(\n packageDirs: Iterable<[string, string]>,\n appPackageJson?: any\n): Record<string, string[]> {\n const lists: Record<string, string[]> = {};\n const add = (name: unknown, json: any) => {\n if (typeof name !== 'string' || !name) return;\n lists[name] = [\n ...new Set([\n ...Object.keys(json?.dependencies ?? {}),\n ...Object.keys(json?.peerDependencies ?? {}),\n ]),\n ].sort();\n };\n if (appPackageJson) add(appPackageJson.name, appPackageJson);\n for (const [name, dir] of packageDirs) {\n try {\n add(name, JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8')));\n } catch {}\n }\n return lists;\n}\n\nfunction realpathOr(p: string): string {\n try {\n return fs.realpathSync(p);\n } catch {\n return p;\n }\n}\n\n/**\n * The conditions a backend entry is resolved with on the Node path. These are\n * the ones Node's ESM loader applies to `import()` — so the file found is the\n * file a bare `import('<pkg>/backend')` from the app would load, and Node's\n * module cache (keyed by real file URL) hands both the same instance.\n * `development` is deliberately absent: it is a Vite/bundler condition, and a\n * production Node runtime never applies it.\n */\nexport const NODE_IMPORT_CONDITIONS = ['import', 'node', 'default'] as const;\n\n/**\n * The absolute path of a package's backend entry file, or null when the\n * package has no backend entry or the file it names does not exist.\n *\n * With `exports`, this follows Node's PACKAGE_EXPORTS_RESOLVE for the\n * `./backend` subpath: an exact `./backend` key wins; otherwise the `./*`-style\n * pattern with the longest matching prefix; condition objects (nested or not)\n * pick the first key that is one of `conditions` or `default`; arrays take the\n * first target that resolves. A package that has `exports` but nothing\n * matching `./backend` has no backend — exactly as Node would refuse to\n * import it.\n *\n * Without `exports`, the legacy layout: `<root>/backend.js`,\n * `<root>/backend/index.js`, and the layout linked packages build to — a\n * `backend.js` next to `main` (`lib/esm/backend.js`).\n *\n * Hand-written rather than via `resolve.exports`: that package also stops at\n * a path and leaves the existence check to the caller, the subset needed is\n * ~50 lines, and the server keeps one less dependency in every app's install.\n */\nexport function resolveBackendEntry(\n pkgRoot: string,\n pkgJson: any,\n conditions: readonly string[] = NODE_IMPORT_CONDITIONS\n): string | null {\n const exists = (rel: string) => packageFile(pkgRoot, rel);\n const exportsField = pkgJson?.exports;\n if (exportsField === undefined || exportsField === null) {\n const candidates = ['backend.js', 'backend/index.js'];\n if (typeof pkgJson?.main === 'string') {\n candidates.push(path.join(path.dirname(pkgJson.main), 'backend.js'));\n }\n candidates.push('lib/esm/backend.js');\n for (const rel of candidates) {\n const file = exists(rel);\n if (file) return file;\n }\n return null;\n }\n return resolveBackendExport(exportsField, conditions, exists);\n}\n\n/** `<pkgRoot>/<rel>` when it is a file inside the package, else null. */\nfunction packageFile(pkgRoot: string, rel: string): string | null {\n const file = path.resolve(pkgRoot, rel);\n // Never let an export target escape the package.\n if (!file.startsWith(path.resolve(pkgRoot) + path.sep)) return null;\n try {\n return fs.statSync(file).isFile() ? file : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The `./backend` subpath of an `exports` map, resolved per Node's\n * PACKAGE_EXPORTS_RESOLVE (see resolveBackendEntry). `probe` turns a matched\n * `./`-relative target into a file, or null when it does not resolve.\n */\nfunction resolveBackendExport(\n exportsField: any,\n conditions: readonly string[],\n probe: (rel: string) => string | null\n): string | null {\n // `\"exports\": \"./x.js\"`, an array, or a condition object at the top level\n // are all sugar for the \".\" subpath only.\n if (\n typeof exportsField !== 'object' ||\n Array.isArray(exportsField) ||\n !Object.keys(exportsField).some((k) => k.startsWith('.'))\n ) {\n return null;\n }\n\n const subpath = './backend';\n let target: any;\n let patternMatch: string | null = null;\n if (Object.prototype.hasOwnProperty.call(exportsField, subpath)) {\n target = exportsField[subpath];\n } else {\n let bestKey: string | null = null;\n for (const key of Object.keys(exportsField)) {\n const star = key.indexOf('*');\n if (star === -1 || key.indexOf('*', star + 1) !== -1) continue;\n const prefix = key.slice(0, star);\n const suffix = key.slice(star + 1);\n if (\n subpath !== prefix &&\n subpath.length >= key.length &&\n subpath.startsWith(prefix) &&\n subpath.endsWith(suffix) &&\n (bestKey === null || patternKeyCompare(bestKey, key) > 0)\n ) {\n bestKey = key;\n patternMatch = subpath.slice(prefix.length, subpath.length - suffix.length);\n }\n }\n if (bestKey === null) return null;\n target = exportsField[bestKey];\n }\n\n const resolveTarget = (t: any): string | null => {\n if (typeof t === 'string') {\n if (!t.startsWith('./')) return null;\n const rel = patternMatch === null ? t : t.split('*').join(patternMatch);\n return probe(rel);\n }\n if (Array.isArray(t)) {\n for (const item of t) {\n const file = resolveTarget(item);\n if (file) return file;\n }\n return null;\n }\n if (t && typeof t === 'object') {\n for (const key of Object.keys(t)) {\n if (key === 'default' || conditions.includes(key)) {\n // Node takes the first matching condition even if its target fails\n // to resolve; it does not fall through to later keys.\n return resolveTarget(t[key]);\n }\n }\n }\n return null;\n };\n return resolveTarget(target);\n}\n\n/**\n * The SOURCE file a dev Vite runner loads for `<pkg>/backend` when the\n * package is a source package — its real root has a `src/` directory, which is\n * what makes `linked`'s Vite config register it as a workspace (cli\n * `discoverWorkspaces` / `readSourcePackage`). Null when the package has no\n * `src/` or no source backend; the caller then falls back to\n * resolveBackendEntry (a built `lib/` copy, or nothing).\n *\n * Mirrors the cli's `resolveWorkspaceSpecifier` for the `./backend` subpath,\n * which runs BEFORE `exports`: `src/backend.tsx`, `src/backend.ts`, then the\n * package's own `exports` under `import`/`default` with a `./lib/esm/X.js`\n * target mapped to `src/X.tsx` / `src/X.ts` (any other `./lib/esm/` target to\n * the same path under src). So an unbuilt workspace, whose `exports` name only\n * `lib/esm`, still has its backend found, and a built one reports the src file\n * Vite actually evaluates rather than its stale `lib/`.\n *\n * Only meaningful when the dev Vite runner owns the package; Node (production,\n * external packages) loads `lib/` and never sees src.\n */\nexport function resolveSourceBackendEntry(\n pkgRoot: string,\n pkgJson: any\n): string | null {\n try {\n if (!fs.statSync(path.join(pkgRoot, 'src')).isDirectory()) return null;\n } catch {\n return null;\n }\n for (const rel of ['src/backend.tsx', 'src/backend.ts']) {\n const file = packageFile(pkgRoot, rel);\n if (file) return file;\n }\n const exportsField = pkgJson?.exports;\n if (exportsField === undefined || exportsField === null) return null;\n const libPrefix = './lib/esm/';\n return resolveBackendExport(exportsField, ['import'], (rel) => {\n if (!rel.startsWith(libPrefix)) return null;\n const sub = rel.slice(libPrefix.length);\n if (/\\.jsx?$/.test(sub)) {\n const base = 'src/' + sub.replace(/\\.jsx?$/, '');\n return packageFile(pkgRoot, base + '.tsx') ?? packageFile(pkgRoot, base + '.ts');\n }\n return packageFile(pkgRoot, 'src/' + sub);\n });\n}\n\n/** Node's PATTERN_KEY_COMPARE: < 0 means `a` is the more specific pattern. */\nfunction patternKeyCompare(a: string, b: string): number {\n const aBase = a.indexOf('*');\n const bBase = b.indexOf('*');\n const baseA = aBase === -1 ? a.length : aBase + 1;\n const baseB = bBase === -1 ? b.length : bBase + 1;\n if (baseA > baseB) return -1;\n if (baseB > baseA) return 1;\n if (aBase === -1) return 1;\n if (bBase === -1) return -1;\n if (a.length > b.length) return -1;\n if (b.length > a.length) return 1;\n return 0;\n}\n\n/**\n * Whether the dev SSR runner BUNDLES `pkgName` (it is in Vite's\n * `ssr.noExternal`) rather than handing it to Node.\n *\n * This decides which loader a package's backend must be loaded with. A module\n * has to be evaluated by the same loader that evaluates the package everywhere\n * else in the SSR graph, or it runs twice:\n *\n * - `vite.ssrLoadModule('<external pkg>/backend')` transforms that entry and\n * its relative imports even though the package is external, while the app's\n * bare imports of the same package are evaluated by Node — two copies of the\n * package's module state.\n * - a plain `import()` of a BUNDLED package goes to Node, while the app's\n * imports of it are evaluated by Vite — the same split the other way round.\n *\n * Vite matches `noExternal` entries against the bare package name, so a\n * subpath (`pkg/backend`) is covered by an entry for `pkg`.\n */\nexport function isBundledBySsr(pkgName: string, noExternal: unknown): boolean {\n if (noExternal === true) return true;\n const entries = Array.isArray(noExternal)\n ? noExternal\n : noExternal\n ? [noExternal]\n : [];\n return entries.some((entry) =>\n typeof entry === 'string'\n ? entry === pkgName\n : entry instanceof RegExp\n ? entry.test(pkgName)\n : false\n );\n}\n\n/** The dev SSR runner's resolved `noExternal`, wherever this Vite keeps it. */\nexport function ssrNoExternalOf(vite: any): unknown {\n return (\n vite?.config?.ssr?.noExternal ??\n vite?.config?.environments?.ssr?.resolve?.noExternal\n );\n}\n\n/**\n * The backend entry of a package the dev Vite runner owns (see isBundledBySsr):\n * its source backend when it is a source package (resolveSourceBackendEntry),\n * otherwise what `exports` names under the `development` condition and Node's\n * import conditions. A registry install has no src/, so it resolves exactly\n * as before.\n */\nexport function resolveDevBackendEntry(\n pkgRoot: string,\n pkgJson: any\n): string | null {\n return (\n resolveSourceBackendEntry(pkgRoot, pkgJson) ??\n resolveBackendEntry(pkgRoot, pkgJson, [\n 'development',\n ...NODE_IMPORT_CONDITIONS,\n ])\n );\n}\n"]}
1
+ {"version":3,"file":"linkedDependencies.js","sourceRoot":"","sources":["../../../src/utils/linkedDependencies.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { unpublishedPackages } from '@_linked/cli/installed-packages';\n\n/**\n * A linked package found in the app's dependency tree, wherever it is\n * installed: a workspace member, a localized checkout, or a registry install.\n */\nexport interface LinkedDependency {\n packageName: string;\n /**\n * Realpath of the package root whose backend the server loads: the copy the\n * app itself resolves when that copy is a linked package, otherwise the\n * first copy the walk found.\n */\n path: string;\n /**\n * Every distinct installed copy of this package in the tree (realpaths),\n * in the order the walk found them. More than one means the install is not\n * deduplicated; only `path`'s backend is ever loaded.\n */\n copies: { path: string; version?: string }[];\n}\n\n// linkedKind: twin of @_linked/cli src/installed-packages.ts, keep byte-identical.\n/** What a `package.json` is, by its `linked.kind`. */\nexport type LinkedKind = 'app' | 'ontology' | 'assets' | 'library';\n\n/** Every value `linked.kind` may take. */\nexport const LINKED_KINDS: readonly LinkedKind[] = [\n 'app',\n 'ontology',\n 'assets',\n 'library',\n];\n\n/**\n * THE way to tell what a `package.json` is: its `\"linked\": {\"kind\": …}`. `app` is an app (built\n * by `linked build-app`); `ontology`, `assets` and `library` are linked packages (an ontology\n * package may carry shapes for its own terms; `library` is framework code). Undefined for\n * anything else: no `linked` object and a kind that is not one of these.\n *\n * Until every published package carries `linked.kind`, a `package.json` without one is still\n * read by the retired flags: `linkedApp: true` is an `app`, `linkedPackage: true` a `library`.\n */\nexport function linkedKind(json: unknown): LinkedKind | undefined {\n if (!json || typeof json !== 'object') return undefined;\n const linked: unknown = (json as {linked?: unknown}).linked;\n if (!linked || typeof linked !== 'object') return retiredFlagKind(json);\n const kind: unknown = (linked as {kind?: unknown}).kind;\n return LINKED_KINDS.find((k) => k === kind) ?? retiredFlagKind(json);\n}\n\n/** The kind a `package.json` published before `linked.kind` declares by its retired flags. */\nfunction retiredFlagKind(json: object): LinkedKind | undefined {\n const flags = json as {linkedApp?: unknown; linkedPackage?: unknown};\n if (flags.linkedApp === true) return 'app';\n if (flags.linkedPackage === true) return 'library';\n return undefined;\n}\n// end of the linkedKind twin.\n\n/**\n * A package whose backend providers the server loads at boot: a named package\n * whose `linked.kind` is not `app` ({@link linkedKind}). That is the only test —\n * not the package's scope. `@_linked/localize` is in the `@_linked` scope and\n * is a CLI tool, not a linked package; a custom-scope package with a kind is\n * a linked package. The CLI's workspace discovery uses the same test.\n *\n * The legacy `\"lincd\": true` flag is deliberately NOT enough. Those packages\n * import the old `lincd` core, and loading them at boot is what produced\n * \"Multiple versions of LINCD are loaded\" before boot loading was narrowed to\n * workspace members.\n */\nexport function isLinkedPackageJson(json: any): boolean {\n if (!json || typeof json.name !== 'string') return false;\n const kind = linkedKind(json);\n return kind !== undefined && kind !== 'app';\n}\n\n/**\n * Find an installed package the way Node does: `<dir>/node_modules/<name>`,\n * then each parent directory's `node_modules`. Returns null when it is not\n * installed (an optional dependency, say) rather than throwing.\n */\n/**\n * Whether a package has a JavaScript entry the server can import: `main`,\n * `module`, or an `exports` map with a root (`.`) entry or a single string.\n * A linked package can be pure CSS (`@_linked/css`); importing that whole\n * fails with \"Failed to resolve entry\", so the server skips it.\n */\nexport function hasModuleEntry(json: any): boolean {\n if (!json) return false;\n if (typeof json.main === 'string' || typeof json.module === 'string') {\n return true;\n }\n const exp = json.exports;\n if (typeof exp === 'string') return true;\n if (exp && typeof exp === 'object') {\n const keys = Object.keys(exp);\n // Conditions only ({import, require, ...}) describe the root entry.\n if (keys.length > 0 && keys.every((k) => !k.startsWith('.'))) return true;\n return '.' in exp;\n }\n return false;\n}\n\nexport function readInstalledPackage(\n name: string,\n fromDir: string\n): { root: string; json: any } | null {\n let dir = path.resolve(fromDir);\n while (true) {\n const root = path.join(dir, 'node_modules', name);\n const pkgJsonPath = path.join(root, 'package.json');\n if (fs.existsSync(pkgJsonPath)) {\n try {\n return { root, json: JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) };\n } catch {\n return null;\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * The npm names a `package.json` lists in `linked.unpublishedPackages` (K-unpublished): packages\n * it uses that are not on npm, localized into the app's `packages-local/`. The server treats them\n * as direct dependencies of whoever lists them. Read with the cli's one reader, so a malformed\n * list throws rather than shrinking silently.\n */\nexport function unpublishedNames(json: unknown): string[] {\n return unpublishedPackages(json).map((p) => p.name);\n}\n\n/** Where a listed package's checkout lives in the app, when npm has not linked it yet. */\nconst LOCAL_DIR = 'packages-local';\n\n/**\n * A package the app lists in `linked.unpublishedPackages`, found by its npm name: first the\n * way Node finds it (`node_modules/<name>` from `fromDir` up, which is npm's workspace link into\n * `packages-local/` once the app is installed), else among `<appDir>/packages-local/<dir>`\n * by the `name` in each `package.json` (a checkout not yet installed). Null when there is no\n * checkout of it.\n */\nexport function findListedPackage(\n name: string,\n fromDir: string,\n appDir: string\n): { root: string; json: any } | null {\n const installed = readInstalledPackage(name, fromDir);\n if (installed) return installed;\n const localDir = path.join(appDir, LOCAL_DIR);\n let entries: string[] = [];\n try {\n entries = fs.readdirSync(localDir).sort();\n } catch {\n return null;\n }\n for (const entry of entries) {\n const root = path.join(localDir, entry);\n try {\n const json = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf-8'));\n if (json?.name === name) return { root, json };\n } catch {}\n }\n return null;\n}\n\n/**\n * Every name in the app's `linked.unpublishedPackages`, and transitively in the lists of the\n * listed packages it finds ({@link findListedPackage}): the packages the server treats as the\n * app's own direct dependencies. A listed package without a checkout still counts; only its own\n * list cannot be read.\n */\nexport function listedPackageNames(appDir: string, appPackageJson: any): Set<string> {\n const names = new Set<string>();\n const queue = unpublishedNames(appPackageJson).map((name) => ({ name, fromDir: appDir }));\n while (queue.length) {\n const { name, fromDir } = queue.shift()!;\n if (names.has(name) || name === appPackageJson?.name) continue;\n names.add(name);\n const found = findListedPackage(name, fromDir, appDir);\n if (!found) continue;\n const root = realpathOr(found.root);\n for (const next of unpublishedNames(found.json)) queue.push({ name: next, fromDir: root });\n }\n return names;\n}\n\n/**\n * Every linked package reachable from the app's `dependencies` and its\n * `linked.unpublishedPackages` (transitively, through each package's own\n * `dependencies` and list), each one AFTER\n * the linked packages it depends on. Providers register middleware in the\n * order they are indexed, so a package's middleware must not run before that\n * of a package it builds on (e.g. anything reading `request.linkedAuth` after\n * @_linked/auth's JWT middleware).\n *\n * Only linked packages are recursed into — the same rule the workspace-only\n * filter used — so the walk reads a few dozen package.json files, not the\n * whole of node_modules. Each package's dependencies are resolved from its\n * REAL location, so a symlinked workspace or localized checkout resolves its\n * own dependencies the way Node will when it loads it — which is how a\n * package installed only nested (`owl/node_modules/@_linked/rdfs`) is found.\n *\n * The walk is keyed by real path, not name, so every installed copy of a\n * package is recorded (`copies`). The copy whose backend is loaded (`path`)\n * is the one the app itself resolves, so it is the same module instance the\n * app's own imports reach; when the app cannot resolve the package at all\n * (it is only installed nested) it is the first copy found.\n *\n * `isLinked` decides which installed packages are linked ones (default\n * {@link isLinkedPackageJson}); a caller reading installs of another\n * generation passes its own.\n */\nexport function discoverLinkedDependencies(\n appDir: string,\n appPackageJson: any,\n isLinked: (json: any) => boolean = isLinkedPackageJson\n): LinkedDependency[] {\n const out: LinkedDependency[] = [];\n const byName = new Map<string, LinkedDependency>();\n const visitedRoots = new Set<string>();\n const appName = appPackageJson?.name;\n\n const visit = (name: string, fromDir: string, listed = false) => {\n if (name === appName) return;\n const installed = listed\n ? findListedPackage(name, fromDir, appDir)\n : readInstalledPackage(name, fromDir);\n if (!installed || !isLinked(installed.json)) return;\n const realRoot = realpathOr(installed.root);\n if (visitedRoots.has(realRoot)) return;\n visitedRoots.add(realRoot);\n let entry = byName.get(name);\n if (!entry) {\n entry = { packageName: name, path: realRoot, copies: [] };\n byName.set(name, entry);\n }\n entry.copies.push({ path: realRoot, version: installed.json.version });\n for (const dep of Object.keys(installed.json.dependencies ?? {})) {\n visit(dep, realRoot);\n }\n for (const dep of unpublishedNames(installed.json)) {\n visit(dep, realRoot, true);\n }\n // Pushed after its dependencies, once per name: the first copy found\n // fixes the package's place in the order.\n if (!out.includes(entry)) out.push(entry);\n };\n\n for (const name of Object.keys(appPackageJson?.dependencies ?? {})) {\n visit(name, appDir);\n }\n for (const name of unpublishedNames(appPackageJson)) {\n visit(name, appDir, true);\n }\n\n for (const entry of out) {\n if (entry.copies.length < 2) continue;\n const fromApp = readInstalledPackage(entry.packageName, appDir);\n if (fromApp && isLinked(fromApp.json)) {\n const appCopy = realpathOr(fromApp.root);\n if (entry.copies.some((c) => c.path === appCopy)) entry.path = appCopy;\n }\n }\n return out;\n}\n\n/**\n * Package name → the names of its direct `dependencies`, `peerDependencies` and\n * `linked.unpublishedPackages`, for the app\n * (`appPackageJson`) and every package in `packageDirs` (name → package root, as discovery\n * found it). The shape check scopes its direction-I errors with it. A package whose\n * `package.json` cannot be read is left out.\n */\nexport function readDependencyLists(\n packageDirs: Iterable<[string, string]>,\n appPackageJson?: any\n): Record<string, string[]> {\n const lists: Record<string, string[]> = {};\n const add = (name: unknown, json: any) => {\n if (typeof name !== 'string' || !name) return;\n lists[name] = [\n ...new Set([\n ...Object.keys(json?.dependencies ?? {}),\n ...Object.keys(json?.peerDependencies ?? {}),\n ...unpublishedNames(json),\n ]),\n ].sort();\n };\n if (appPackageJson) add(appPackageJson.name, appPackageJson);\n for (const [name, dir] of packageDirs) {\n try {\n add(name, JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8')));\n } catch {}\n }\n return lists;\n}\n\nfunction realpathOr(p: string): string {\n try {\n return fs.realpathSync(p);\n } catch {\n return p;\n }\n}\n\n/**\n * The conditions a backend entry is resolved with on the Node path. These are\n * the ones Node's ESM loader applies to `import()` — so the file found is the\n * file a bare `import('<pkg>/backend')` from the app would load, and Node's\n * module cache (keyed by real file URL) hands both the same instance.\n * `development` is deliberately absent: it is a Vite/bundler condition, and a\n * production Node runtime never applies it.\n */\nexport const NODE_IMPORT_CONDITIONS = ['import', 'node', 'default'] as const;\n\n/**\n * The absolute path of a package's backend entry file, or null when the\n * package has no backend entry or the file it names does not exist.\n *\n * With `exports`, this follows Node's PACKAGE_EXPORTS_RESOLVE for the\n * `./backend` subpath: an exact `./backend` key wins; otherwise the `./*`-style\n * pattern with the longest matching prefix; condition objects (nested or not)\n * pick the first key that is one of `conditions` or `default`; arrays take the\n * first target that resolves. A package that has `exports` but nothing\n * matching `./backend` has no backend — exactly as Node would refuse to\n * import it.\n *\n * Without `exports`, the legacy layout: `<root>/backend.js`,\n * `<root>/backend/index.js`, and the layout linked packages build to — a\n * `backend.js` next to `main` (`lib/esm/backend.js`).\n *\n * Hand-written rather than via `resolve.exports`: that package also stops at\n * a path and leaves the existence check to the caller, the subset needed is\n * ~50 lines, and the server keeps one less dependency in every app's install.\n */\nexport function resolveBackendEntry(\n pkgRoot: string,\n pkgJson: any,\n conditions: readonly string[] = NODE_IMPORT_CONDITIONS\n): string | null {\n const exists = (rel: string) => packageFile(pkgRoot, rel);\n const exportsField = pkgJson?.exports;\n if (exportsField === undefined || exportsField === null) {\n const candidates = ['backend.js', 'backend/index.js'];\n if (typeof pkgJson?.main === 'string') {\n candidates.push(path.join(path.dirname(pkgJson.main), 'backend.js'));\n }\n candidates.push('lib/esm/backend.js');\n for (const rel of candidates) {\n const file = exists(rel);\n if (file) return file;\n }\n return null;\n }\n return resolveBackendExport(exportsField, conditions, exists);\n}\n\n/** `<pkgRoot>/<rel>` when it is a file inside the package, else null. */\nfunction packageFile(pkgRoot: string, rel: string): string | null {\n const file = path.resolve(pkgRoot, rel);\n // Never let an export target escape the package.\n if (!file.startsWith(path.resolve(pkgRoot) + path.sep)) return null;\n try {\n return fs.statSync(file).isFile() ? file : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The `./backend` subpath of an `exports` map, resolved per Node's\n * PACKAGE_EXPORTS_RESOLVE (see resolveBackendEntry). `probe` turns a matched\n * `./`-relative target into a file, or null when it does not resolve.\n */\nfunction resolveBackendExport(\n exportsField: any,\n conditions: readonly string[],\n probe: (rel: string) => string | null\n): string | null {\n // `\"exports\": \"./x.js\"`, an array, or a condition object at the top level\n // are all sugar for the \".\" subpath only.\n if (\n typeof exportsField !== 'object' ||\n Array.isArray(exportsField) ||\n !Object.keys(exportsField).some((k) => k.startsWith('.'))\n ) {\n return null;\n }\n\n const subpath = './backend';\n let target: any;\n let patternMatch: string | null = null;\n if (Object.prototype.hasOwnProperty.call(exportsField, subpath)) {\n target = exportsField[subpath];\n } else {\n let bestKey: string | null = null;\n for (const key of Object.keys(exportsField)) {\n const star = key.indexOf('*');\n if (star === -1 || key.indexOf('*', star + 1) !== -1) continue;\n const prefix = key.slice(0, star);\n const suffix = key.slice(star + 1);\n if (\n subpath !== prefix &&\n subpath.length >= key.length &&\n subpath.startsWith(prefix) &&\n subpath.endsWith(suffix) &&\n (bestKey === null || patternKeyCompare(bestKey, key) > 0)\n ) {\n bestKey = key;\n patternMatch = subpath.slice(prefix.length, subpath.length - suffix.length);\n }\n }\n if (bestKey === null) return null;\n target = exportsField[bestKey];\n }\n\n const resolveTarget = (t: any): string | null => {\n if (typeof t === 'string') {\n if (!t.startsWith('./')) return null;\n const rel = patternMatch === null ? t : t.split('*').join(patternMatch);\n return probe(rel);\n }\n if (Array.isArray(t)) {\n for (const item of t) {\n const file = resolveTarget(item);\n if (file) return file;\n }\n return null;\n }\n if (t && typeof t === 'object') {\n for (const key of Object.keys(t)) {\n if (key === 'default' || conditions.includes(key)) {\n // Node takes the first matching condition even if its target fails\n // to resolve; it does not fall through to later keys.\n return resolveTarget(t[key]);\n }\n }\n }\n return null;\n };\n return resolveTarget(target);\n}\n\n/**\n * The SOURCE file a dev Vite runner loads for `<pkg>/backend` when the\n * package is a source package — its real root has a `src/` directory, which is\n * what makes `linked`'s Vite config register it as a workspace (cli\n * `discoverWorkspaces` / `readSourcePackage`). Null when the package has no\n * `src/` or no source backend; the caller then falls back to\n * resolveBackendEntry (a built `lib/` copy, or nothing).\n *\n * Mirrors the cli's `resolveWorkspaceSpecifier` for the `./backend` subpath,\n * which runs BEFORE `exports`: `src/backend.tsx`, `src/backend.ts`, then the\n * package's own `exports` under `import`/`default` with a `./lib/esm/X.js`\n * target mapped to `src/X.tsx` / `src/X.ts` (any other `./lib/esm/` target to\n * the same path under src). So an unbuilt workspace, whose `exports` name only\n * `lib/esm`, still has its backend found, and a built one reports the src file\n * Vite actually evaluates rather than its stale `lib/`.\n *\n * Only meaningful when the dev Vite runner owns the package; Node (production,\n * external packages) loads `lib/` and never sees src.\n */\nexport function resolveSourceBackendEntry(\n pkgRoot: string,\n pkgJson: any\n): string | null {\n try {\n if (!fs.statSync(path.join(pkgRoot, 'src')).isDirectory()) return null;\n } catch {\n return null;\n }\n for (const rel of ['src/backend.tsx', 'src/backend.ts']) {\n const file = packageFile(pkgRoot, rel);\n if (file) return file;\n }\n const exportsField = pkgJson?.exports;\n if (exportsField === undefined || exportsField === null) return null;\n const libPrefix = './lib/esm/';\n return resolveBackendExport(exportsField, ['import'], (rel) => {\n if (!rel.startsWith(libPrefix)) return null;\n const sub = rel.slice(libPrefix.length);\n if (/\\.jsx?$/.test(sub)) {\n const base = 'src/' + sub.replace(/\\.jsx?$/, '');\n return packageFile(pkgRoot, base + '.tsx') ?? packageFile(pkgRoot, base + '.ts');\n }\n return packageFile(pkgRoot, 'src/' + sub);\n });\n}\n\n/** Node's PATTERN_KEY_COMPARE: < 0 means `a` is the more specific pattern. */\nfunction patternKeyCompare(a: string, b: string): number {\n const aBase = a.indexOf('*');\n const bBase = b.indexOf('*');\n const baseA = aBase === -1 ? a.length : aBase + 1;\n const baseB = bBase === -1 ? b.length : bBase + 1;\n if (baseA > baseB) return -1;\n if (baseB > baseA) return 1;\n if (aBase === -1) return 1;\n if (bBase === -1) return -1;\n if (a.length > b.length) return -1;\n if (b.length > a.length) return 1;\n return 0;\n}\n\n/**\n * Whether the dev SSR runner BUNDLES `pkgName` (it is in Vite's\n * `ssr.noExternal`) rather than handing it to Node.\n *\n * This decides which loader a package's backend must be loaded with. A module\n * has to be evaluated by the same loader that evaluates the package everywhere\n * else in the SSR graph, or it runs twice:\n *\n * - `vite.ssrLoadModule('<external pkg>/backend')` transforms that entry and\n * its relative imports even though the package is external, while the app's\n * bare imports of the same package are evaluated by Node — two copies of the\n * package's module state.\n * - a plain `import()` of a BUNDLED package goes to Node, while the app's\n * imports of it are evaluated by Vite — the same split the other way round.\n *\n * Vite matches `noExternal` entries against the bare package name, so a\n * subpath (`pkg/backend`) is covered by an entry for `pkg`.\n */\nexport function isBundledBySsr(pkgName: string, noExternal: unknown): boolean {\n if (noExternal === true) return true;\n const entries = Array.isArray(noExternal)\n ? noExternal\n : noExternal\n ? [noExternal]\n : [];\n return entries.some((entry) =>\n typeof entry === 'string'\n ? entry === pkgName\n : entry instanceof RegExp\n ? entry.test(pkgName)\n : false\n );\n}\n\n/** The dev SSR runner's resolved `noExternal`, wherever this Vite keeps it. */\nexport function ssrNoExternalOf(vite: any): unknown {\n return (\n vite?.config?.ssr?.noExternal ??\n vite?.config?.environments?.ssr?.resolve?.noExternal\n );\n}\n\n/**\n * The backend entry of a package the dev Vite runner owns (see isBundledBySsr):\n * its source backend when it is a source package (resolveSourceBackendEntry),\n * otherwise what `exports` names under the `development` condition and Node's\n * import conditions. A registry install has no src/, so it resolves exactly\n * as before.\n */\nexport function resolveDevBackendEntry(\n pkgRoot: string,\n pkgJson: any\n): string | null {\n return (\n resolveSourceBackendEntry(pkgRoot, pkgJson) ??\n resolveBackendEntry(pkgRoot, pkgJson, [\n 'development',\n ...NODE_IMPORT_CONDITIONS,\n ])\n );\n}\n"]}