@jskit-ai/kernel 0.1.153 → 0.1.155

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.
@@ -62,18 +62,33 @@ function isPathInsideRoot(rootPath, candidatePath) {
62
62
  * local package's root, shared entry, or exported subpath and accidentally re-enter node_modules caching.
63
63
  */
64
64
  async function resolveLocalPackageSources({ appRoot }) {
65
- const installedPackages = await discoverInstalledPackages({ appRoot });
66
- return Object.freeze(
67
- installedPackages
68
- .filter((entry) => LOCAL_PACKAGE_SOURCE_TYPES.has(entry.sourceType))
69
- .map((entry) =>
70
- Object.freeze({
71
- packageId: entry.packageId,
72
- installedPackageRoot: entry.installedPackageRoot,
73
- sourcePackageRoot: entry.sourcePackageRoot
74
- })
75
- )
76
- );
65
+ const appPackageJson = await readJsonFile(path.resolve(appRoot, "package.json"), {});
66
+ const dependencySpecifiers = collectRootDependencySpecifiers(appPackageJson);
67
+ const localPackages = [];
68
+
69
+ for (const packageId of sortStrings([...dependencySpecifiers.keys()])) {
70
+ const specifier = dependencySpecifiers.get(packageId);
71
+ if (!specifier.startsWith("file:")) {
72
+ continue;
73
+ }
74
+ const sourcePackageRoot = path.resolve(appRoot, specifier.slice("file:".length));
75
+ const sourcePackageJson = await readJsonFile(
76
+ path.join(sourcePackageRoot, "package.json"),
77
+ null
78
+ );
79
+ if (!sourcePackageJson) {
80
+ continue;
81
+ }
82
+ localPackages.push(
83
+ Object.freeze({
84
+ packageId,
85
+ installedPackageRoot: path.resolve(appRoot, "node_modules", ...packageId.split("/")),
86
+ sourcePackageRoot
87
+ })
88
+ );
89
+ }
90
+
91
+ return Object.freeze(localPackages);
77
92
  }
78
93
 
79
94
  function splitSpecifierSuffix(source) {
@@ -86,6 +86,15 @@ test("resolveLocalPackageSources includes every file dependency regardless of sc
86
86
  "@example/local-utility": { packagePath: "packages/utility" },
87
87
  "@example/published": {}
88
88
  });
89
+ const utilityPackageJsonPath = path.join(
90
+ tempRoot,
91
+ "packages",
92
+ "utility",
93
+ "package.json"
94
+ );
95
+ const utilityPackageJson = JSON.parse(await readFile(utilityPackageJsonPath, "utf8"));
96
+ delete utilityPackageJson.jskit;
97
+ await writeJson(utilityPackageJsonPath, utilityPackageJson);
89
98
 
90
99
  const localPackages = await resolveLocalPackageSources({ appRoot: tempRoot });
91
100
  assert.deepEqual(localPackages.map((entry) => entry.packageId), [
@@ -140,9 +140,11 @@ async function resolvePackageRoots({
140
140
  parentPackageRoot
141
141
  });
142
142
  const fileDependencyRoot = resolveFileDependencyRoot(appRoot, directSpecifier);
143
- let sourcePackageRoot = fileDependencyRoot && (await fileExists(fileDependencyRoot))
144
- ? fileDependencyRoot
145
- : "";
143
+ let sourcePackageRoot =
144
+ fileDependencyRoot &&
145
+ (await fileExists(path.join(fileDependencyRoot, "package.json")))
146
+ ? fileDependencyRoot
147
+ : "";
146
148
 
147
149
  if (!sourcePackageRoot && (await fileExists(installedPackageRoot))) {
148
150
  try {
@@ -1,7 +1,11 @@
1
1
  import assert from "node:assert/strict";
2
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
2
5
  import test from "node:test";
3
6
  import {
4
7
  createPackageMetadata,
8
+ discoverInstalledPackages,
5
9
  JSKIT_PACKAGE_CONFIG_KEYS
6
10
  } from "./installedPackages.js";
7
11
 
@@ -49,3 +53,43 @@ test("createPackageMetadata accepts only the canonical package.json.jskit fields
49
53
  /unknown field: packageId/
50
54
  );
51
55
  });
56
+
57
+ test("discoverInstalledPackages resolves file tarballs from node_modules", async (context) => {
58
+ const appRoot = await mkdtemp(path.join(tmpdir(), "jskit-installed-package-tarball-"));
59
+ context.after(() => rm(appRoot, { recursive: true, force: true }));
60
+ const installedPackageRoot = path.join(
61
+ appRoot,
62
+ "node_modules",
63
+ "@jskit-ai",
64
+ "shell-web"
65
+ );
66
+
67
+ await mkdir(path.join(appRoot, "archives"), { recursive: true });
68
+ await mkdir(installedPackageRoot, { recursive: true });
69
+ await writeFile(
70
+ path.join(appRoot, "package.json"),
71
+ JSON.stringify({
72
+ dependencies: {
73
+ "@jskit-ai/shell-web": "file:archives/shell-web.tgz"
74
+ }
75
+ })
76
+ );
77
+ await writeFile(path.join(appRoot, "archives", "shell-web.tgz"), "fixture");
78
+ await writeFile(
79
+ path.join(installedPackageRoot, "package.json"),
80
+ JSON.stringify({
81
+ name: "@jskit-ai/shell-web",
82
+ version: "0.1.0",
83
+ jskit: {
84
+ kind: "runtime"
85
+ }
86
+ })
87
+ );
88
+
89
+ const packages = await discoverInstalledPackages({ appRoot });
90
+
91
+ assert.equal(packages.length, 1);
92
+ assert.equal(packages[0].packageId, "@jskit-ai/shell-web");
93
+ assert.equal(packages[0].packageRoot, installedPackageRoot);
94
+ assert.equal(packages[0].sourceType, "npm-package");
95
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/kernel",
3
- "version": "0.1.153",
3
+ "version": "0.1.155",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "json-rest-schema": "^1.0.17"