@sun-asterisk/sungen 3.2.10-beta.5 → 3.2.10
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/capabilities/discover.d.ts.map +1 -1
- package/dist/capabilities/discover.js +2 -5
- package/dist/capabilities/discover.js.map +1 -1
- package/dist/cli/commands/capability.d.ts.map +1 -1
- package/dist/cli/commands/capability.js +2 -44
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/harness/capability.d.ts +0 -1
- package/dist/harness/capability.d.ts.map +1 -1
- package/dist/harness/capability.js.map +1 -1
- package/dist/harness/catalog/drivers.yaml +1 -2
- package/dist/harness/query-catalog.d.ts +2 -32
- package/dist/harness/query-catalog.d.ts.map +1 -1
- package/dist/harness/query-catalog.js +0 -0
- package/dist/harness/query-catalog.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/templates/ai-src/commands/run-test.md +0 -1
- package/dist/orchestrator/templates/ai-src/config/claude.md +1 -3
- package/dist/orchestrator/templates/ai-src/config/copilot.md +1 -3
- package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +5 -15
- package/dist/orchestrator/templates/specs-db.d.ts +11 -201
- package/dist/orchestrator/templates/specs-db.d.ts.map +1 -1
- package/dist/orchestrator/templates/specs-db.js +91 -440
- package/dist/orchestrator/templates/specs-db.js.map +1 -1
- package/dist/orchestrator/templates/specs-db.ts +79 -463
- package/dist/orchestrator/templates/specs-test-data.ts +3 -39
- package/package.json +4 -8
- package/src/capabilities/discover.ts +2 -5
- package/src/cli/commands/capability.ts +2 -40
- package/src/harness/capability.ts +0 -1
- package/src/harness/catalog/drivers.yaml +1 -2
- package/src/harness/query-catalog.ts +0 -0
- package/src/index.ts +2 -2
- package/src/orchestrator/templates/ai-src/commands/run-test.md +0 -1
- package/src/orchestrator/templates/ai-src/config/claude.md +1 -3
- package/src/orchestrator/templates/ai-src/config/copilot.md +1 -3
- package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +5 -15
- package/src/orchestrator/templates/specs-db.ts +79 -463
- package/src/orchestrator/templates/specs-test-data.ts +3 -39
- package/dist/orchestrator/templates/ai-src/commands/create-data-test.md +0 -85
- package/dist/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +0 -101
- package/src/orchestrator/templates/ai-src/commands/create-data-test.md +0 -85
- package/src/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +0 -101
|
@@ -1,226 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `build()` always emits PG-style `$1..$n` placeholders; mysql2/better-sqlite3 both bind with
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* `
|
|
6
|
-
* silently swap and the query returns wrong rows. A repeated `$k` duplicates its value at each `?`.
|
|
7
|
-
* Postgres binds `$n` natively, so it is returned untouched.
|
|
8
|
-
*
|
|
9
|
-
* Only real placeholders are rewritten — a `$1` inside a single-quoted string literal (e.g.
|
|
10
|
-
* `WHERE label = '$1 off'`) is left untouched. SQL escapes an inner quote by doubling it (`''`),
|
|
11
|
-
* which the simple in-string toggle handles (an even number of quotes returns to the same state).
|
|
12
|
-
*
|
|
13
|
-
* DynamoDB PartiQL binds the same positional `?` as mysql2/sqlite, so it shares this path — the
|
|
14
|
-
* reorder is essential there too (an author-written PartiQL `WHERE sk = $2 AND pk = $1`).
|
|
2
|
+
* `build()` always emits PG-style `$1..$n` placeholders; mysql2/better-sqlite3 both bind with `?`.
|
|
3
|
+
* Only real placeholders are rewritten — a `$1` sitting inside a single-quoted string literal (e.g.
|
|
4
|
+
* a catalog query `WHERE label = '$1 off'`) is left untouched. SQL escapes an inner quote by doubling
|
|
5
|
+
* it (`''`), which the simple in-string toggle handles (an even number of quotes returns to the same state).
|
|
15
6
|
*/
|
|
16
|
-
export declare function rewritePlaceholders(engine: string, sql: string
|
|
17
|
-
sql: string;
|
|
18
|
-
params: any[];
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Engine contract — the assertion surface is engine-agnostic; each engine owns its own dialect so
|
|
22
|
-
* a NoSQL store (Cosmos / MongoDB / DynamoDB) can back the same declarative steps as SQL.
|
|
23
|
-
* findRows(table, filter, limit) — rows matching an equality filter, capped at `limit`
|
|
24
|
-
* countRows(table, filter) — count of rows matching an equality filter
|
|
25
|
-
* runQuery(label, sql, params) — a raw catalog query (read-only). SQL dialects (incl. Cosmos SQL
|
|
26
|
-
* and DynamoDB PartiQL) take a SQL string; MongoDB's non-SQL
|
|
27
|
-
* find/pipeline shapes are dispatched separately via fetchQueryShape.
|
|
28
|
-
*/
|
|
29
|
-
interface Engine {
|
|
30
|
-
findRows(table: string, filter: Record<string, any>, limit: number): Promise<any[]>;
|
|
31
|
-
countRows(table: string, filter: Record<string, any>): Promise<number>;
|
|
32
|
-
runQuery(label: string, sql: string, params: any[]): Promise<any[]>;
|
|
33
|
-
runShape?(label: string, shape: ShapeQuery, params: Record<string, any>): Promise<any[]>;
|
|
34
|
-
}
|
|
35
|
-
/** A MongoDB catalog entry's runtime shape: exactly one of find/pipeline, with `:param` placeholders bound at runtime. */
|
|
36
|
-
type ShapeQuery = {
|
|
37
|
-
find?: {
|
|
38
|
-
collection: string;
|
|
39
|
-
filter?: Record<string, any>;
|
|
40
|
-
projection?: Record<string, any>;
|
|
41
|
-
sort?: Record<string, any>;
|
|
42
|
-
limit?: number;
|
|
43
|
-
};
|
|
44
|
-
pipeline?: {
|
|
45
|
-
collection: string;
|
|
46
|
-
stages: any[];
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
/** Minimal shape of an @azure/cosmos container the engine uses — kept local so the SDK stays a lazy dep. */
|
|
50
|
-
type CosmosContainer = {
|
|
51
|
-
items: {
|
|
52
|
-
query(spec: {
|
|
53
|
-
query: string;
|
|
54
|
-
parameters: Array<{
|
|
55
|
-
name: string;
|
|
56
|
-
value: any;
|
|
57
|
-
}>;
|
|
58
|
-
}, opts?: any): {
|
|
59
|
-
fetchAll(): Promise<{
|
|
60
|
-
resources: any[];
|
|
61
|
-
}>;
|
|
62
|
-
};
|
|
63
|
-
};
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* Azure Cosmos DB (NoSQL API) engine. The Cosmos query API is read-only by construction — `.query()`
|
|
67
|
-
* only ever reads; mutations require item-level APIs this engine never calls — so the SELECT guard is
|
|
68
|
-
* defense-in-depth. Cosmos binds NAMED params (`@p`), so it is immune to the positional-`?` reorder
|
|
69
|
-
* hazard. A step/catalog `[table]` selects the container; `SELECT * FROM c` uses the mandatory `c` alias.
|
|
70
|
-
*/
|
|
71
|
-
export declare class CosmosEngine implements Engine {
|
|
72
|
-
private getContainer;
|
|
73
|
-
private opts;
|
|
74
|
-
constructor(getContainer: (name?: string) => CosmosContainer, opts: {
|
|
75
|
-
timeoutMs: number;
|
|
76
|
-
maxRows: number;
|
|
77
|
-
});
|
|
78
|
-
private query;
|
|
79
|
-
/** Build `c.<col> = @p<i>` equality predicates over the mandatory `c` alias. Columns are identifier-checked. */
|
|
80
|
-
private whereFor;
|
|
81
|
-
findRows(table: string, filter: Record<string, any>, limit: number): Promise<any[]>;
|
|
82
|
-
countRows(table: string, filter: Record<string, any>): Promise<number>;
|
|
83
|
-
runQuery(label: string, sql: string, params: any[]): Promise<any[]>;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Rewrite compiled positional `$n` placeholders to Cosmos NAMED params (`@pN`) and collect the
|
|
87
|
-
* matching parameter list. A `$n` inside a single-quoted string literal is left untouched (same
|
|
88
|
-
* in-string toggle as the SQL rewrite); a repeated `$n` reuses its one `@pN` entry.
|
|
89
|
-
*/
|
|
90
|
-
export declare function cosmosBindParams(sql: string, params: any[]): {
|
|
91
|
-
query: string;
|
|
92
|
-
parameters: Array<{
|
|
93
|
-
name: string;
|
|
94
|
-
value: any;
|
|
95
|
-
}>;
|
|
96
|
-
};
|
|
97
|
-
/** Minimal shapes of the mongodb driver objects the engine uses — kept local so the SDK stays a lazy dep. */
|
|
98
|
-
type MongoCursor = {
|
|
99
|
-
project(p: any): MongoCursor;
|
|
100
|
-
sort(s: any): MongoCursor;
|
|
101
|
-
limit(n: number): MongoCursor;
|
|
102
|
-
maxTimeMS(t: number): MongoCursor;
|
|
103
|
-
toArray(): Promise<any[]>;
|
|
104
|
-
};
|
|
105
|
-
type MongoCollection = {
|
|
106
|
-
find(filter: any): MongoCursor;
|
|
107
|
-
countDocuments(filter: any, opts?: any): Promise<number>;
|
|
108
|
-
aggregate(pipeline: any[], opts?: any): {
|
|
109
|
-
toArray(): Promise<any[]>;
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
/**
|
|
113
|
-
* MongoDB engine. There is no SQL — declarative steps map to native find()/countDocuments(), and the
|
|
114
|
-
* raw `@query` path takes a find/pipeline shape (via fetchQueryShape → runShape) rather than a SQL
|
|
115
|
-
* string. Type-strict matching (`{age:30}` ≠ `{age:"30"}`) is why DB params bind via raw() (native
|
|
116
|
-
* type), not the stringifying get(). Read-only is enforced first by the server-side read role, with
|
|
117
|
-
* the operator blocklist as in-driver defense-in-depth. Per-query `maxTimeMS` + row cap bound cost.
|
|
118
|
-
*/
|
|
119
|
-
export declare class MongoEngine implements Engine {
|
|
120
|
-
private getCollection;
|
|
121
|
-
private opts;
|
|
122
|
-
constructor(getCollection: (name: string) => MongoCollection, opts: {
|
|
123
|
-
timeoutMs: number;
|
|
124
|
-
maxRows: number;
|
|
125
|
-
});
|
|
126
|
-
findRows(table: string, filter: Record<string, any>, limit: number): Promise<any[]>;
|
|
127
|
-
countRows(table: string, filter: Record<string, any>): Promise<number>;
|
|
128
|
-
runQuery(label: string): Promise<any[]>;
|
|
129
|
-
runShape(label: string, shape: ShapeQuery, params: Record<string, any>): Promise<any[]>;
|
|
130
|
-
}
|
|
131
|
-
/** The three read-only DynamoDB operations the engine needs, over the auto-marshalling Document client. */
|
|
132
|
-
type DynamoOps = {
|
|
133
|
-
executeStatement(input: {
|
|
134
|
-
Statement: string;
|
|
135
|
-
Parameters?: any[];
|
|
136
|
-
Limit?: number;
|
|
137
|
-
NextToken?: string;
|
|
138
|
-
}, signal?: AbortSignal): Promise<{
|
|
139
|
-
Items?: any[];
|
|
140
|
-
NextToken?: string;
|
|
141
|
-
}>;
|
|
142
|
-
getItem(input: {
|
|
143
|
-
TableName: string;
|
|
144
|
-
Key: Record<string, any>;
|
|
145
|
-
}, signal?: AbortSignal): Promise<{
|
|
146
|
-
Item?: any;
|
|
147
|
-
}>;
|
|
148
|
-
query(input: {
|
|
149
|
-
TableName: string;
|
|
150
|
-
KeyConditionExpression: string;
|
|
151
|
-
ExpressionAttributeNames: Record<string, string>;
|
|
152
|
-
ExpressionAttributeValues: Record<string, any>;
|
|
153
|
-
Select?: string;
|
|
154
|
-
Limit?: number;
|
|
155
|
-
ExclusiveStartKey?: Record<string, any>;
|
|
156
|
-
}, signal?: AbortSignal): Promise<{
|
|
157
|
-
Items?: any[];
|
|
158
|
-
Count?: number;
|
|
159
|
-
LastEvaluatedKey?: Record<string, any>;
|
|
160
|
-
}>;
|
|
161
|
-
};
|
|
162
|
-
type KeySchema = Record<string, {
|
|
163
|
-
partitionKey: string;
|
|
164
|
-
sortKey?: string | null;
|
|
165
|
-
}>;
|
|
166
|
-
/**
|
|
167
|
-
* DynamoDB engine. The clean primary path is raw `@query` PartiQL SELECT (positional `?`, reordered
|
|
168
|
-
* via the shared placeholder rewrite). Declarative assertRow/count is structurally constrained by
|
|
169
|
-
* DynamoDB's key model: it routes GetItem/Query only for pk / pk+sk filters (via the `keySchema`
|
|
170
|
-
* registry) and REFUSES a non-key filter rather than falling back to an unaffordable full-table Scan.
|
|
171
|
-
* Read-only is primarily IAM (`dynamodb:PartiQLSelect` only); the SELECT guard is defense-in-depth.
|
|
172
|
-
*/
|
|
173
|
-
export declare class DynamoEngine implements Engine {
|
|
174
|
-
private ops;
|
|
175
|
-
private keySchema;
|
|
176
|
-
private opts;
|
|
177
|
-
constructor(ops: DynamoOps, keySchema: KeySchema, opts: {
|
|
178
|
-
timeoutMs: number;
|
|
179
|
-
maxRows: number;
|
|
180
|
-
});
|
|
181
|
-
private withTimeout;
|
|
182
|
-
/** Decide how a flat equality filter maps to a key-based access pattern, or refuse it. */
|
|
183
|
-
private route;
|
|
184
|
-
findRows(table: string, filter: Record<string, any>, limit: number): Promise<any[]>;
|
|
185
|
-
countRows(table: string, filter: Record<string, any>): Promise<number>;
|
|
186
|
-
runQuery(label: string, sql: string, params: any[]): Promise<any[]>;
|
|
187
|
-
}
|
|
7
|
+
export declare function rewritePlaceholders(engine: string, sql: string): string;
|
|
188
8
|
declare class DataSource {
|
|
189
9
|
private configs;
|
|
190
10
|
private engines;
|
|
191
11
|
private tunnels;
|
|
192
12
|
private mysqlPools;
|
|
193
|
-
private mongoClients;
|
|
194
13
|
private cfg;
|
|
195
14
|
private engine;
|
|
196
|
-
/**
|
|
197
|
-
private sqlExec;
|
|
198
|
-
/** Build the Cosmos engine — connect via endpoint+key or a connection-string url; resolve containers by name. */
|
|
199
|
-
private cosmosEngine;
|
|
200
|
-
/** Build the MongoDB engine — one reused client per datasource; the db comes from `database` or the URI default. */
|
|
201
|
-
private mongoEngine;
|
|
202
|
-
/** Build the DynamoDB engine — region + credentials from the AWS env chain; wraps the Document client's three read ops. */
|
|
203
|
-
private dynamoEngine;
|
|
204
|
-
/** Close open MySQL pools + Mongo clients + SSH tunnels (optional explicit teardown; tunnels are unref'd so the process exits regardless). */
|
|
15
|
+
/** Close open MySQL pools + SSH tunnels (optional explicit teardown; tunnels are unref'd so the process exits regardless). */
|
|
205
16
|
close(): void;
|
|
17
|
+
private build;
|
|
206
18
|
/** A row matching `filter` must exist; if `expected` given, assert those columns on the first match. */
|
|
207
19
|
assertRow(table: string, filter: Record<string, any>, expected?: Record<string, any>, datasource?: string): Promise<void>;
|
|
208
20
|
/** No row matching `filter` may exist. */
|
|
209
21
|
assertNoRow(table: string, filter: Record<string, any>, datasource?: string): Promise<void>;
|
|
210
22
|
/** Exactly `count` rows must match `filter`. */
|
|
211
23
|
assertCount(table: string, filter: Record<string, any>, count: number, datasource?: string): Promise<void>;
|
|
24
|
+
/** Rewrites $1/$2 placeholders to `?` for engines that don't support PG-style positional params. */
|
|
25
|
+
private sqlFor;
|
|
26
|
+
/** Read-only guard (second layer): a named query must be a single SELECT/WITH statement. */
|
|
27
|
+
private assertSelectOnly;
|
|
212
28
|
/**
|
|
213
29
|
* Run a catalog query (read-only) and return its rows. The result is bound to a `{{name}}`
|
|
214
30
|
* variable via `testData.bind(...)`, so the scenario asserts on it with `expect …` steps and
|
|
215
31
|
* path access (`{{name.count}}`, `{{name.first.col}}`, `{{name[2].col}}`).
|
|
216
32
|
*/
|
|
217
33
|
fetchQuery(label: string, sql: string, params: any[], datasource?: string): Promise<any[]>;
|
|
218
|
-
/**
|
|
219
|
-
* Run a MongoDB find/pipeline catalog query (read-only) and return its documents. Same binding
|
|
220
|
-
* contract as fetchQuery, but the query is a structured shape (not SQL) with `:param` placeholders
|
|
221
|
-
* bound from `params` at runtime. Refused on an engine that has no non-SQL shape support.
|
|
222
|
-
*/
|
|
223
|
-
fetchQueryShape(label: string, shape: ShapeQuery, params: Record<string, any>, datasource?: string): Promise<any[]>;
|
|
224
34
|
}
|
|
225
35
|
export declare const db: DataSource;
|
|
226
36
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"specs-db.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/templates/specs-db.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"specs-db.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/templates/specs-db.ts"],"names":[],"mappings":"AA8HA;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAiBvE;AAID,cAAM,UAAU;IACd,OAAO,CAAC,OAAO,CAAiD;IAChE,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,UAAU,CAA2C;IAE7D,OAAO,CAAC,GAAG;YAQG,MAAM;IAkEpB,8HAA8H;IAC9H,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,KAAK;IAOb,wGAAwG;IAClG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc/H,0CAA0C;IACpC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOjG,gDAAgD;IAC1C,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhH,oGAAoG;IACpG,OAAO,CAAC,MAAM;IAKd,4FAA4F;IAC5F,OAAO,CAAC,gBAAgB;IASxB;;;;OAIG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;CAKjG;AAMD,eAAO,MAAM,EAAE,YAAmB,CAAC"}
|