@objectstack/cli 2.0.1 → 2.0.2
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/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +19 -0
- package/dist/bin.js +45 -27
- package/dist/index.js +43 -26
- package/package.json +11 -11
- package/src/commands/test.ts +47 -17
- package/src/utils/studio.ts +26 -8
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
|
|
2
|
-
> @objectstack/cli@2.0.
|
|
2
|
+
> @objectstack/cli@2.0.2 build /home/runner/work/spec/spec/packages/cli
|
|
3
3
|
> tsup
|
|
4
4
|
|
|
5
|
-
[34mCLI[39m Building entry: src/
|
|
5
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.5.1
|
|
8
8
|
[34mCLI[39m Using tsup config: /home/runner/work/spec/spec/packages/cli/tsup.config.ts
|
|
9
|
-
[34mCLI[39m Building entry: src/
|
|
9
|
+
[34mCLI[39m Building entry: src/bin.ts
|
|
10
10
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
11
11
|
[34mCLI[39m tsup v8.5.1
|
|
12
12
|
[34mCLI[39m Using tsup config: /home/runner/work/spec/spec/packages/cli/tsup.config.ts
|
|
13
13
|
[34mCLI[39m Target: es2022
|
|
14
|
-
[34mCLI[39m Target: es2022
|
|
15
14
|
[34mESM[39m Build start
|
|
15
|
+
[34mCLI[39m Target: es2022
|
|
16
16
|
[34mCLI[39m Cleaning output folder
|
|
17
17
|
[34mESM[39m Build start
|
|
18
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
19
|
-
[32mESM[39m ⚡️ Build success in
|
|
20
|
-
[32mESM[39m [1mdist/bin.js [22m[
|
|
21
|
-
[32mESM[39m ⚡️ Build success in
|
|
18
|
+
[32mESM[39m [1mdist/index.js [22m[32m58.65 KB[39m
|
|
19
|
+
[32mESM[39m ⚡️ Build success in 169ms
|
|
20
|
+
[32mESM[39m [1mdist/bin.js [22m[32m61.27 KB[39m
|
|
21
|
+
[32mESM[39m ⚡️ Build success in 152ms
|
|
22
22
|
[34mDTS[39m Build start
|
|
23
|
-
[32mDTS[39m ⚡️ Build success in
|
|
23
|
+
[32mDTS[39m ⚡️ Build success in 7598ms
|
|
24
24
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m2.93 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @objectstack/cli
|
|
2
2
|
|
|
3
|
+
## 2.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1db8559: chore: exclude generated json-schema from git tracking
|
|
8
|
+
|
|
9
|
+
- Add `packages/spec/json-schema/` to `.gitignore` (1277 generated files, 5MB)
|
|
10
|
+
- JSON schema files are still generated during `pnpm build` and included in npm publish via `files` field
|
|
11
|
+
- Fix studio module resolution logic for better compatibility
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [1db8559]
|
|
14
|
+
- @objectstack/spec@2.0.2
|
|
15
|
+
- @objectstack/core@2.0.2
|
|
16
|
+
- @objectstack/objectql@2.0.2
|
|
17
|
+
- @objectstack/driver-memory@2.0.2
|
|
18
|
+
- @objectstack/plugin-hono-server@2.0.2
|
|
19
|
+
- @objectstack/rest@2.0.2
|
|
20
|
+
- @objectstack/runtime@2.0.2
|
|
21
|
+
|
|
3
22
|
## 2.0.1
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/dist/bin.js
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
-
}) : x)(function(x) {
|
|
5
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
-
});
|
|
8
2
|
|
|
9
3
|
// src/bin.ts
|
|
10
|
-
import { createRequire } from "module";
|
|
4
|
+
import { createRequire as createRequire2 } from "module";
|
|
11
5
|
import { Command as Command12 } from "commander";
|
|
12
6
|
import chalk13 from "chalk";
|
|
13
7
|
|
|
@@ -747,6 +741,8 @@ import { bundleRequire as bundleRequire2 } from "bundle-require";
|
|
|
747
741
|
// src/utils/studio.ts
|
|
748
742
|
import path6 from "path";
|
|
749
743
|
import fs6 from "fs";
|
|
744
|
+
import { createRequire } from "module";
|
|
745
|
+
import { pathToFileURL } from "url";
|
|
750
746
|
var STUDIO_PATH = "/_studio";
|
|
751
747
|
function resolveStudioPath() {
|
|
752
748
|
const cwd = process.cwd();
|
|
@@ -765,14 +761,25 @@ function resolveStudioPath() {
|
|
|
765
761
|
}
|
|
766
762
|
}
|
|
767
763
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
764
|
+
const resolutionBases = [
|
|
765
|
+
pathToFileURL(path6.join(cwd, "package.json")).href,
|
|
766
|
+
// consumer workspace
|
|
767
|
+
import.meta.url
|
|
768
|
+
// CLI package itself
|
|
769
|
+
];
|
|
770
|
+
for (const base of resolutionBases) {
|
|
771
|
+
try {
|
|
772
|
+
const req = createRequire(base);
|
|
773
|
+
const resolved = req.resolve("@objectstack/studio/package.json");
|
|
774
|
+
return path6.dirname(resolved);
|
|
775
|
+
} catch {
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
const directPath = path6.join(cwd, "node_modules", "@objectstack", "studio");
|
|
779
|
+
if (fs6.existsSync(path6.join(directPath, "package.json"))) {
|
|
780
|
+
return directPath;
|
|
775
781
|
}
|
|
782
|
+
return null;
|
|
776
783
|
}
|
|
777
784
|
function hasStudioDist(studioPath) {
|
|
778
785
|
return fs6.existsSync(path6.join(studioPath, "dist", "index.html"));
|
|
@@ -1082,6 +1089,28 @@ import chalk8 from "chalk";
|
|
|
1082
1089
|
import path8 from "path";
|
|
1083
1090
|
import fs8 from "fs";
|
|
1084
1091
|
import { QA as CoreQA } from "@objectstack/core";
|
|
1092
|
+
function resolveGlob(pattern) {
|
|
1093
|
+
if (!pattern.includes("*")) {
|
|
1094
|
+
return fs8.existsSync(pattern) ? [pattern] : [];
|
|
1095
|
+
}
|
|
1096
|
+
const parts = pattern.split(path8.sep.replace("\\", "/"));
|
|
1097
|
+
const segments = pattern.includes("/") ? pattern.split("/") : parts;
|
|
1098
|
+
let baseDir = ".";
|
|
1099
|
+
let globStart = 0;
|
|
1100
|
+
for (let i = 0; i < segments.length; i++) {
|
|
1101
|
+
if (segments[i].includes("*")) {
|
|
1102
|
+
globStart = i;
|
|
1103
|
+
break;
|
|
1104
|
+
}
|
|
1105
|
+
baseDir = i === 0 ? segments[i] : path8.join(baseDir, segments[i]);
|
|
1106
|
+
}
|
|
1107
|
+
if (!fs8.existsSync(baseDir)) return [];
|
|
1108
|
+
const globPortion = segments.slice(globStart).join("/");
|
|
1109
|
+
const regexStr = globPortion.replace(/\./g, "\\.").replace(/\*\*\//g, "(.+/)?").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*");
|
|
1110
|
+
const regex = new RegExp(`^${regexStr}$`);
|
|
1111
|
+
const entries = fs8.readdirSync(baseDir, { recursive: true, encoding: "utf-8" });
|
|
1112
|
+
return entries.filter((entry) => regex.test(entry.replace(/\\/g, "/"))).map((entry) => path8.join(baseDir, entry)).filter((fullPath) => fs8.statSync(fullPath).isFile());
|
|
1113
|
+
}
|
|
1085
1114
|
var testCommand = new Command7("test").description("Run Quality Protocol test scenarios against a running server").argument("[files]", 'Glob pattern for test files (e.g. "qa/*.test.json")', "qa/*.test.json").option("--url <url>", "Target base URL", "http://localhost:3000").option("--token <token>", "Authentication token").action(async (filesPattern, options) => {
|
|
1086
1115
|
console.log(chalk8.bold(`
|
|
1087
1116
|
\u{1F9EA} ObjectStack Quality Protocol Runner`));
|
|
@@ -1089,18 +1118,7 @@ var testCommand = new Command7("test").description("Run Quality Protocol test sc
|
|
|
1089
1118
|
console.log(`Target: ${chalk8.blue(options.url)}`);
|
|
1090
1119
|
const adapter = new CoreQA.HttpTestAdapter(options.url, options.token);
|
|
1091
1120
|
const runner = new CoreQA.TestRunner(adapter);
|
|
1092
|
-
const
|
|
1093
|
-
const testFiles = [];
|
|
1094
|
-
if (fs8.existsSync(filesPattern)) {
|
|
1095
|
-
testFiles.push(filesPattern);
|
|
1096
|
-
} else {
|
|
1097
|
-
const dir = path8.dirname(filesPattern);
|
|
1098
|
-
const ext = path8.extname(filesPattern);
|
|
1099
|
-
if (fs8.existsSync(dir)) {
|
|
1100
|
-
const files = fs8.readdirSync(dir).filter((f) => f.endsWith(ext) || f.endsWith(".json"));
|
|
1101
|
-
files.forEach((f) => testFiles.push(path8.join(dir, f)));
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1121
|
+
const testFiles = resolveGlob(filesPattern);
|
|
1104
1122
|
if (testFiles.length === 0) {
|
|
1105
1123
|
console.warn(chalk8.yellow(`No test files found matching: ${filesPattern}`));
|
|
1106
1124
|
return;
|
|
@@ -1850,7 +1868,7 @@ var generateCommand = new Command11("generate").alias("g").description("Generate
|
|
|
1850
1868
|
});
|
|
1851
1869
|
|
|
1852
1870
|
// src/bin.ts
|
|
1853
|
-
var require2 =
|
|
1871
|
+
var require2 = createRequire2(import.meta.url);
|
|
1854
1872
|
var pkg = require2("../package.json");
|
|
1855
1873
|
process.on("unhandledRejection", (err) => {
|
|
1856
1874
|
console.error(chalk13.red(`
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
-
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
1
|
// src/commands/compile.ts
|
|
9
2
|
import { Command } from "commander";
|
|
10
3
|
import path2 from "path";
|
|
@@ -1300,6 +1293,8 @@ import { bundleRequire as bundleRequire2 } from "bundle-require";
|
|
|
1300
1293
|
// src/utils/studio.ts
|
|
1301
1294
|
import path7 from "path";
|
|
1302
1295
|
import fs7 from "fs";
|
|
1296
|
+
import { createRequire } from "module";
|
|
1297
|
+
import { pathToFileURL } from "url";
|
|
1303
1298
|
var STUDIO_PATH = "/_studio";
|
|
1304
1299
|
function resolveStudioPath() {
|
|
1305
1300
|
const cwd = process.cwd();
|
|
@@ -1318,14 +1313,25 @@ function resolveStudioPath() {
|
|
|
1318
1313
|
}
|
|
1319
1314
|
}
|
|
1320
1315
|
}
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1316
|
+
const resolutionBases = [
|
|
1317
|
+
pathToFileURL(path7.join(cwd, "package.json")).href,
|
|
1318
|
+
// consumer workspace
|
|
1319
|
+
import.meta.url
|
|
1320
|
+
// CLI package itself
|
|
1321
|
+
];
|
|
1322
|
+
for (const base of resolutionBases) {
|
|
1323
|
+
try {
|
|
1324
|
+
const req = createRequire(base);
|
|
1325
|
+
const resolved = req.resolve("@objectstack/studio/package.json");
|
|
1326
|
+
return path7.dirname(resolved);
|
|
1327
|
+
} catch {
|
|
1328
|
+
}
|
|
1328
1329
|
}
|
|
1330
|
+
const directPath = path7.join(cwd, "node_modules", "@objectstack", "studio");
|
|
1331
|
+
if (fs7.existsSync(path7.join(directPath, "package.json"))) {
|
|
1332
|
+
return directPath;
|
|
1333
|
+
}
|
|
1334
|
+
return null;
|
|
1329
1335
|
}
|
|
1330
1336
|
function hasStudioDist(studioPath) {
|
|
1331
1337
|
return fs7.existsSync(path7.join(studioPath, "dist", "index.html"));
|
|
@@ -1610,6 +1616,28 @@ import chalk11 from "chalk";
|
|
|
1610
1616
|
import path9 from "path";
|
|
1611
1617
|
import fs9 from "fs";
|
|
1612
1618
|
import { QA as CoreQA } from "@objectstack/core";
|
|
1619
|
+
function resolveGlob(pattern) {
|
|
1620
|
+
if (!pattern.includes("*")) {
|
|
1621
|
+
return fs9.existsSync(pattern) ? [pattern] : [];
|
|
1622
|
+
}
|
|
1623
|
+
const parts = pattern.split(path9.sep.replace("\\", "/"));
|
|
1624
|
+
const segments = pattern.includes("/") ? pattern.split("/") : parts;
|
|
1625
|
+
let baseDir = ".";
|
|
1626
|
+
let globStart = 0;
|
|
1627
|
+
for (let i = 0; i < segments.length; i++) {
|
|
1628
|
+
if (segments[i].includes("*")) {
|
|
1629
|
+
globStart = i;
|
|
1630
|
+
break;
|
|
1631
|
+
}
|
|
1632
|
+
baseDir = i === 0 ? segments[i] : path9.join(baseDir, segments[i]);
|
|
1633
|
+
}
|
|
1634
|
+
if (!fs9.existsSync(baseDir)) return [];
|
|
1635
|
+
const globPortion = segments.slice(globStart).join("/");
|
|
1636
|
+
const regexStr = globPortion.replace(/\./g, "\\.").replace(/\*\*\//g, "(.+/)?").replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*");
|
|
1637
|
+
const regex = new RegExp(`^${regexStr}$`);
|
|
1638
|
+
const entries = fs9.readdirSync(baseDir, { recursive: true, encoding: "utf-8" });
|
|
1639
|
+
return entries.filter((entry) => regex.test(entry.replace(/\\/g, "/"))).map((entry) => path9.join(baseDir, entry)).filter((fullPath) => fs9.statSync(fullPath).isFile());
|
|
1640
|
+
}
|
|
1613
1641
|
var testCommand = new Command9("test").description("Run Quality Protocol test scenarios against a running server").argument("[files]", 'Glob pattern for test files (e.g. "qa/*.test.json")', "qa/*.test.json").option("--url <url>", "Target base URL", "http://localhost:3000").option("--token <token>", "Authentication token").action(async (filesPattern, options) => {
|
|
1614
1642
|
console.log(chalk11.bold(`
|
|
1615
1643
|
\u{1F9EA} ObjectStack Quality Protocol Runner`));
|
|
@@ -1617,18 +1645,7 @@ var testCommand = new Command9("test").description("Run Quality Protocol test sc
|
|
|
1617
1645
|
console.log(`Target: ${chalk11.blue(options.url)}`);
|
|
1618
1646
|
const adapter = new CoreQA.HttpTestAdapter(options.url, options.token);
|
|
1619
1647
|
const runner = new CoreQA.TestRunner(adapter);
|
|
1620
|
-
const
|
|
1621
|
-
const testFiles = [];
|
|
1622
|
-
if (fs9.existsSync(filesPattern)) {
|
|
1623
|
-
testFiles.push(filesPattern);
|
|
1624
|
-
} else {
|
|
1625
|
-
const dir = path9.dirname(filesPattern);
|
|
1626
|
-
const ext = path9.extname(filesPattern);
|
|
1627
|
-
if (fs9.existsSync(dir)) {
|
|
1628
|
-
const files = fs9.readdirSync(dir).filter((f) => f.endsWith(ext) || f.endsWith(".json"));
|
|
1629
|
-
files.forEach((f) => testFiles.push(path9.join(dir, f)));
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1648
|
+
const testFiles = resolveGlob(filesPattern);
|
|
1632
1649
|
if (testFiles.length === 0) {
|
|
1633
1650
|
console.warn(chalk11.yellow(`No test files found matching: ${filesPattern}`));
|
|
1634
1651
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Command Line Interface for ObjectStack Protocol",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -21,20 +21,20 @@
|
|
|
21
21
|
"chalk": "^5.3.0",
|
|
22
22
|
"commander": "^14.0.3",
|
|
23
23
|
"tsx": "^4.7.1",
|
|
24
|
-
"zod": "^3.
|
|
25
|
-
"@objectstack/core": "2.0.
|
|
26
|
-
"@objectstack/driver-memory": "^2.0.
|
|
27
|
-
"@objectstack/objectql": "^2.0.
|
|
28
|
-
"@objectstack/plugin-hono-server": "2.0.
|
|
29
|
-
"@objectstack/rest": "2.0.
|
|
30
|
-
"@objectstack/runtime": "^2.0.
|
|
31
|
-
"@objectstack/spec": "2.0.
|
|
24
|
+
"zod": "^4.3.6",
|
|
25
|
+
"@objectstack/core": "2.0.2",
|
|
26
|
+
"@objectstack/driver-memory": "^2.0.2",
|
|
27
|
+
"@objectstack/objectql": "^2.0.2",
|
|
28
|
+
"@objectstack/plugin-hono-server": "2.0.2",
|
|
29
|
+
"@objectstack/rest": "2.0.2",
|
|
30
|
+
"@objectstack/runtime": "^2.0.2",
|
|
31
|
+
"@objectstack/spec": "2.0.2"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@objectstack/core": "2.0.
|
|
34
|
+
"@objectstack/core": "2.0.2"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@types/node": "^25.
|
|
37
|
+
"@types/node": "^25.2.2",
|
|
38
38
|
"tsup": "^8.0.2",
|
|
39
39
|
"typescript": "^5.3.3",
|
|
40
40
|
"vitest": "^4.0.18"
|
package/src/commands/test.ts
CHANGED
|
@@ -7,6 +7,51 @@ import fs from 'fs';
|
|
|
7
7
|
import { QA as CoreQA } from '@objectstack/core';
|
|
8
8
|
import { QA } from '@objectstack/spec';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a glob-like pattern to matching file paths.
|
|
12
|
+
* Supports `*` (single segment wildcard) and `**` (recursive wildcard).
|
|
13
|
+
* Falls back to direct file path if no glob characters are present.
|
|
14
|
+
*/
|
|
15
|
+
function resolveGlob(pattern: string): string[] {
|
|
16
|
+
// Direct file path — no wildcards
|
|
17
|
+
if (!pattern.includes('*')) {
|
|
18
|
+
return fs.existsSync(pattern) ? [pattern] : [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Split pattern into the static base directory and the glob portion
|
|
22
|
+
const parts = pattern.split(path.sep.replace('\\', '/'));
|
|
23
|
+
// Also handle forward-slash on Windows
|
|
24
|
+
const segments = pattern.includes('/') ? pattern.split('/') : parts;
|
|
25
|
+
|
|
26
|
+
let baseDir = '.';
|
|
27
|
+
let globStart = 0;
|
|
28
|
+
for (let i = 0; i < segments.length; i++) {
|
|
29
|
+
if (segments[i].includes('*')) {
|
|
30
|
+
globStart = i;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
baseDir = i === 0 ? segments[i] : path.join(baseDir, segments[i]);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!fs.existsSync(baseDir)) return [];
|
|
37
|
+
|
|
38
|
+
// Convert the glob portion into a RegExp
|
|
39
|
+
const globPortion = segments.slice(globStart).join('/');
|
|
40
|
+
const regexStr = globPortion
|
|
41
|
+
.replace(/\./g, '\\.') // escape dots
|
|
42
|
+
.replace(/\*\*\//g, '(.+/)?') // ** matches any directory depth
|
|
43
|
+
.replace(/\*\*/g, '.*') // trailing ** without slash
|
|
44
|
+
.replace(/\*/g, '[^/]*'); // * matches within a single segment
|
|
45
|
+
const regex = new RegExp(`^${regexStr}$`);
|
|
46
|
+
|
|
47
|
+
// Recursively read all files under baseDir
|
|
48
|
+
const entries = fs.readdirSync(baseDir, { recursive: true, encoding: 'utf-8' }) as string[];
|
|
49
|
+
return entries
|
|
50
|
+
.filter(entry => regex.test(entry.replace(/\\/g, '/')))
|
|
51
|
+
.map(entry => path.join(baseDir, entry))
|
|
52
|
+
.filter(fullPath => fs.statSync(fullPath).isFile());
|
|
53
|
+
}
|
|
54
|
+
|
|
10
55
|
export const testCommand = new Command('test')
|
|
11
56
|
.description('Run Quality Protocol test scenarios against a running server')
|
|
12
57
|
.argument('[files]', 'Glob pattern for test files (e.g. "qa/*.test.json")', 'qa/*.test.json')
|
|
@@ -21,23 +66,8 @@ export const testCommand = new Command('test')
|
|
|
21
66
|
const adapter = new CoreQA.HttpTestAdapter(options.url, options.token);
|
|
22
67
|
const runner = new CoreQA.TestRunner(adapter);
|
|
23
68
|
|
|
24
|
-
// 2. Find
|
|
25
|
-
|
|
26
|
-
const cwd = process.cwd();
|
|
27
|
-
const testFiles: string[] = [];
|
|
28
|
-
|
|
29
|
-
// Very basic file finding for demo - assume explicit path or check local dir
|
|
30
|
-
if (fs.existsSync(filesPattern)) {
|
|
31
|
-
testFiles.push(filesPattern);
|
|
32
|
-
} else {
|
|
33
|
-
// Simple directory scan
|
|
34
|
-
const dir = path.dirname(filesPattern);
|
|
35
|
-
const ext = path.extname(filesPattern);
|
|
36
|
-
if (fs.existsSync(dir)) {
|
|
37
|
-
const files = fs.readdirSync(dir).filter(f => f.endsWith(ext) || f.endsWith('.json'));
|
|
38
|
-
files.forEach(f => testFiles.push(path.join(dir, f)));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
69
|
+
// 2. Find test files using glob-style pattern matching
|
|
70
|
+
const testFiles: string[] = resolveGlob(filesPattern);
|
|
41
71
|
|
|
42
72
|
if (testFiles.length === 0) {
|
|
43
73
|
console.warn(chalk.yellow(`No test files found matching: ${filesPattern}`));
|
package/src/utils/studio.ts
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
import path from 'path';
|
|
10
10
|
import fs from 'fs';
|
|
11
11
|
import net from 'net';
|
|
12
|
+
import { createRequire } from 'module';
|
|
13
|
+
import { pathToFileURL } from 'url';
|
|
12
14
|
import { spawn, type ChildProcess } from 'child_process';
|
|
13
15
|
import chalk from 'chalk';
|
|
14
16
|
|
|
@@ -48,15 +50,31 @@ export function resolveStudioPath(): string | null {
|
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
// Fallback: resolve from node_modules
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
// Fallback: resolve from node_modules via createRequire.
|
|
54
|
+
// Try the consumer's cwd first (pnpm strict isolation means the CLI's own
|
|
55
|
+
// import.meta.url cannot see the consumer's dependencies), then the CLI itself.
|
|
56
|
+
const resolutionBases = [
|
|
57
|
+
pathToFileURL(path.join(cwd, 'package.json')).href, // consumer workspace
|
|
58
|
+
import.meta.url, // CLI package itself
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
for (const base of resolutionBases) {
|
|
62
|
+
try {
|
|
63
|
+
const req = createRequire(base);
|
|
64
|
+
const resolved = req.resolve('@objectstack/studio/package.json');
|
|
65
|
+
return path.dirname(resolved);
|
|
66
|
+
} catch {
|
|
67
|
+
// Not resolvable from this base — try next
|
|
68
|
+
}
|
|
59
69
|
}
|
|
70
|
+
|
|
71
|
+
// Last resort: direct filesystem check in cwd/node_modules
|
|
72
|
+
const directPath = path.join(cwd, 'node_modules', '@objectstack', 'studio');
|
|
73
|
+
if (fs.existsSync(path.join(directPath, 'package.json'))) {
|
|
74
|
+
return directPath;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return null;
|
|
60
78
|
}
|
|
61
79
|
|
|
62
80
|
/**
|