@shortlink-org/portolan 0.2.0 → 0.2.1

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@shortlink-org/portolan",
3
3
  "description": "Generate a navigable architecture catalog from code and specifications.",
4
4
  "private": false,
5
- "version": "0.2.0",
5
+ "version": "0.2.1",
6
6
  "type": "module",
7
7
  "license": "MIT",
8
8
  "homepage": "https://github.com/shortlink-org/portolan#readme",
Binary file
@@ -18,7 +18,6 @@ import { tmpdir } from "node:os";
18
18
  import { createServer as createNetServer } from "node:net";
19
19
  import { basename, dirname, join, posix, relative, resolve, sep } from "node:path";
20
20
 
21
- import { publicSetupFrom } from "../src/lib/setup-info.ts";
22
21
  import { loadManifest } from "./manifest.mjs";
23
22
  import { builtinPluginNames } from "./builtin-plugins.mjs";
24
23
  import { installDeliveryPreset, planDeliveryPreset, publicDeliveryPreset } from "./delivery-presets.mjs";
@@ -726,7 +725,7 @@ export function writeProject(workspace, request) {
726
725
  return plan;
727
726
  }
728
727
 
729
- function setup(workspace) {
728
+ function setup(workspace, publicSetupFrom) {
730
729
  const manifestText = readFileSync(join(workspace, "portolan.json"), "utf8");
731
730
  let report;
732
731
  try { report = JSON.parse(readFileSync(join(workspace, ".portolan/build-report.json"), "utf8")); } catch {}
@@ -1095,7 +1094,7 @@ function startProjectTrial(workspace, request) {
1095
1094
  catch (cause) { rmSync(prepared.holder, { recursive: true, force: true }); throw cause; }
1096
1095
  }
1097
1096
 
1098
- export function localApiPlugin(workspace = process.cwd()) {
1097
+ export function localApiPlugin(workspace = process.cwd(), publicSetupFrom) {
1099
1098
  return {
1100
1099
  name: "portolan-local-api",
1101
1100
  apply: "serve",
@@ -1108,7 +1107,7 @@ export function localApiPlugin(workspace = process.cwd()) {
1108
1107
  try {
1109
1108
  if (req.method === "GET" && url.pathname === `${LOCAL_API_PREFIX}/status`) {
1110
1109
  const active = [...jobs.values()].find((job) => job.status === "running");
1111
- return send(res, 200, { local: true, workspace: realpathSync(workspace), setup: setup(workspace), activeRun: active ? { id: active.id, mode: active.mode } : null });
1110
+ return send(res, 200, { local: true, workspace: realpathSync(workspace), setup: setup(workspace, publicSetupFrom), activeRun: active ? { id: active.id, mode: active.mode } : null });
1112
1111
  }
1113
1112
  if (req.method === "GET" && url.pathname === `${LOCAL_API_PREFIX}/delivery-presets`) {
1114
1113
  return send(res, 200, publicDeliveryPreset(planDeliveryPreset(workspace, url.searchParams.get("provider"))));
@@ -1151,7 +1150,7 @@ export function localApiPlugin(workspace = process.cwd()) {
1151
1150
  const result = writeProject(workspace, trial.projectRequest);
1152
1151
  trial.applied = true;
1153
1152
  const generation = input.generate ? startJob(workspace, "write", trial) : null;
1154
- return send(res, 201, { ...result, setup: setup(workspace), run: generation ? { runId: generation.id, mode: generation.mode } : null });
1153
+ return send(res, 201, { ...result, setup: setup(workspace, publicSetupFrom), run: generation ? { runId: generation.id, mode: generation.mode } : null });
1155
1154
  }
1156
1155
  const disposeTrialMatch = url.pathname.match(/^\/__portolan\/projects\/trials\/([^/]+)\/dispose$/);
1157
1156
  if (disposeTrialMatch) {
@@ -1167,7 +1166,7 @@ export function localApiPlugin(workspace = process.cwd()) {
1167
1166
  }
1168
1167
  if (url.pathname === `${LOCAL_API_PREFIX}/projects`) {
1169
1168
  const result = writeProject(workspace, input);
1170
- return send(res, 201, { ...result, setup: setup(workspace) });
1169
+ return send(res, 201, { ...result, setup: setup(workspace, publicSetupFrom) });
1171
1170
  }
1172
1171
  if (url.pathname === `${LOCAL_API_PREFIX}/runs`) {
1173
1172
  if ([...jobs.values()].some((job) => job.status === "running")) return send(res, 409, { error: "A generator run is already active." });
@@ -8,6 +8,7 @@ import { rmSync } from "node:fs";
8
8
  import { classifyRepositoryFailure, diffGeneratedFiles, discoverProject, forgetRepositoryCredential, inspectionRoot, localApiPath, planProject, readLocalSource, resolveRepositoryCommit, storeRepositoryCredential, summarizeProjectTrial, writeProject } from "./local-api.mjs";
9
9
  import { installDeliveryPreset, planDeliveryPreset, providerFromRemote, publicDeliveryPreset } from "./delivery-presets.mjs";
10
10
 
11
+ const PACKAGE_VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
11
12
  const roots = [];
12
13
  afterEach(() => { for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true }); });
13
14
 
@@ -66,7 +67,7 @@ describe("local project setup", () => {
66
67
  const installed = installDeliveryPreset(root, { provider: "github", revision: preview.revision });
67
68
  expect(installed.written).toHaveLength(2);
68
69
  expect(installed.status).toBe("installed");
69
- expect(readFileSync(join(root, ".github/workflows/portolan-check.yml"), "utf8")).toContain("shortlink-org/portolan@0.2.0");
70
+ expect(readFileSync(join(root, ".github/workflows/portolan-check.yml"), "utf8")).toContain(`shortlink-org/portolan@${PACKAGE_VERSION}`);
70
71
  expect(readFileSync(join(root, ".github/workflows/portolan-pages.yml"), "utf8")).toContain("base: /${{ github.event.repository.name }}/");
71
72
  expect(installDeliveryPreset(root, { provider: "github", revision: installed.revision }).written).toEqual([]);
72
73
  });
@@ -2,16 +2,32 @@
2
2
  // This catches accidental cwd coupling before the same package reaches npm.
3
3
 
4
4
  import { execFileSync } from "node:child_process";
5
- import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
5
+ import { existsSync, mkdirSync, mkdtempSync, renameSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
6
6
  import { tmpdir } from "node:os";
7
7
  import { resolve } from "node:path";
8
8
  import { fileURLToPath } from "node:url";
9
9
 
10
10
  const root = resolve(fileURLToPath(new URL("..", import.meta.url)));
11
- const cli = resolve(root, "cli/portolan.mjs");
12
11
  const fixture = mkdtempSync(resolve(tmpdir(), "portolan-package-smoke-"));
12
+ const install = mkdtempSync(resolve(tmpdir(), "portolan-package-install-"));
13
13
 
14
14
  try {
15
+ // Exercise the tarball from a real node_modules path. Node permits native
16
+ // TypeScript stripping in a checkout but rejects it below node_modules, so
17
+ // invoking the source-tree CLI did not catch broken published entry graphs.
18
+ const tarball = execFileSync("npm", ["pack", "--ignore-scripts", "--pack-destination", install], {
19
+ cwd: root,
20
+ encoding: "utf8",
21
+ stdio: ["ignore", "pipe", "inherit"],
22
+ }).trim().split("\n").at(-1);
23
+ const scope = resolve(install, "node_modules/@shortlink-org");
24
+ mkdirSync(scope, { recursive: true });
25
+ execFileSync("tar", ["-xzf", resolve(install, tarball), "-C", scope]);
26
+ const installed = resolve(scope, "portolan");
27
+ renameSync(resolve(scope, "package"), installed);
28
+ symlinkSync(resolve(root, "node_modules"), resolve(installed, "node_modules"), process.platform === "win32" ? "junction" : "dir");
29
+ const cli = resolve(installed, "cli/portolan.mjs");
30
+
15
31
  writeFileSync(resolve(fixture, "package.json"), '{"name":"package-smoke","version":"1.0.0"}\n');
16
32
  writeFileSync(resolve(fixture, "README.md"), "# Package smoke\n");
17
33
  // A Go domain layout: init should notice it and wire the extractor without being asked.
@@ -34,6 +50,7 @@ try {
34
50
  console.log("package smoke: init, generate, check, and build passed outside the repository");
35
51
  } finally {
36
52
  rmSync(fixture, { recursive: true, force: true });
53
+ rmSync(install, { recursive: true, force: true });
37
54
  }
38
55
 
39
56
  function run(command, args) {
package/vite.config.ts CHANGED
@@ -152,7 +152,11 @@ export default defineConfig({
152
152
  __PROJECT_PREVIEW__: JSON.stringify(env.PORTOLAN_PROJECT_PREVIEW === "1"),
153
153
  },
154
154
  plugins: [
155
- localApiPlugin(workspace),
155
+ // Inject the TypeScript projection from the staged Vite config rather than
156
+ // importing it from local-api.mjs. The latter is also loaded directly by
157
+ // `portolan init` from the published package, and Node does not strip
158
+ // TypeScript below node_modules.
159
+ localApiPlugin(workspace, publicSetupFrom),
156
160
  siteDocsPlugin(workspace),
157
161
  react(),
158
162
  tailwindcss(),