@objectstack/cli 10.0.0 → 10.2.0
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/commands/compile.js +2 -2
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/lint.js +1 -1
- package/dist/commands/lint.js.map +1 -1
- package/dist/commands/migrate/apply.d.ts +19 -0
- package/dist/commands/migrate/apply.d.ts.map +1 -0
- package/dist/commands/migrate/apply.js +155 -0
- package/dist/commands/migrate/apply.js.map +1 -0
- package/dist/commands/migrate/index.d.ts +9 -0
- package/dist/commands/migrate/index.d.ts.map +1 -0
- package/dist/commands/migrate/index.js +10 -0
- package/dist/commands/migrate/index.js.map +1 -0
- package/dist/commands/migrate/plan.d.ts +16 -0
- package/dist/commands/migrate/plan.d.ts.map +1 -0
- package/dist/commands/migrate/plan.js +93 -0
- package/dist/commands/migrate/plan.js.map +1 -0
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +6 -0
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +37 -3
- package/dist/commands/validate.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/schema-migrate.d.ts +26 -0
- package/dist/utils/schema-migrate.d.ts.map +1 -0
- package/dist/utils/schema-migrate.integration.test.d.ts +2 -0
- package/dist/utils/schema-migrate.integration.test.d.ts.map +1 -0
- package/dist/utils/schema-migrate.integration.test.js +83 -0
- package/dist/utils/schema-migrate.integration.test.js.map +1 -0
- package/dist/utils/schema-migrate.js +123 -0
- package/dist/utils/schema-migrate.js.map +1 -0
- package/package.json +48 -47
- package/dist/utils/validate-expressions.d.ts +0 -19
- package/dist/utils/validate-expressions.d.ts.map +0 -1
- package/dist/utils/validate-expressions.js +0 -201
- package/dist/utils/validate-expressions.js.map +0 -1
- package/dist/utils/validate-expressions.test.d.ts +0 -2
- package/dist/utils/validate-expressions.test.d.ts.map +0 -1
- package/dist/utils/validate-expressions.test.js +0 -320
- package/dist/utils/validate-expressions.test.js.map +0 -1
- package/dist/utils/validate-widget-bindings.d.ts +0 -74
- package/dist/utils/validate-widget-bindings.d.ts.map +0 -1
- package/dist/utils/validate-widget-bindings.js +0 -304
- package/dist/utils/validate-widget-bindings.js.map +0 -1
- package/dist/utils/validate-widget-bindings.test.d.ts +0 -2
- package/dist/utils/validate-widget-bindings.test.d.ts.map +0 -1
- package/dist/utils/validate-widget-bindings.test.js +0 -285
- package/dist/utils/validate-widget-bindings.test.js.map +0 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ManagedDriftEntry, DriftCategory } from '@objectstack/driver-sql';
|
|
2
|
+
export interface SqlDriverLike {
|
|
3
|
+
detectManagedDrift(): Promise<ManagedDriftEntry[]>;
|
|
4
|
+
applyMigrationEntries(entries: ManagedDriftEntry[], opts: {
|
|
5
|
+
allowDestructive?: boolean;
|
|
6
|
+
}): Promise<{
|
|
7
|
+
applied: ManagedDriftEntry[];
|
|
8
|
+
skipped: ManagedDriftEntry[];
|
|
9
|
+
}>;
|
|
10
|
+
config?: any;
|
|
11
|
+
disconnect?: () => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export interface SchemaStack {
|
|
14
|
+
driver: SqlDriverLike | null;
|
|
15
|
+
dbLabel: string;
|
|
16
|
+
managedTableCount: number;
|
|
17
|
+
shutdown: () => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/** Boot the schema stack. Caller MUST call `shutdown()` when done. */
|
|
20
|
+
export declare function bootSchemaStack(opts?: {
|
|
21
|
+
databaseUrl?: string;
|
|
22
|
+
}): Promise<SchemaStack>;
|
|
23
|
+
export declare function groupByCategory(drift: ManagedDriftEntry[]): Record<DriftCategory, ManagedDriftEntry[]>;
|
|
24
|
+
export declare function renderPlan(drift: ManagedDriftEntry[]): void;
|
|
25
|
+
export declare function summarize(drift: ManagedDriftEntry[]): string;
|
|
26
|
+
//# sourceMappingURL=schema-migrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-migrate.d.ts","sourceRoot":"","sources":["../../src/utils/schema-migrate.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAEhF,MAAM,WAAW,aAAa;IAC5B,kBAAkB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACnD,qBAAqB,CACnB,OAAO,EAAE,iBAAiB,EAAE,EAC5B,IAAI,EAAE;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC;QAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;QAAC,OAAO,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAC,CAAC;IAC3E,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAyCD,sEAAsE;AACtE,wBAAsB,eAAe,CAAC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CA4B/F;AAYD,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,iBAAiB,EAAE,CAAC,CAItG;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAa3D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAG5D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-migrate.integration.test.d.ts","sourceRoot":"","sources":["../../src/utils/schema-migrate.integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
3
|
+
import { mkdtempSync, writeFileSync, mkdirSync, rmSync } from 'node:fs';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { SqlDriver } from '@objectstack/driver-sql';
|
|
7
|
+
import { bootSchemaStack } from './schema-migrate.js';
|
|
8
|
+
/**
|
|
9
|
+
* End-to-end (#2186): boot the real standalone stack via `bootSchemaStack`
|
|
10
|
+
* against a pre-seeded "legacy" SQLite DB (organization_id created NOT NULL),
|
|
11
|
+
* then verify `os migrate`'s engine detects the drift and reconciles it —
|
|
12
|
+
* exercising the full createStandaloneStack → AppPlugin → ObjectQL → driver path.
|
|
13
|
+
*/
|
|
14
|
+
describe('bootSchemaStack + migrate engine (integration)', () => {
|
|
15
|
+
let dir;
|
|
16
|
+
let dbFile;
|
|
17
|
+
const savedEnv = {};
|
|
18
|
+
beforeAll(async () => {
|
|
19
|
+
dir = mkdtempSync(join(tmpdir(), 'os-mig-'));
|
|
20
|
+
mkdirSync(join(dir, 'dist'), { recursive: true });
|
|
21
|
+
mkdirSync(join(dir, 'data'), { recursive: true });
|
|
22
|
+
dbFile = join(dir, 'data', 'app.db');
|
|
23
|
+
// Compiled-artifact stand-in: id at top level so AppPlugin registers it.
|
|
24
|
+
writeFileSync(join(dir, 'dist', 'objectstack.json'), JSON.stringify({
|
|
25
|
+
id: 'mig_smoke',
|
|
26
|
+
name: 'Migrate Smoke',
|
|
27
|
+
objects: [
|
|
28
|
+
{
|
|
29
|
+
name: 'mig_biz_unit',
|
|
30
|
+
fields: {
|
|
31
|
+
name: { type: 'text', required: true },
|
|
32
|
+
organization_id: { type: 'text', required: false }, // optional now
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
}));
|
|
37
|
+
// Seed a "legacy" DB where organization_id is NOT NULL (the #2178 shape).
|
|
38
|
+
const seed = new SqlDriver({ client: 'better-sqlite3', connection: { filename: dbFile }, useNullAsDefault: true });
|
|
39
|
+
const k = seed.knex;
|
|
40
|
+
await k.schema.createTable('mig_biz_unit', (t) => {
|
|
41
|
+
t.string('id').primary();
|
|
42
|
+
t.timestamp('created_at');
|
|
43
|
+
t.timestamp('updated_at');
|
|
44
|
+
t.string('name').notNullable();
|
|
45
|
+
t.string('organization_id').notNullable();
|
|
46
|
+
});
|
|
47
|
+
await k('mig_biz_unit').insert({ id: '1', name: 'Acme', organization_id: 'org1' });
|
|
48
|
+
await k.destroy();
|
|
49
|
+
savedEnv.OS_ARTIFACT_PATH = process.env.OS_ARTIFACT_PATH;
|
|
50
|
+
savedEnv.NODE_ENV = process.env.NODE_ENV;
|
|
51
|
+
process.env.OS_ARTIFACT_PATH = join(dir, 'dist', 'objectstack.json');
|
|
52
|
+
process.env.NODE_ENV = 'production'; // ensure no auto-reconcile masks the drift
|
|
53
|
+
});
|
|
54
|
+
afterAll(() => {
|
|
55
|
+
process.env.OS_ARTIFACT_PATH = savedEnv.OS_ARTIFACT_PATH;
|
|
56
|
+
process.env.NODE_ENV = savedEnv.NODE_ENV;
|
|
57
|
+
try {
|
|
58
|
+
rmSync(dir, { recursive: true, force: true });
|
|
59
|
+
}
|
|
60
|
+
catch { /* ignore */ }
|
|
61
|
+
});
|
|
62
|
+
it('detects the NOT NULL drift, applies it, and self-verifies in-sync', async () => {
|
|
63
|
+
const stack = await bootSchemaStack({ databaseUrl: `file:${dbFile}` });
|
|
64
|
+
try {
|
|
65
|
+
expect(stack.driver).toBeTruthy();
|
|
66
|
+
expect(stack.managedTableCount).toBeGreaterThan(0);
|
|
67
|
+
const drift = await stack.driver.detectManagedDrift();
|
|
68
|
+
const org = drift.find((d) => d.table === 'mig_biz_unit' && d.column === 'organization_id');
|
|
69
|
+
expect(org, 'expected drift on mig_biz_unit.organization_id').toBeDefined();
|
|
70
|
+
expect(org.category).toBe('safe');
|
|
71
|
+
expect(org.op.type).toBe('relax_not_null');
|
|
72
|
+
const { applied, skipped } = await stack.driver.applyMigrationEntries(drift, { allowDestructive: false });
|
|
73
|
+
expect(applied.some((d) => d.op.type === 'relax_not_null')).toBe(true);
|
|
74
|
+
expect(skipped).toHaveLength(0);
|
|
75
|
+
const after = await stack.driver.detectManagedDrift();
|
|
76
|
+
expect(after.find((d) => d.table === 'mig_biz_unit' && d.column === 'organization_id')).toBeUndefined();
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
await stack.shutdown();
|
|
80
|
+
}
|
|
81
|
+
}, 30_000);
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=schema-migrate.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-migrate.integration.test.js","sourceRoot":"","sources":["../../src/utils/schema-migrate.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
/**
|
|
3
|
+
* Shared boot + rendering for `os migrate` (issue #2186).
|
|
4
|
+
*
|
|
5
|
+
* Boots the data stack (driver + ObjectQL + the compiled artifact's objects)
|
|
6
|
+
* via the supported `createStandaloneStack` programmatic entry, runs schema
|
|
7
|
+
* sync, and hands back the live SQL driver so the command can call
|
|
8
|
+
* `detectManagedDrift()` / `applyMigrationEntries()`.
|
|
9
|
+
*
|
|
10
|
+
* Migration only sees the objects present in the loaded metadata (compiled
|
|
11
|
+
* artifact). Run `os build` first so your objects are visible; tables/columns
|
|
12
|
+
* not in the loaded metadata are never examined or altered.
|
|
13
|
+
*/
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
const SQL_DRIVER_SERVICES = [
|
|
16
|
+
'driver.com.objectstack.driver.sql',
|
|
17
|
+
'driver.com.objectstack.driver.turso',
|
|
18
|
+
'driver.sql',
|
|
19
|
+
];
|
|
20
|
+
function findSqlDriver(kernel) {
|
|
21
|
+
for (const name of SQL_DRIVER_SERVICES) {
|
|
22
|
+
let d;
|
|
23
|
+
try {
|
|
24
|
+
d = kernel?.getService?.(name);
|
|
25
|
+
}
|
|
26
|
+
catch { /* not registered */ }
|
|
27
|
+
if (d && typeof d.detectManagedDrift === 'function' && typeof d.applyMigrationEntries === 'function') {
|
|
28
|
+
return d;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
function describeDb(driver) {
|
|
34
|
+
const cfg = driver?.config;
|
|
35
|
+
if (!cfg)
|
|
36
|
+
return 'unknown';
|
|
37
|
+
const conn = cfg.connection;
|
|
38
|
+
if (typeof conn === 'string')
|
|
39
|
+
return redactUrl(conn);
|
|
40
|
+
if (conn && typeof conn === 'object') {
|
|
41
|
+
if (conn.filename)
|
|
42
|
+
return `sqlite:${conn.filename}`;
|
|
43
|
+
if (conn.host)
|
|
44
|
+
return `${cfg.client}://${conn.host}${conn.database ? '/' + conn.database : ''}`;
|
|
45
|
+
}
|
|
46
|
+
return String(cfg.client ?? 'unknown');
|
|
47
|
+
}
|
|
48
|
+
function redactUrl(url) {
|
|
49
|
+
try {
|
|
50
|
+
const u = new URL(url);
|
|
51
|
+
if (u.password)
|
|
52
|
+
u.password = '***';
|
|
53
|
+
return u.toString();
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return url.replace(/:\/\/[^@]*@/, '://***@');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** Boot the schema stack. Caller MUST call `shutdown()` when done. */
|
|
60
|
+
export async function bootSchemaStack(opts = {}) {
|
|
61
|
+
const { createStandaloneStack, Runtime } = await import('@objectstack/runtime');
|
|
62
|
+
const stack = await createStandaloneStack({
|
|
63
|
+
projectRoot: process.cwd(),
|
|
64
|
+
...(opts.databaseUrl ? { databaseUrl: opts.databaseUrl } : {}),
|
|
65
|
+
});
|
|
66
|
+
// No HTTP, no cluster — this is a one-shot schema operation.
|
|
67
|
+
const runtime = new Runtime({ cluster: false });
|
|
68
|
+
const kernel = runtime.getKernel();
|
|
69
|
+
for (const plugin of stack.plugins) {
|
|
70
|
+
await kernel.use(plugin);
|
|
71
|
+
}
|
|
72
|
+
await runtime.start();
|
|
73
|
+
const driver = findSqlDriver(kernel);
|
|
74
|
+
const managedTableCount = driver ? driver.managedObjectFields?.size ?? 0 : 0;
|
|
75
|
+
return {
|
|
76
|
+
driver,
|
|
77
|
+
dbLabel: describeDb(driver),
|
|
78
|
+
managedTableCount,
|
|
79
|
+
shutdown: async () => {
|
|
80
|
+
try {
|
|
81
|
+
await runtime.stop?.();
|
|
82
|
+
}
|
|
83
|
+
catch { /* ignore */ }
|
|
84
|
+
try {
|
|
85
|
+
await driver?.disconnect?.();
|
|
86
|
+
}
|
|
87
|
+
catch { /* ignore */ }
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
// ── Rendering ───────────────────────────────────────────────────────
|
|
92
|
+
const CATEGORY_ORDER = ['safe', 'needs_confirm', 'destructive'];
|
|
93
|
+
const CATEGORY_META = {
|
|
94
|
+
safe: { label: 'Safe (loosening — applied without --allow-destructive)', color: chalk.green, icon: '✓' },
|
|
95
|
+
needs_confirm: { label: 'Needs confirmation', color: chalk.yellow, icon: '~' },
|
|
96
|
+
destructive: { label: 'Destructive (requires --allow-destructive)', color: chalk.red, icon: '✗' },
|
|
97
|
+
};
|
|
98
|
+
export function groupByCategory(drift) {
|
|
99
|
+
const out = { safe: [], needs_confirm: [], destructive: [] };
|
|
100
|
+
for (const d of drift)
|
|
101
|
+
out[d.category].push(d);
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
export function renderPlan(drift) {
|
|
105
|
+
const grouped = groupByCategory(drift);
|
|
106
|
+
for (const cat of CATEGORY_ORDER) {
|
|
107
|
+
const items = grouped[cat];
|
|
108
|
+
if (items.length === 0)
|
|
109
|
+
continue;
|
|
110
|
+
const meta = CATEGORY_META[cat];
|
|
111
|
+
console.log(` ${chalk.bold(meta.label)}`);
|
|
112
|
+
for (const d of items) {
|
|
113
|
+
console.log(` ${meta.color(meta.icon)} ${meta.color(`${d.table}.${d.column ?? ''}`)} ${chalk.dim(`[${d.op.type}]`)}`);
|
|
114
|
+
console.log(` ${chalk.dim(d.message)}`);
|
|
115
|
+
}
|
|
116
|
+
console.log('');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function summarize(drift) {
|
|
120
|
+
const g = groupByCategory(drift);
|
|
121
|
+
return `${drift.length} change(s): ${g.safe.length} safe, ${g.needs_confirm.length} needs-confirm, ${g.destructive.length} destructive`;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=schema-migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-migrate.js","sourceRoot":"","sources":["../../src/utils/schema-migrate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/cli",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.2.0",
|
|
4
4
|
"description": "Command Line Interface for ObjectStack Protocol",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -47,52 +47,53 @@
|
|
|
47
47
|
"tsx": "^4.22.4",
|
|
48
48
|
"yaml": "^2.9.0",
|
|
49
49
|
"zod": "^4.4.3",
|
|
50
|
-
"@objectstack/account": "10.
|
|
51
|
-
"@objectstack/client": "10.
|
|
52
|
-
"@objectstack/cloud-connection": "10.
|
|
53
|
-
"@objectstack/console": "10.
|
|
54
|
-
"@objectstack/core": "^10.
|
|
55
|
-
"@objectstack/driver-memory": "^10.
|
|
56
|
-
"@objectstack/driver-mongodb": "^10.
|
|
57
|
-
"@objectstack/driver-sql": "^10.
|
|
58
|
-
"@objectstack/driver-sqlite-wasm": "^10.
|
|
59
|
-
"@objectstack/formula": "10.
|
|
60
|
-
"@objectstack/
|
|
61
|
-
"@objectstack/
|
|
62
|
-
"@objectstack/
|
|
63
|
-
"@objectstack/
|
|
64
|
-
"@objectstack/
|
|
65
|
-
"@objectstack/plugin-
|
|
66
|
-
"@objectstack/plugin-
|
|
67
|
-
"@objectstack/
|
|
68
|
-
"@objectstack/
|
|
69
|
-
"@objectstack/plugin-hono-server": "10.
|
|
70
|
-
"@objectstack/
|
|
71
|
-
"@objectstack/plugin-
|
|
72
|
-
"@objectstack/plugin-
|
|
73
|
-
"@objectstack/plugin-
|
|
74
|
-
"@objectstack/plugin-
|
|
75
|
-
"@objectstack/
|
|
76
|
-
"@objectstack/
|
|
77
|
-
"@objectstack/
|
|
78
|
-
"@objectstack/
|
|
79
|
-
"@objectstack/
|
|
80
|
-
"@objectstack/
|
|
81
|
-
"@objectstack/service-
|
|
82
|
-
"@objectstack/service-
|
|
83
|
-
"@objectstack/service-
|
|
84
|
-
"@objectstack/service-
|
|
85
|
-
"@objectstack/service-
|
|
86
|
-
"@objectstack/service-
|
|
87
|
-
"@objectstack/service-
|
|
88
|
-
"@objectstack/service-
|
|
89
|
-
"@objectstack/
|
|
90
|
-
"@objectstack/
|
|
91
|
-
"@objectstack/
|
|
92
|
-
"@objectstack/
|
|
93
|
-
"@objectstack/
|
|
94
|
-
"@objectstack/
|
|
95
|
-
"@objectstack/
|
|
50
|
+
"@objectstack/account": "10.2.0",
|
|
51
|
+
"@objectstack/client": "10.2.0",
|
|
52
|
+
"@objectstack/cloud-connection": "10.2.0",
|
|
53
|
+
"@objectstack/console": "10.2.0",
|
|
54
|
+
"@objectstack/core": "^10.2.0",
|
|
55
|
+
"@objectstack/driver-memory": "^10.2.0",
|
|
56
|
+
"@objectstack/driver-mongodb": "^10.2.0",
|
|
57
|
+
"@objectstack/driver-sql": "^10.2.0",
|
|
58
|
+
"@objectstack/driver-sqlite-wasm": "^10.2.0",
|
|
59
|
+
"@objectstack/formula": "10.2.0",
|
|
60
|
+
"@objectstack/lint": "10.2.0",
|
|
61
|
+
"@objectstack/mcp": "10.2.0",
|
|
62
|
+
"@objectstack/objectql": "^10.2.0",
|
|
63
|
+
"@objectstack/observability": "^10.2.0",
|
|
64
|
+
"@objectstack/platform-objects": "10.2.0",
|
|
65
|
+
"@objectstack/plugin-approvals": "10.2.0",
|
|
66
|
+
"@objectstack/plugin-audit": "10.2.0",
|
|
67
|
+
"@objectstack/plugin-auth": "10.2.0",
|
|
68
|
+
"@objectstack/plugin-email": "10.2.0",
|
|
69
|
+
"@objectstack/plugin-hono-server": "10.2.0",
|
|
70
|
+
"@objectstack/plugin-org-scoping": "10.2.0",
|
|
71
|
+
"@objectstack/plugin-reports": "10.2.0",
|
|
72
|
+
"@objectstack/plugin-security": "10.2.0",
|
|
73
|
+
"@objectstack/plugin-sharing": "10.2.0",
|
|
74
|
+
"@objectstack/plugin-webhooks": "10.2.0",
|
|
75
|
+
"@objectstack/rest": "10.2.0",
|
|
76
|
+
"@objectstack/runtime": "^10.2.0",
|
|
77
|
+
"@objectstack/service-ai": "10.2.0",
|
|
78
|
+
"@objectstack/service-analytics": "10.2.0",
|
|
79
|
+
"@objectstack/service-automation": "10.2.0",
|
|
80
|
+
"@objectstack/service-cache": "10.2.0",
|
|
81
|
+
"@objectstack/service-datasource": "10.2.0",
|
|
82
|
+
"@objectstack/service-job": "10.2.0",
|
|
83
|
+
"@objectstack/service-messaging": "10.2.0",
|
|
84
|
+
"@objectstack/service-package": "10.2.0",
|
|
85
|
+
"@objectstack/service-queue": "10.2.0",
|
|
86
|
+
"@objectstack/service-realtime": "10.2.0",
|
|
87
|
+
"@objectstack/service-settings": "10.2.0",
|
|
88
|
+
"@objectstack/service-storage": "10.2.0",
|
|
89
|
+
"@objectstack/setup": "10.2.0",
|
|
90
|
+
"@objectstack/spec": "10.2.0",
|
|
91
|
+
"@objectstack/studio": "10.2.0",
|
|
92
|
+
"@objectstack/trigger-api": "10.2.0",
|
|
93
|
+
"@objectstack/trigger-record-change": "10.2.0",
|
|
94
|
+
"@objectstack/trigger-schedule": "10.2.0",
|
|
95
|
+
"@objectstack/types": "10.2.0",
|
|
96
|
+
"@objectstack/verify": "10.2.0"
|
|
96
97
|
},
|
|
97
98
|
"devDependencies": {
|
|
98
99
|
"@oclif/plugin-help": "^6.2.52",
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export interface ExprIssue {
|
|
2
|
-
where: string;
|
|
3
|
-
message: string;
|
|
4
|
-
source: string;
|
|
5
|
-
/**
|
|
6
|
-
* `error` fails the build (e.g. a bare ref in a record-scoped formula). `warning`
|
|
7
|
-
* is advisory and never fails it (e.g. a possible field typo in a flattened flow
|
|
8
|
-
* condition, which might be a flow variable). Absent ⇒ treat as `error`.
|
|
9
|
-
*/
|
|
10
|
-
severity?: 'error' | 'warning';
|
|
11
|
-
}
|
|
12
|
-
type AnyRec = Record<string, unknown>;
|
|
13
|
-
/**
|
|
14
|
-
* Validate every predicate in the stack. Returns the list of issues (empty =
|
|
15
|
-
* clean). Caller decides how to surface / whether to fail the build.
|
|
16
|
-
*/
|
|
17
|
-
export declare function validateStackExpressions(stack: AnyRec): ExprIssue[];
|
|
18
|
-
export {};
|
|
19
|
-
//# sourceMappingURL=validate-expressions.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate-expressions.d.ts","sourceRoot":"","sources":["../../src/utils/validate-expressions.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA0BtC;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,CAoKnE"}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
-
/**
|
|
3
|
-
* Build-time expression validation (ADR-0032 §Decision 1a + 1b).
|
|
4
|
-
*
|
|
5
|
-
* Runs at `objectstack compile`, where the whole normalized stack is in hand —
|
|
6
|
-
* so flow conditions can be checked against the *resolved* object schema
|
|
7
|
-
* (field existence) in addition to CEL syntax. Uses the one shared validator
|
|
8
|
-
* from `@objectstack/formula`, so the verdict matches `registerFlow` and the
|
|
9
|
-
* agent `validate_expression` tool exactly.
|
|
10
|
-
*
|
|
11
|
-
* Scope (v1): flow predicates (start/decision `config.condition` + edge
|
|
12
|
-
* `condition`), object validation-rule / formula predicates, and UI action
|
|
13
|
-
* `visible` / `disabled` predicates. Each error is located (flow/object/action
|
|
14
|
-
* + node/edge/field) with a corrective message.
|
|
15
|
-
*/
|
|
16
|
-
import { validateExpression } from '@objectstack/formula';
|
|
17
|
-
/** Coerce an `objects` collection (array or name-keyed map) to an array. */
|
|
18
|
-
function asArray(v) {
|
|
19
|
-
if (Array.isArray(v))
|
|
20
|
-
return v;
|
|
21
|
-
if (v && typeof v === 'object') {
|
|
22
|
-
return Object.entries(v).map(([name, def]) => ({ name, ...def }));
|
|
23
|
-
}
|
|
24
|
-
return [];
|
|
25
|
-
}
|
|
26
|
-
/** object name → set of its field names, for schema-aware field checks. */
|
|
27
|
-
function buildFieldIndex(objects) {
|
|
28
|
-
const idx = new Map();
|
|
29
|
-
for (const obj of objects) {
|
|
30
|
-
const name = typeof obj.name === 'string' ? obj.name : undefined;
|
|
31
|
-
if (!name)
|
|
32
|
-
continue;
|
|
33
|
-
const fields = obj.fields;
|
|
34
|
-
let names = [];
|
|
35
|
-
if (Array.isArray(fields))
|
|
36
|
-
names = fields.map(f => f.name).filter((n) => typeof n === 'string');
|
|
37
|
-
else if (fields && typeof fields === 'object')
|
|
38
|
-
names = Object.keys(fields);
|
|
39
|
-
idx.set(name, names);
|
|
40
|
-
}
|
|
41
|
-
return idx;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Validate every predicate in the stack. Returns the list of issues (empty =
|
|
45
|
-
* clean). Caller decides how to surface / whether to fail the build.
|
|
46
|
-
*/
|
|
47
|
-
export function validateStackExpressions(stack) {
|
|
48
|
-
const issues = [];
|
|
49
|
-
const objects = asArray(stack.objects);
|
|
50
|
-
const fieldIndex = buildFieldIndex(objects);
|
|
51
|
-
const check = (where, raw, objectName, scope = 'flattened') => {
|
|
52
|
-
if (raw == null)
|
|
53
|
-
return;
|
|
54
|
-
const fields = objectName ? fieldIndex.get(objectName) : undefined;
|
|
55
|
-
const res = validateExpression('predicate', raw, objectName ? { objectName, fields, scope } : { scope });
|
|
56
|
-
for (const e of res.errors)
|
|
57
|
-
issues.push({ where, message: e.message, source: e.source, severity: 'error' });
|
|
58
|
-
for (const w of res.warnings)
|
|
59
|
-
issues.push({ where, message: w.message, source: w.source, severity: 'warning' });
|
|
60
|
-
};
|
|
61
|
-
// ── Flows ──────────────────────────────────────────────────────────
|
|
62
|
-
for (const flow of asArray(stack.flows)) {
|
|
63
|
-
const flowName = typeof flow.name === 'string' ? flow.name : '(unnamed flow)';
|
|
64
|
-
const nodes = Array.isArray(flow.nodes) ? flow.nodes : [];
|
|
65
|
-
const edges = Array.isArray(flow.edges) ? flow.edges : [];
|
|
66
|
-
// The record-change target object — `record.*` refs resolve against it.
|
|
67
|
-
const startNode = nodes.find(n => n.type === 'start');
|
|
68
|
-
const startCfg = (startNode?.config ?? {});
|
|
69
|
-
const objectName = typeof startCfg.objectName === 'string' ? startCfg.objectName : undefined;
|
|
70
|
-
for (const node of nodes) {
|
|
71
|
-
const cfg = (node.config ?? {});
|
|
72
|
-
check(`flow '${flowName}' · node '${node.id}' (${node.type}) condition`, cfg.condition, objectName);
|
|
73
|
-
// #1870 — a `script` node must declare a callable target (`actionType` or
|
|
74
|
-
// `function`). A node with neither is a silent no-op that otherwise passes
|
|
75
|
-
// build. (Function *existence* isn't checkable here — functions are code,
|
|
76
|
-
// not serialized into the artifact — so this is a structural check; the
|
|
77
|
-
// runtime verifies the named function is actually registered.)
|
|
78
|
-
if (node.type === 'script') {
|
|
79
|
-
// `function` is canonical; `functionName` is an accepted alias.
|
|
80
|
-
const fn = (typeof cfg.function === 'string' ? cfg.function.trim() : '') ||
|
|
81
|
-
(typeof cfg.functionName === 'string' ? cfg.functionName.trim() : '');
|
|
82
|
-
const action = typeof cfg.actionType === 'string' ? cfg.actionType.trim() : '';
|
|
83
|
-
// Inline `config.script` (a JS body) is also a declared form — the
|
|
84
|
-
// built-in runtime doesn't execute it (warned at run time), but the node
|
|
85
|
-
// is not the empty no-op this check targets, so don't flag it.
|
|
86
|
-
const inline = typeof cfg.script === 'string' ? cfg.script.trim() : '';
|
|
87
|
-
if (!fn && !action && !inline) {
|
|
88
|
-
issues.push({
|
|
89
|
-
where: `flow '${flowName}' · node '${node.id}' (script) callable`,
|
|
90
|
-
message: `script node declares neither \`actionType\` nor \`function\` — it would do nothing at runtime. ` +
|
|
91
|
-
`Name a built-in action (e.g. \`actionType: 'email'\`) or a registered function ` +
|
|
92
|
-
`(\`function: 'my_fn'\`, registered via \`defineStack({ functions })\`).`,
|
|
93
|
-
source: JSON.stringify({ id: node.id, type: node.type, config: cfg }),
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
else if (action === 'invoke_function' && !fn) {
|
|
97
|
-
// `actionType: 'invoke_function'` is a marker that names no callable on
|
|
98
|
-
// its own — the function name must be in `function`/`functionName`.
|
|
99
|
-
issues.push({
|
|
100
|
-
where: `flow '${flowName}' · node '${node.id}' (script) callable`,
|
|
101
|
-
message: `script node uses \`actionType: 'invoke_function'\` but no \`function\` (or \`functionName\`) — ` +
|
|
102
|
-
`it names no callable. Set \`function: 'my_fn'\` and register it via \`defineStack({ functions })\`.`,
|
|
103
|
-
source: JSON.stringify({ id: node.id, type: node.type, config: cfg }),
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
for (const edge of edges) {
|
|
109
|
-
check(`flow '${flowName}' · edge '${edge.id}' (${edge.source}→${edge.target}) condition`, edge.condition, objectName);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
// ── Object validation-rule + formula predicates ────────────────────
|
|
113
|
-
for (const obj of objects) {
|
|
114
|
-
const objectName = typeof obj.name === 'string' ? obj.name : undefined;
|
|
115
|
-
const validations = obj.validations ?? obj.validationRules;
|
|
116
|
-
for (const rule of asArray(validations)) {
|
|
117
|
-
const where = `object '${objectName}' · validation '${rule.name ?? '?'}'`;
|
|
118
|
-
// Common predicate keys across rule shapes. Validation predicates are
|
|
119
|
-
// `record`-scoped — no field flattening — so bare refs are flagged (#1928).
|
|
120
|
-
check(where, rule.expression ?? rule.predicate ?? rule.condition ?? rule.formula, objectName, 'record');
|
|
121
|
-
// `conditional` rules carry a nested `when` predicate (record-scoped).
|
|
122
|
-
check(`${where} when`, rule.when, objectName, 'record');
|
|
123
|
-
}
|
|
124
|
-
// Field-level formulas (computed fields) reference the same object.
|
|
125
|
-
const fields = obj.fields;
|
|
126
|
-
const fieldList = Array.isArray(fields)
|
|
127
|
-
? fields
|
|
128
|
-
: (fields && typeof fields === 'object' ? Object.values(fields) : []);
|
|
129
|
-
for (const f of fieldList) {
|
|
130
|
-
// Field-level conditional rules are server-enforced (rule-validator) and
|
|
131
|
-
// record-scoped — a bare ref silently fails the rule (required/readonly
|
|
132
|
-
// not enforced = data-integrity hole). #1928 class, same as actions.
|
|
133
|
-
if (f && typeof f === 'object') {
|
|
134
|
-
const fname = f.name ?? '?';
|
|
135
|
-
for (const key of ['requiredWhen', 'readonlyWhen', 'conditionalRequired', 'visibleWhen']) {
|
|
136
|
-
check(`object '${objectName}' · field '${fname}' ${key}`, f[key], objectName, 'record');
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
if (f && typeof f === 'object' && f.formula) {
|
|
140
|
-
// formulas are `value` role (any return type), still CEL. They are
|
|
141
|
-
// `record`-scoped — `record.<field>`, never bare — so flag bare refs (#1928).
|
|
142
|
-
const res = validateExpression('value', f.formula, objectName ? { objectName, fields: fieldIndex.get(objectName), scope: 'record' } : { scope: 'record' });
|
|
143
|
-
const fieldWhere = `object '${objectName}' · field '${f.name ?? '?'}' formula`;
|
|
144
|
-
for (const e of res.errors)
|
|
145
|
-
issues.push({ where: fieldWhere, message: e.message, source: e.source, severity: 'error' });
|
|
146
|
-
for (const w of res.warnings)
|
|
147
|
-
issues.push({ where: fieldWhere, message: w.message, source: w.source, severity: 'warning' });
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
// ── Action `visible` / `disabled` predicates ───────────────────────
|
|
152
|
-
// Record-scoped, same as validation rules: a record-header / row action's
|
|
153
|
-
// `visible` is evaluated by ActionEngine against `{ record, recordId,
|
|
154
|
-
// objectName, user, … }` with fail-closed semantics, so a BARE field ref
|
|
155
|
-
// (`done` instead of `record.done`) throws and the action is silently hidden
|
|
156
|
-
// on every record (the trap behind the #2183 "Mark Done never hides" hunt).
|
|
157
|
-
// Flagging it here turns that into a build error with a corrective message.
|
|
158
|
-
// `disabled` may be a boolean (skip) or a predicate (check).
|
|
159
|
-
const seenActions = new Set();
|
|
160
|
-
const checkAction = (where, action, objectName) => {
|
|
161
|
-
const obj = objectName
|
|
162
|
-
?? (typeof action.objectName === 'string' ? action.objectName : undefined)
|
|
163
|
-
?? (typeof action.object === 'string' ? action.object : undefined);
|
|
164
|
-
const name = typeof action.name === 'string' ? action.name : '?';
|
|
165
|
-
const key = `${obj ?? ''}:${name}`;
|
|
166
|
-
if (seenActions.has(key))
|
|
167
|
-
return; // de-dup (actions are merged onto objects AND kept top-level)
|
|
168
|
-
seenActions.add(key);
|
|
169
|
-
check(`${where} · action '${name}' visible`, action.visible, obj, 'record');
|
|
170
|
-
if (typeof action.disabled !== 'boolean') {
|
|
171
|
-
check(`${where} · action '${name}' disabled`, action.disabled, obj, 'record');
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
for (const action of asArray(stack.actions)) {
|
|
175
|
-
checkAction('stack', action);
|
|
176
|
-
}
|
|
177
|
-
for (const obj of objects) {
|
|
178
|
-
const objectName = typeof obj.name === 'string' ? obj.name : undefined;
|
|
179
|
-
for (const action of asArray(obj.actions)) {
|
|
180
|
-
checkAction(`object '${objectName}'`, action, objectName);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
// ── Sharing-rule predicates (security-critical, record-scoped) ─────
|
|
184
|
-
// A criteria sharing rule's `condition` decides which rows a principal sees.
|
|
185
|
-
// It is evaluated against the record, so a bare ref silently changes access.
|
|
186
|
-
for (const rule of asArray(stack.sharingRules)) {
|
|
187
|
-
const ruleObj = typeof rule.object === 'string' ? rule.object : undefined;
|
|
188
|
-
const where = `sharingRule '${rule.name ?? '?'}'${ruleObj ? ` (${ruleObj})` : ''} condition`;
|
|
189
|
-
check(where, rule.condition ?? rule.criteria ?? rule.predicate, ruleObj, 'record');
|
|
190
|
-
}
|
|
191
|
-
// ── Hook `condition` predicates (record-scoped gate) ───────────────
|
|
192
|
-
// A lifecycle hook's `condition` skips the handler when false; it is
|
|
193
|
-
// evaluated against the record, so a bare ref silently makes the hook
|
|
194
|
-
// run on every record (or never) instead of the intended subset.
|
|
195
|
-
for (const hook of asArray(stack.hooks)) {
|
|
196
|
-
const hookObj = typeof hook.object === 'string' ? hook.object : undefined; // array targets → no single field set
|
|
197
|
-
check(`hook '${hook.name ?? '?'}'${hookObj ? ` (${hookObj})` : ''} condition`, hook.condition, hookObj, 'record');
|
|
198
|
-
}
|
|
199
|
-
return issues;
|
|
200
|
-
}
|
|
201
|
-
//# sourceMappingURL=validate-expressions.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate-expressions.js","sourceRoot":"","sources":["../../src/utils/validate-expressions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate-expressions.test.d.ts","sourceRoot":"","sources":["../../src/utils/validate-expressions.test.ts"],"names":[],"mappings":""}
|