@treeseed/sdk 0.3.2 → 0.3.4
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/dist/scripts/test-smoke.js +2 -0
- package/dist/verification.d.ts +10 -0
- package/dist/verification.js +96 -13
- package/package.json +3 -1
|
@@ -124,6 +124,8 @@ try {
|
|
|
124
124
|
type: 'module',
|
|
125
125
|
scripts: {
|
|
126
126
|
'verify:direct': 'node --input-type=module -e "console.log(\'treeseed-sdk-smoke-verify\')"',
|
|
127
|
+
'verify:local': 'node --input-type=module -e "process.env.TREESEED_VERIFY_DRIVER=\'direct\'; console.log(\'treeseed-sdk-smoke-verify-local\')"',
|
|
128
|
+
'verify:action': 'node --input-type=module -e "process.env.TREESEED_VERIFY_DRIVER=\'act\'; console.log(\'treeseed-sdk-smoke-verify-action\')"',
|
|
127
129
|
},
|
|
128
130
|
}, null, 2)}\n`, 'utf8');
|
|
129
131
|
run(process.execPath, ['--input-type=module', '-e', 'await import("@treeseed/sdk/verification");'], installRoot);
|
package/dist/verification.d.ts
CHANGED
|
@@ -4,6 +4,11 @@ export type TreeseedVerifyDriverOptions = {
|
|
|
4
4
|
driver?: TreeseedVerifyDriver;
|
|
5
5
|
eventName?: string;
|
|
6
6
|
write?: (message: string, stream?: 'stdout' | 'stderr') => void;
|
|
7
|
+
runCommand?: (command: string, args: string[], cwd: string) => number;
|
|
8
|
+
checkCommand?: (command: string, args: string[], cwd: string) => {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
detail: string;
|
|
11
|
+
};
|
|
7
12
|
};
|
|
8
13
|
export type TreeseedVerifyDriverStatus = {
|
|
9
14
|
packageRoot: string;
|
|
@@ -15,6 +20,11 @@ export type TreeseedVerifyDriverStatus = {
|
|
|
15
20
|
ghActAvailable: boolean;
|
|
16
21
|
dockerAvailable: boolean;
|
|
17
22
|
canUseAct: boolean;
|
|
23
|
+
workspaceRoot: string | null;
|
|
24
|
+
currentPackageName: string | null;
|
|
25
|
+
localTreeseedPackageNames: string[];
|
|
26
|
+
localTreeseedSiblingDependencies: string[];
|
|
27
|
+
prefersDirectForLocalWorkspace: boolean;
|
|
18
28
|
};
|
|
19
29
|
export declare function getTreeseedVerifyDriverStatus(options?: TreeseedVerifyDriverOptions): TreeseedVerifyDriverStatus;
|
|
20
30
|
export declare function runTreeseedVerifyDriver(options?: TreeseedVerifyDriverOptions): number;
|
package/dist/verification.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import * as childProcess from "node:child_process";
|
|
3
3
|
import { basename, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
function defaultWrite(message, stream = "stdout") {
|
|
@@ -8,7 +8,7 @@ function defaultWrite(message, stream = "stdout") {
|
|
|
8
8
|
`);
|
|
9
9
|
}
|
|
10
10
|
function run(command, args, cwd) {
|
|
11
|
-
const result = spawnSync(command, args, {
|
|
11
|
+
const result = childProcess.spawnSync(command, args, {
|
|
12
12
|
cwd,
|
|
13
13
|
env: process.env,
|
|
14
14
|
stdio: "inherit"
|
|
@@ -16,7 +16,7 @@ function run(command, args, cwd) {
|
|
|
16
16
|
return result.status ?? 1;
|
|
17
17
|
}
|
|
18
18
|
function check(command, args, cwd) {
|
|
19
|
-
const result = spawnSync(command, args, {
|
|
19
|
+
const result = childProcess.spawnSync(command, args, {
|
|
20
20
|
cwd,
|
|
21
21
|
env: process.env,
|
|
22
22
|
stdio: "pipe",
|
|
@@ -28,6 +28,76 @@ function check(command, args, cwd) {
|
|
|
28
28
|
${result.stdout ?? ""}`.trim()
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
|
+
function readPackageManifest(packageJsonPath) {
|
|
32
|
+
if (!existsSync(packageJsonPath)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function findWorkspaceRoot(packageRoot) {
|
|
42
|
+
let current = packageRoot;
|
|
43
|
+
while (true) {
|
|
44
|
+
const packagesRoot = resolve(current, "packages");
|
|
45
|
+
if (existsSync(packagesRoot)) {
|
|
46
|
+
const packageDirs = readdirSync(packagesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => resolve(packagesRoot, entry.name)).filter((dirPath) => existsSync(resolve(dirPath, "package.json")));
|
|
47
|
+
if (packageDirs.length > 0) {
|
|
48
|
+
return {
|
|
49
|
+
workspaceRoot: current,
|
|
50
|
+
packageDirs
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const parent = resolve(current, "..");
|
|
55
|
+
if (parent === current) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
current = parent;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function resolveLocalWorkspaceContext(packageRoot) {
|
|
62
|
+
const currentManifest = readPackageManifest(resolve(packageRoot, "package.json"));
|
|
63
|
+
const currentPackageName = typeof currentManifest?.name === "string" ? currentManifest.name : null;
|
|
64
|
+
const workspace = findWorkspaceRoot(packageRoot);
|
|
65
|
+
if (!workspace) {
|
|
66
|
+
return {
|
|
67
|
+
workspaceRoot: null,
|
|
68
|
+
currentPackageName,
|
|
69
|
+
localTreeseedPackageNames: [],
|
|
70
|
+
localTreeseedSiblingDependencies: []
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const localPackages = workspace.packageDirs.map((dirPath) => ({
|
|
74
|
+
dirPath,
|
|
75
|
+
manifest: readPackageManifest(resolve(dirPath, "package.json"))
|
|
76
|
+
})).filter((entry) => Boolean(entry.manifest?.name));
|
|
77
|
+
const currentPackage = localPackages.find((entry) => entry.dirPath === packageRoot);
|
|
78
|
+
if (!currentPackage) {
|
|
79
|
+
return {
|
|
80
|
+
workspaceRoot: null,
|
|
81
|
+
currentPackageName,
|
|
82
|
+
localTreeseedPackageNames: [],
|
|
83
|
+
localTreeseedSiblingDependencies: []
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const localTreeseedPackageNames = localPackages.map((entry) => entry.manifest.name).filter((name) => name.startsWith("@treeseed/")).sort();
|
|
87
|
+
const localTreeseedPackageSet = new Set(localTreeseedPackageNames);
|
|
88
|
+
const declaredDependencies = {
|
|
89
|
+
...currentPackage.manifest.dependencies ?? {},
|
|
90
|
+
...currentPackage.manifest.devDependencies ?? {},
|
|
91
|
+
...currentPackage.manifest.peerDependencies ?? {}
|
|
92
|
+
};
|
|
93
|
+
const localTreeseedSiblingDependencies = Object.keys(declaredDependencies).filter((name) => name.startsWith("@treeseed/")).filter((name) => localTreeseedPackageSet.has(name)).sort();
|
|
94
|
+
return {
|
|
95
|
+
workspaceRoot: workspace.workspaceRoot,
|
|
96
|
+
currentPackageName: currentPackage.manifest.name ?? currentPackageName,
|
|
97
|
+
localTreeseedPackageNames,
|
|
98
|
+
localTreeseedSiblingDependencies
|
|
99
|
+
};
|
|
100
|
+
}
|
|
31
101
|
function getTreeseedVerifyDriverStatus(options = {}) {
|
|
32
102
|
const packageRoot = resolve(options.packageRoot ?? process.cwd());
|
|
33
103
|
const workflowPath = resolve(packageRoot, ".github", "workflows", "verify.yml");
|
|
@@ -35,8 +105,11 @@ function getTreeseedVerifyDriverStatus(options = {}) {
|
|
|
35
105
|
const eventName = options.eventName ?? process.env.TREESEED_VERIFY_EVENT ?? "workflow_dispatch";
|
|
36
106
|
const inGitHubActions = process.env.GITHUB_ACTIONS === "true";
|
|
37
107
|
const workflowPresent = existsSync(workflowPath);
|
|
38
|
-
const
|
|
39
|
-
const
|
|
108
|
+
const workspace = resolveLocalWorkspaceContext(packageRoot);
|
|
109
|
+
const checkCommand = options.checkCommand ?? check;
|
|
110
|
+
const ghAct = checkCommand("gh", ["act", "--version"], packageRoot);
|
|
111
|
+
const docker = checkCommand("docker", ["info"], packageRoot);
|
|
112
|
+
const prefersDirectForLocalWorkspace = !inGitHubActions && driver === "auto" && workspace.localTreeseedSiblingDependencies.length > 0;
|
|
40
113
|
return {
|
|
41
114
|
packageRoot,
|
|
42
115
|
workflowPath,
|
|
@@ -46,14 +119,21 @@ function getTreeseedVerifyDriverStatus(options = {}) {
|
|
|
46
119
|
workflowPresent,
|
|
47
120
|
ghActAvailable: ghAct.ok,
|
|
48
121
|
dockerAvailable: docker.ok,
|
|
49
|
-
canUseAct: workflowPresent && ghAct.ok && docker.ok
|
|
122
|
+
canUseAct: workflowPresent && ghAct.ok && docker.ok,
|
|
123
|
+
workspaceRoot: workspace.workspaceRoot,
|
|
124
|
+
currentPackageName: workspace.currentPackageName,
|
|
125
|
+
localTreeseedPackageNames: workspace.localTreeseedPackageNames,
|
|
126
|
+
localTreeseedSiblingDependencies: workspace.localTreeseedSiblingDependencies,
|
|
127
|
+
prefersDirectForLocalWorkspace
|
|
50
128
|
};
|
|
51
129
|
}
|
|
52
130
|
function runTreeseedVerifyDriver(options = {}) {
|
|
53
131
|
const write = options.write ?? defaultWrite;
|
|
54
132
|
const status = getTreeseedVerifyDriverStatus(options);
|
|
133
|
+
const runCommand = options.runCommand ?? run;
|
|
134
|
+
const checkCommand = options.checkCommand ?? check;
|
|
55
135
|
if (status.driver === "direct" || status.inGitHubActions) {
|
|
56
|
-
return
|
|
136
|
+
return runCommand("npm", ["run", "verify:direct"], status.packageRoot);
|
|
57
137
|
}
|
|
58
138
|
if (status.driver === "act") {
|
|
59
139
|
if (!status.workflowPresent) {
|
|
@@ -61,19 +141,22 @@ function runTreeseedVerifyDriver(options = {}) {
|
|
|
61
141
|
return 1;
|
|
62
142
|
}
|
|
63
143
|
if (!status.ghActAvailable) {
|
|
64
|
-
const detail =
|
|
144
|
+
const detail = checkCommand("gh", ["act", "--version"], status.packageRoot).detail;
|
|
65
145
|
write(detail || "Treeseed verify requires `gh act` when TREESEED_VERIFY_DRIVER=act.", "stderr");
|
|
66
146
|
return 1;
|
|
67
147
|
}
|
|
68
148
|
if (!status.dockerAvailable) {
|
|
69
|
-
const detail =
|
|
149
|
+
const detail = checkCommand("docker", ["info"], status.packageRoot).detail;
|
|
70
150
|
write(detail || "Treeseed verify requires a running Docker daemon when TREESEED_VERIFY_DRIVER=act.", "stderr");
|
|
71
151
|
return 1;
|
|
72
152
|
}
|
|
73
|
-
return
|
|
153
|
+
return runCommand("gh", ["act", status.eventName, "-W", ".github/workflows/verify.yml", "-j", "verify"], status.packageRoot);
|
|
154
|
+
}
|
|
155
|
+
if (status.prefersDirectForLocalWorkspace) {
|
|
156
|
+
return runCommand("npm", ["run", "verify:direct"], status.packageRoot);
|
|
74
157
|
}
|
|
75
158
|
if (status.canUseAct) {
|
|
76
|
-
return
|
|
159
|
+
return runCommand("gh", ["act", status.eventName, "-W", ".github/workflows/verify.yml", "-j", "verify"], status.packageRoot);
|
|
77
160
|
}
|
|
78
161
|
if (!status.workflowPresent) {
|
|
79
162
|
write("Treeseed verify warning: package-local verify workflow is missing; falling back to verify:direct.", "stderr");
|
|
@@ -82,7 +165,7 @@ function runTreeseedVerifyDriver(options = {}) {
|
|
|
82
165
|
} else if (!status.dockerAvailable) {
|
|
83
166
|
write("Treeseed verify warning: Docker is unavailable; falling back to verify:direct.", "stderr");
|
|
84
167
|
}
|
|
85
|
-
return
|
|
168
|
+
return runCommand("npm", ["run", "verify:direct"], status.packageRoot);
|
|
86
169
|
}
|
|
87
170
|
const invokedPath = process.argv[1] ? resolve(process.argv[1]) : "";
|
|
88
171
|
const invokedBasename = basename(invokedPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treeseed/sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
"fixtures:check": "node ./scripts/run-ts.mjs ./scripts/fixture-tools.ts check",
|
|
42
42
|
"lint": "npm run fixtures:check && npm run build:dist",
|
|
43
43
|
"verify:direct": "npm run release:verify",
|
|
44
|
+
"verify:local": "node --input-type=module -e \"process.env.TREESEED_VERIFY_DRIVER='direct'; await import('@treeseed/sdk/scripts/verify-driver')\"",
|
|
45
|
+
"verify:action": "node --input-type=module -e \"process.env.TREESEED_VERIFY_DRIVER='act'; await import('@treeseed/sdk/scripts/verify-driver')\"",
|
|
44
46
|
"verify": "node ./scripts/verify-driver.mjs",
|
|
45
47
|
"release:setup": "npm run setup:ci",
|
|
46
48
|
"release:check-tag": "node ./scripts/run-ts.mjs ./scripts/assert-release-tag-version.ts",
|