@ductape/sdk 0.4.5 → 0.4.6

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.
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compileSqlContext = compileSqlContext;
4
+ function compileSqlContext(table, context, postgres) {
5
+ var _a;
6
+ const id = (value) => {
7
+ if (typeof value !== 'string' || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(value))
8
+ throw new Error('Invalid SQL context identifier');
9
+ return postgres ? `"${value}"` : '`' + value + '`';
10
+ };
11
+ const aliases = new Set(['root']);
12
+ for (const join of context.joins || []) {
13
+ id(join.alias);
14
+ if (aliases.has(join.alias))
15
+ throw new Error('Duplicate SQL alias');
16
+ aliases.add(join.alias);
17
+ }
18
+ const field = (value) => {
19
+ if (typeof value !== 'string')
20
+ throw new Error('Invalid SQL field');
21
+ const parts = value.split('.');
22
+ if (parts.length !== 2 || !aliases.has(parts[0]))
23
+ throw new Error('Use alias.column for SQL fields');
24
+ return parts.map(id).join('.');
25
+ };
26
+ const params = [];
27
+ const where = (values) => {
28
+ if (!values || !Object.keys(values).length)
29
+ throw new Error('Explicit ownership predicates required');
30
+ return Object.entries(values).map(([key, value]) => {
31
+ if (value === null)
32
+ return `${field(key)} IS NULL`;
33
+ if (!['string', 'number', 'boolean'].includes(typeof value) || (typeof value === 'number' && !Number.isFinite(value)))
34
+ throw new Error('SQL context predicates require scalar values');
35
+ params.push(value);
36
+ return `${field(key)} = ${postgres ? '$' + params.length : '?'}`;
37
+ }).join(' AND ');
38
+ };
39
+ if (!context.select || !Object.keys(context.select).length || Object.keys(context.select).length > 100
40
+ || !Number.isInteger(context.limit) || context.limit < 1 || context.limit > 100 || (((_a = context.joins) === null || _a === void 0 ? void 0 : _a.length) || 0) > 8)
41
+ throw new Error('SQL context bounds exceeded');
42
+ const select = Object.entries(context.select).map(([alias, column]) => `${field(column)} AS ${id(alias)}`).join(', ');
43
+ const joins = (context.joins || []).map(join => {
44
+ if (!join.on || !Object.keys(join.on).length || (join.kind && !['left', 'inner'].includes(join.kind)))
45
+ throw new Error('Invalid context join');
46
+ const on = Object.entries(join.on).map(([a, b]) => `${field(a)} = ${field(b)}`).join(' AND ');
47
+ return `${join.kind === 'inner' ? 'INNER' : 'LEFT'} JOIN ${id(join.table)} AS ${id(join.alias)} ON (${on}) AND (${where(join.where)})`;
48
+ }).join(' ');
49
+ return { query: `SELECT ${select} FROM ${id(table)} AS ${id('root')} ${joins} WHERE ${where(context.where)} LIMIT ${context.limit}`, params };
50
+ }
51
+ //# sourceMappingURL=sql-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-context.js","sourceRoot":"","sources":["../../src/database/sql-context.ts"],"names":[],"mappings":"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"}
@@ -13,3 +13,4 @@ export { IActionDefinition, IActionTemplate, IActionOrderBy, IActionCreateOption
13
13
  export { PreSaveOperationType, IPreSaveOperation, IPreSaveBaseOptions, IPreSaveEncryptOptions, IPreSaveHashOptions, IPreSaveMaskOptions, IPreSaveValidateOptions, IPreSaveTransformOptions, IPreSaveSlugOptions, IPreSaveTruncateOptions, IPreSaveRoundOptions, IPreSaveClampOptions, IPreSaveDefaultOptions, IPreSaveComputeOptions, IPreSaveSimpleOptions, IValidationRule, IValidationError, IPreSaveConfig, IPreSaveResult, IAppliedOperation, ISchemaPreSaveConfig, } from './presave.interface';
14
14
  export { TriggerEvent, TriggerTiming, TriggerActionType, ConditionOperator, ITriggerActionBase, ITriggerDatabaseAction, ITriggerStorageAction, ITriggerNotificationAction, ITriggerBrokerAction, ITriggerCacheAction, ITriggerFeatureAction, ITriggerActionExecuteAction, ITriggerAgentAction, ITriggerResilienceAction, ITriggerLogAction, ITriggerSessionAction, ITriggerVectorAction, ITriggerCustomAction, ITriggerHttpAction, ITriggerAction, IConditionClause, ITriggerCondition, ITriggerContext, ITriggerRetry, ITriggerDefinition, ITriggerActionResult, ITriggerResult, ITriggerConfig, ISchemaTriggerConfig, } from './trigger.interface';
15
15
  export { IFetchDatabaseDashboardOptions, IDatabaseDashboardMetrics, } from './dashboard.interface';
16
+ export type { IMongoPipelineOptions, IMongoPipelineResult } from './pipeline.interface';
@@ -0,0 +1,19 @@
1
+ import { ITransaction } from './transaction.interface';
2
+ /** MongoDB read pipeline. Ownership predicates must be supplied for roots and lookups. */
3
+ export interface IMongoPipelineOptions {
4
+ product: string;
5
+ env: string;
6
+ database: string;
7
+ table: string;
8
+ pipeline: Record<string, unknown>[];
9
+ session?: string;
10
+ transaction?: ITransaction;
11
+ maxTimeMS?: number;
12
+ allowDiskUse?: boolean;
13
+ }
14
+ export interface IMongoPipelineResult<T> {
15
+ data: T[];
16
+ /** Number of returned documents, not an independent total-count query. */
17
+ count: number;
18
+ }
19
+ export declare function validateReadPipeline(pipeline: unknown): asserts pipeline is Record<string, unknown>[];
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateReadPipeline = validateReadPipeline;
4
+ function validateReadPipeline(pipeline) {
5
+ if (!Array.isArray(pipeline))
6
+ throw new Error('MongoDB pipeline must be an array');
7
+ const visit = (value) => {
8
+ if (!value || typeof value !== 'object')
9
+ return;
10
+ for (const [key, child] of Object.entries(value)) {
11
+ if (key === '$out' || key === '$merge')
12
+ throw new Error('aggregatePipeline is read-only');
13
+ visit(child);
14
+ }
15
+ };
16
+ for (const stage of pipeline) {
17
+ if (!stage || typeof stage !== 'object' || Array.isArray(stage) || Object.keys(stage).length !== 1)
18
+ throw new Error('Each MongoDB pipeline stage must have exactly one operator');
19
+ visit(stage);
20
+ }
21
+ }
22
+ //# sourceMappingURL=pipeline.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.interface.js","sourceRoot":"","sources":["../../../src/database/types/pipeline.interface.ts"],"names":[],"mappings":";;AAqBA,oDAcC;AAdD,SAAgB,oBAAoB,CAAC,QAAiB;IACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACnF,MAAM,KAAK,GAAG,CAAC,KAAc,EAAQ,EAAE;QACrC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO;QAChD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;YAC1F,KAAK,CAAC,KAAK,CAAC,CAAC;QACf,CAAC;IACH,CAAC,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;YAChG,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,KAAK,CAAC,KAAK,CAAC,CAAC;IACf,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -236,6 +236,9 @@ export { AgentExecutor, AgentContext, ToolRegistry, MemoryManager, createLLMProv
236
236
  export type { IAgentServiceConfig, IDefineAgentOptions, IDefinedAgent, IRunAgentOptions, IAgentExecutionResult, IDispatchAgentOptions, IDispatchAgentResult, ISendAgentSignalOptions, IAgentStatusOptions, IAgentState, IListAgentExecutionsOptions, IAgentExecutionListResult, IAgentTool, IAgentToolSchema, IToolParam, IToolCallResult, ILLMConfig, LLMProvider, IAgentMemoryConfig, IAgentTerminationConfig, IAgentStreamEvent, IAgentToolContext, IConversationMessage, ITokenUsage, AgentStatus, IHumanInLoopConfig, IApprovalRequest, IApprovalResponse, IMultiAgentWorkflow, MultiAgentMode, } from './agents';
237
237
  export { deriveDatabaseActionOutputContract, validateDatabaseActionOutput } from './database';
238
238
  export { AtomicBatchOptions, AtomicBatchOperation, AtomicBatchResult, AtomicBatchError } from './database/atomic-batch';
239
+ export type { IMongoPipelineOptions, IMongoPipelineResult } from './database/types/pipeline.interface';
240
+ export type { AtomicPipelineOptions, AtomicPipelineResult } from './database/atomic-pipeline';
241
+ export type { SqlContext } from './database/sql-context';
239
242
  export type { IActionResult, IQueryActionResult, IInsertActionResult, IUpdateActionResult, IDeleteActionResult, IRawActionResult, IDatabaseActionSchemaNode, IDatabaseActionOutputContract, IDatabaseActionOutputValidation, IDatabaseTableColumnMetadata, } from './database';
240
243
  export { StorageService, StorageError } from './storage';
241
244
  export { uploadBlobToCloud, downloadBlobFromCloud, deleteBlobFromCloud, listBlobsInCloud, generateSignedUrl, } from './storage';
@@ -1925,6 +1928,8 @@ export default class Ductape implements IDuctape {
1925
1928
  /**
1926
1929
  * Perform multiple aggregations in one query
1927
1930
  */
1931
+ aggregatePipeline: <T = Record<string, unknown>>(options: Parameters<DatabaseService["aggregatePipeline"]>[0]) => Promise<import("./database").IMongoPipelineResult<T>>;
1932
+ atomicPipeline: <T = Record<string, unknown>>(options: Parameters<DatabaseService["atomicPipeline"]>[0]) => Promise<import("./database/atomic-pipeline").AtomicPipelineResult<T>>;
1928
1933
  aggregate: (options: Parameters<DatabaseService["aggregate"]>[0]) => Promise<import("./database").IAggregateResult>;
1929
1934
  /**
1930
1935
  * Begin a database transaction
@@ -4408,7 +4413,7 @@ export default class Ductape implements IDuctape {
4408
4413
  refreshedAt?: number;
4409
4414
  error?: string;
4410
4415
  };
4411
- connections: "degraded" | "ready" | "warming";
4416
+ connections: "ready" | "warming" | "degraded";
4412
4417
  };
4413
4418
  warmup: {
4414
4419
  databases: {
package/dist/index.js CHANGED
@@ -2490,6 +2490,14 @@ class Ductape {
2490
2490
  /**
2491
2491
  * Perform multiple aggregations in one query
2492
2492
  */
2493
+ aggregatePipeline: async (options) => {
2494
+ const service = await this.createNewDatabaseService();
2495
+ return service.aggregatePipeline(options);
2496
+ },
2497
+ atomicPipeline: async (options) => {
2498
+ const service = await this.createNewDatabaseService();
2499
+ return service.atomicPipeline(options);
2500
+ },
2493
2501
  aggregate: async (options) => {
2494
2502
  const service = await this.createNewDatabaseService();
2495
2503
  return service.aggregate(options);