@objectstack/cli 2.0.0 → 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.
@@ -1,24 +1,24 @@
1
1
 
2
- > @objectstack/cli@2.0.0 build /home/runner/work/spec/spec/packages/cli
2
+ > @objectstack/cli@2.0.2 build /home/runner/work/spec/spec/packages/cli
3
3
  > tsup
4
4
 
5
- CLI Building entry: src/bin.ts
5
+ CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.5.1
8
8
  CLI Using tsup config: /home/runner/work/spec/spec/packages/cli/tsup.config.ts
9
- CLI Building entry: src/index.ts
9
+ CLI Building entry: src/bin.ts
10
10
  CLI Using tsconfig: tsconfig.json
11
11
  CLI tsup v8.5.1
12
12
  CLI Using tsup config: /home/runner/work/spec/spec/packages/cli/tsup.config.ts
13
13
  CLI Target: es2022
14
- CLI Target: es2022
15
14
  ESM Build start
15
+ CLI Target: es2022
16
16
  CLI Cleaning output folder
17
17
  ESM Build start
18
- ESM dist/index.js 57.98 KB
19
- ESM ⚡️ Build success in 106ms
20
- ESM dist/bin.js 60.60 KB
21
- ESM ⚡️ Build success in 119ms
18
+ ESM dist/index.js 58.65 KB
19
+ ESM ⚡️ Build success in 169ms
20
+ ESM dist/bin.js 61.27 KB
21
+ ESM ⚡️ Build success in 152ms
22
22
  DTS Build start
23
- DTS ⚡️ Build success in 9596ms
23
+ DTS ⚡️ Build success in 7598ms
24
24
  DTS dist/index.d.ts 2.93 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
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
+
22
+ ## 2.0.1
23
+
24
+ ### Patch Changes
25
+
26
+ - Patch release for maintenance and stability improvements
27
+ - Updated dependencies
28
+ - @objectstack/spec@2.0.1
29
+ - @objectstack/core@2.0.1
30
+ - @objectstack/objectql@2.0.1
31
+ - @objectstack/runtime@2.0.1
32
+ - @objectstack/rest@2.0.1
33
+ - @objectstack/driver-memory@2.0.1
34
+ - @objectstack/plugin-hono-server@2.0.1
35
+
3
36
  ## 2.0.0
4
37
 
5
38
  ### 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
- try {
769
- const { createRequire: createRequire2 } = __require("module");
770
- const req = createRequire2(import.meta.url);
771
- const resolved = req.resolve("@objectstack/studio/package.json");
772
- return path6.dirname(resolved);
773
- } catch {
774
- return null;
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 cwd = process.cwd();
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 = createRequire(import.meta.url);
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
- try {
1322
- const { createRequire } = __require("module");
1323
- const req = createRequire(import.meta.url);
1324
- const resolved = req.resolve("@objectstack/studio/package.json");
1325
- return path7.dirname(resolved);
1326
- } catch {
1327
- return null;
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 cwd = process.cwd();
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.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.24.1",
25
- "@objectstack/core": "2.0.0",
26
- "@objectstack/driver-memory": "^2.0.0",
27
- "@objectstack/objectql": "^2.0.0",
28
- "@objectstack/plugin-hono-server": "2.0.0",
29
- "@objectstack/rest": "2.0.0",
30
- "@objectstack/runtime": "^2.0.0",
31
- "@objectstack/spec": "2.0.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.0"
34
+ "@objectstack/core": "2.0.2"
35
35
  },
36
36
  "devDependencies": {
37
- "@types/node": "^25.1.0",
37
+ "@types/node": "^25.2.2",
38
38
  "tsup": "^8.0.2",
39
39
  "typescript": "^5.3.3",
40
40
  "vitest": "^4.0.18"
@@ -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 Files (Simple implementation for now)
25
- // TODO: Use glob
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}`));
@@ -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
- try {
53
- const { createRequire } = require('module');
54
- const req = createRequire(import.meta.url);
55
- const resolved = req.resolve('@objectstack/studio/package.json');
56
- return path.dirname(resolved);
57
- } catch {
58
- return null;
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
  /**