@venturekit/data 0.0.24 → 0.0.26

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/index.d.ts CHANGED
@@ -8,6 +8,6 @@ export { createRdsConfig, DEFAULT_RDS_CONFIG, buildRdsConfig, } from './rds/inde
8
8
  export type { RdsOutputs, RdsInfraConfig } from './rds/index.js';
9
9
  export { createMigrationConfig, DEFAULT_MIGRATION_CONFIG, getFlywayEnv, runMigrations, getMigrationStatus, runSeeds, getSeedStatus, MIGRATIONS_TRACKING_TABLE, SEEDS_TRACKING_TABLE, MigrationToolNotImplementedError, MigrationHashMismatchError, MigrationCollisionError, applyDatabaseUrlToEnv, } from './migrations/index.js';
10
10
  export type { RunResult, StatusEntry, RunOptions, SeedRunOptions, } from './migrations/index.js';
11
- export { query, getPool, mapResults, mapRow, configureMapper, getMapperConfig, beginTransaction, withTransaction, buildTransaction, applyDbSecretToEnv, TENANT_GUC, runWithTenant, runWithoutTenant, getCurrentTenantId, isTenancyEngaged, } from './query/index.js';
11
+ export { query, getPool, mapResults, mapRow, configureMapper, getMapperConfig, beginTransaction, withTransaction, buildTransaction, applyDbSecretToEnv, TENANT_GUC, TENANT_SCOPE_GUC, runWithTenant, runWithTenantScope, runWithoutTenant, getCurrentTenantId, getCurrentTenantScope, isTenancyEngaged, } from './query/index.js';
12
12
  export type { Transaction, ResultsMapper, Querier, MapperOptions, } from './query/index.js';
13
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKjE,OAAO,EAEL,qBAAqB,EACrB,wBAAwB,EACxB,YAAY,EAEZ,aAAa,EACb,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,yBAAyB,EACzB,oBAAoB,EAEpB,gCAAgC,EAChC,0BAA0B,EAC1B,uBAAuB,EAGvB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,SAAS,EACT,WAAW,EACX,UAAU,EACV,cAAc,GACf,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,KAAK,EACL,OAAO,EACP,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAKhB,kBAAkB,EAOlB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,WAAW,EACX,aAAa,EACb,OAAO,EACP,aAAa,GACd,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKjE,OAAO,EAEL,qBAAqB,EACrB,wBAAwB,EACxB,YAAY,EAEZ,aAAa,EACb,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,yBAAyB,EACzB,oBAAoB,EAEpB,gCAAgC,EAChC,0BAA0B,EAC1B,uBAAuB,EAGvB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,SAAS,EACT,WAAW,EACX,UAAU,EACV,cAAc,GACf,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,KAAK,EACL,OAAO,EACP,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAKhB,kBAAkB,EAUlB,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,WAAW,EACX,aAAa,EACb,OAAO,EACP,aAAa,GACd,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -31,7 +31,10 @@ applyDbSecretToEnv,
31
31
  // `runWithTenant(id, fn)` and every query inside it — pooled or
32
32
  // transactional — carries the `app.tenant_id` GUC, so RLS policies
33
33
  // enforce isolation the application SQL may have forgotten.
34
+ // `runWithTenantScope([parent, ...children], fn)` additionally
35
+ // publishes `app.tenant_ids` for hierarchies where one request may
36
+ // read several tenants.
34
37
  // See ./query/tenant.ts for the required policy shape and the
35
38
  // database-role split RLS depends on.
36
- TENANT_GUC, runWithTenant, runWithoutTenant, getCurrentTenantId, isTenancyEngaged, } from './query/index.js';
39
+ TENANT_GUC, TENANT_SCOPE_GUC, runWithTenant, runWithTenantScope, runWithoutTenant, getCurrentTenantId, getCurrentTenantScope, isTenancyEngaged, } from './query/index.js';
37
40
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAEjC,MAAM;AACN,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAGxB,uEAAuE;AACvE,iEAAiE;AACjE,gDAAgD;AAChD,OAAO;AACL,4BAA4B;AAC5B,qBAAqB,EACrB,wBAAwB,EACxB,YAAY;AACZ,sEAAsE;AACtE,aAAa,EACb,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,yBAAyB,EACzB,oBAAoB;AACpB,SAAS;AACT,gCAAgC,EAChC,0BAA0B,EAC1B,uBAAuB;AACvB,uEAAuE;AACvE,qEAAqE;AACrE,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAQ/B,kDAAkD;AAClD,OAAO,EACL,KAAK,EACL,OAAO,EACP,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB;AAChB,0DAA0D;AAC1D,mEAAmE;AACnE,iEAAiE;AACjE,gCAAgC;AAChC,kBAAkB;AAClB,2DAA2D;AAC3D,gEAAgE;AAChE,mEAAmE;AACnE,4DAA4D;AAC5D,8DAA8D;AAC9D,sCAAsC;AACtC,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAEjC,MAAM;AACN,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAGxB,uEAAuE;AACvE,iEAAiE;AACjE,gDAAgD;AAChD,OAAO;AACL,4BAA4B;AAC5B,qBAAqB,EACrB,wBAAwB,EACxB,YAAY;AACZ,sEAAsE;AACtE,aAAa,EACb,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,yBAAyB,EACzB,oBAAoB;AACpB,SAAS;AACT,gCAAgC,EAChC,0BAA0B,EAC1B,uBAAuB;AACvB,uEAAuE;AACvE,qEAAqE;AACrE,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAQ/B,kDAAkD;AAClD,OAAO,EACL,KAAK,EACL,OAAO,EACP,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB;AAChB,0DAA0D;AAC1D,mEAAmE;AACnE,iEAAiE;AACjE,gCAAgC;AAChC,kBAAkB;AAClB,2DAA2D;AAC3D,gEAAgE;AAChE,mEAAmE;AACnE,4DAA4D;AAC5D,+DAA+D;AAC/D,mEAAmE;AACnE,wBAAwB;AACxB,8DAA8D;AAC9D,sCAAsC;AACtC,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC"}
@@ -56,7 +56,7 @@ import type { ResultsMapper } from './transaction.js';
56
56
  export declare const DEFAULT_SLOW_QUERY_THRESHOLD_MS = 1000;
57
57
  export { getPool, applyDatabaseUrlToEnv } from './pool.js';
58
58
  export { applyDbSecretToEnv } from './secret.js';
59
- export { TENANT_GUC, runWithTenant, runWithoutTenant, getCurrentTenantId, isTenancyEngaged, } from './tenant.js';
59
+ export { TENANT_GUC, TENANT_SCOPE_GUC, runWithTenant, runWithTenantScope, runWithoutTenant, getCurrentTenantId, getCurrentTenantScope, isTenancyEngaged, } from './tenant.js';
60
60
  export { mapResults, mapRow, configureMapper, getMapperConfig, } from './mapper.js';
61
61
  export type { MapperOptions } from './mapper.js';
62
62
  export { beginTransaction, withTransaction, buildTransaction, } from './transaction.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAIH,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAKtD;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,OAAQ,CAAC;AAqBrD,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AA+B5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACvD,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,EAAE,EACvB,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EAChC,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CA6CZ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAIH,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAKtD;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,OAAQ,CAAC;AAqBrD,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AA+B5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACvD,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,EAAE,EACvB,aAAa,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,EAChC,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CA6CZ"}
@@ -77,7 +77,7 @@ function previewSql(sql) {
77
77
  }
78
78
  export { getPool, applyDatabaseUrlToEnv } from './pool.js';
79
79
  export { applyDbSecretToEnv } from './secret.js';
80
- export { TENANT_GUC, runWithTenant, runWithoutTenant, getCurrentTenantId, isTenancyEngaged, } from './tenant.js';
80
+ export { TENANT_GUC, TENANT_SCOPE_GUC, runWithTenant, runWithTenantScope, runWithoutTenant, getCurrentTenantId, getCurrentTenantScope, isTenancyEngaged, } from './tenant.js';
81
81
  export { mapResults, mapRow, configureMapper, getMapperConfig, } from './mapper.js';
82
82
  export { beginTransaction, withTransaction, buildTransaction, } from './transaction.js';
83
83
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAA8B,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,KAAK,CAAC;AAErD,SAAS,2BAA2B;IAClC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;IACnD,IAAI,CAAC,GAAG;QAAE,OAAO,+BAA+B,CAAC;IACjD,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,+BAA+B,CAAC;AAC5E,CAAC;AAED;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;AACrE,CAAC;AAED,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,OAAO,CACpB,IAAU,EACV,QAAgB,EAChB,WAAuB;IAEvB,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,QAAgB,EAChB,WAAuB,EACvB,aAAgC,EAChC,aAA6B;IAE7B,sEAAsE;IACtE,0EAA0E;IAC1E,8EAA8E;IAC9E,6CAA6C;IAC7C,MAAM,kBAAkB,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,GAAgB,CAAC;IACrB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,mEAAmE;QACnE,gEAAgE;QAChE,mEAAmE;QACnE,mEAAmE;QACnE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,GAA6D,CAAC;QAC7E,KAAK,CAAC,KAAK,CAAC,uBAAuB,EAAE;YACnC,UAAU;YACV,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC;YAChC,UAAU,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;YACpC,SAAS,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YACtD,YAAY,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YAC9D,MAAM,EAAE,MAAM,CAAC,IAAI;YACnB,UAAU,EAAE,MAAM,CAAC,QAAQ;YAC3B,SAAS,EAAE,MAAM,CAAC,OAAO;SAC1B,CAAC,CAAC;QACH,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAC1C,MAAM,MAAM,GAAG,2BAA2B,EAAE,CAAC;IAC7C,IAAI,MAAM,GAAG,CAAC,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,qBAAqB,EAAE;YAChC,UAAU;YACV,WAAW,EAAE,MAAM;YACnB,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM;YACzC,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IACnD,OAAO,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAsB,CAAC;AACxE,CAAC"}
@@ -35,6 +35,32 @@
35
35
  * this wrong (e.g. omit the NULLIF and cast `''::uuid`) and you
36
36
  * trade a leak for a runtime error on every unscoped query.
37
37
  *
38
+ * # Hierarchies: one request, several readable tenants
39
+ *
40
+ * Plenty of products let one tenant read others: a parent organization
41
+ * over its subsidiaries, a franchise group over its outlets, a reseller
42
+ * over the accounts it manages. A single-valued GUC cannot express that,
43
+ * and the usual workaround — dropping RLS for those requests and
44
+ * rebuilding the filter in application SQL — removes the guarantee
45
+ * exactly where the access rules are most intricate.
46
+ *
47
+ * {@link runWithTenantScope} therefore publishes a SECOND GUC,
48
+ * `app.tenant_ids`, holding every tenant the request may read. The
49
+ * first element is also published as `app.tenant_id`, so it remains the
50
+ * "acting" tenant that writes are attributed to.
51
+ *
52
+ * ```sql
53
+ * CREATE POLICY tenant_isolation ON posts
54
+ * USING (tenant_id::text = ANY (
55
+ * string_to_array(NULLIF(current_setting('app.tenant_ids', true), ''), ',')
56
+ * ));
57
+ * ```
58
+ *
59
+ * `string_to_array(NULL, ',')` is NULL and `x = ANY (NULL)` is NULL, so
60
+ * an unset GUC filters every row — the same fail-closed default as the
61
+ * single-tenant shape. {@link runWithTenant} sets both GUCs, so this one
62
+ * policy shape serves flat and hierarchical apps alike.
63
+ *
38
64
  * RLS does not apply to a table's OWNER unless `FORCE ROW LEVEL
39
65
  * SECURITY` is set, and is skipped entirely for roles with `BYPASSRLS`.
40
66
  * Run the application as a role that owns nothing and has neither
@@ -68,6 +94,13 @@ import type { PoolClient } from 'pg';
68
94
  * needed for the setting to exist.
69
95
  */
70
96
  export declare const TENANT_GUC = "app.tenant_id";
97
+ /**
98
+ * The GUC carrying every tenant readable by the current request, as a
99
+ * comma-separated list. Always a superset of {@link TENANT_GUC}: a flat
100
+ * {@link runWithTenant} scope publishes the single id here too, so a
101
+ * policy written against this GUC alone is correct in both cases.
102
+ */
103
+ export declare const TENANT_SCOPE_GUC = "app.tenant_ids";
71
104
  /** True once tenancy has been engaged. Read by `query()`. */
72
105
  export declare function isTenancyEngaged(): boolean;
73
106
  /**
@@ -75,6 +108,11 @@ export declare function isTenancyEngaged(): boolean;
75
108
  * scope / inside a {@link runWithoutTenant} block.
76
109
  */
77
110
  export declare function getCurrentTenantId(): string | null;
111
+ /**
112
+ * Every tenant readable in the current async scope, acting tenant
113
+ * first. Empty outside any scope / inside {@link runWithoutTenant}.
114
+ */
115
+ export declare function getCurrentTenantScope(): string[];
78
116
  /**
79
117
  * Run `fn` with `tenantId` applied to every query it issues.
80
118
  *
@@ -92,6 +130,29 @@ export declare function getCurrentTenantId(): string | null;
92
130
  * ```
93
131
  */
94
132
  export declare function runWithTenant<T>(tenantId: string, fn: () => Promise<T>): Promise<T>;
133
+ /**
134
+ * Run `fn` with a scope spanning SEVERAL tenants — a parent and its
135
+ * children, a group and its members.
136
+ *
137
+ * `tenantIds[0]` is the acting tenant: it is published as
138
+ * {@link TENANT_GUC}, so writes and audit stay attributed to one
139
+ * subject, while reads may span the whole list via
140
+ * {@link TENANT_SCOPE_GUC}.
141
+ *
142
+ * The caller owns the expansion. This module deliberately does not walk
143
+ * a hierarchy: which tenants a principal may read is an authorization
144
+ * decision, and inferring it from a table here would put that decision
145
+ * out of reach of review. Resolve the list once, from your own closure
146
+ * table or membership rows, then hand it over.
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * // A group administrator reads across the group's schools.
151
+ * const scope = [group.id, ...descendantIds];
152
+ * await runWithTenantScope(scope, async () => handler(body, ctx));
153
+ * ```
154
+ */
155
+ export declare function runWithTenantScope<T>(tenantIds: string[], fn: () => Promise<T>): Promise<T>;
95
156
  /**
96
157
  * Run `fn` with NO tenant applied, clearing any inherited scope.
97
158
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/query/tenant.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,UAAU,kBAAkB,CAAC;AAiC1C,6DAA6D;AAC7D,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAElD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CASnF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAGpE;AAaD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ3E;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
1
+ {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/query/tenant.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,UAAU,kBAAkB,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AA6CjD,6DAA6D;AAC7D,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAElD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CASnF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CA2B3F;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAGpE;AAkCD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB3E;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAShF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -35,6 +35,32 @@
35
35
  * this wrong (e.g. omit the NULLIF and cast `''::uuid`) and you
36
36
  * trade a leak for a runtime error on every unscoped query.
37
37
  *
38
+ * # Hierarchies: one request, several readable tenants
39
+ *
40
+ * Plenty of products let one tenant read others: a parent organization
41
+ * over its subsidiaries, a franchise group over its outlets, a reseller
42
+ * over the accounts it manages. A single-valued GUC cannot express that,
43
+ * and the usual workaround — dropping RLS for those requests and
44
+ * rebuilding the filter in application SQL — removes the guarantee
45
+ * exactly where the access rules are most intricate.
46
+ *
47
+ * {@link runWithTenantScope} therefore publishes a SECOND GUC,
48
+ * `app.tenant_ids`, holding every tenant the request may read. The
49
+ * first element is also published as `app.tenant_id`, so it remains the
50
+ * "acting" tenant that writes are attributed to.
51
+ *
52
+ * ```sql
53
+ * CREATE POLICY tenant_isolation ON posts
54
+ * USING (tenant_id::text = ANY (
55
+ * string_to_array(NULLIF(current_setting('app.tenant_ids', true), ''), ',')
56
+ * ));
57
+ * ```
58
+ *
59
+ * `string_to_array(NULL, ',')` is NULL and `x = ANY (NULL)` is NULL, so
60
+ * an unset GUC filters every row — the same fail-closed default as the
61
+ * single-tenant shape. {@link runWithTenant} sets both GUCs, so this one
62
+ * policy shape serves flat and hierarchical apps alike.
63
+ *
38
64
  * RLS does not apply to a table's OWNER unless `FORCE ROW LEVEL
39
65
  * SECURITY` is set, and is skipped entirely for roles with `BYPASSRLS`.
40
66
  * Run the application as a role that owns nothing and has neither
@@ -68,6 +94,19 @@ import { AsyncLocalStorage } from 'node:async_hooks';
68
94
  * needed for the setting to exist.
69
95
  */
70
96
  export const TENANT_GUC = 'app.tenant_id';
97
+ /**
98
+ * The GUC carrying every tenant readable by the current request, as a
99
+ * comma-separated list. Always a superset of {@link TENANT_GUC}: a flat
100
+ * {@link runWithTenant} scope publishes the single id here too, so a
101
+ * policy written against this GUC alone is correct in both cases.
102
+ */
103
+ export const TENANT_SCOPE_GUC = 'app.tenant_ids';
104
+ /**
105
+ * Separator for {@link TENANT_SCOPE_GUC}. A tenant id containing this
106
+ * character would split into two ids and silently widen the scope, so
107
+ * {@link runWithTenantScope} rejects such ids rather than encoding them.
108
+ */
109
+ const SCOPE_SEPARATOR = ',';
71
110
  /**
72
111
  * Value written when a scope is explicitly un-tenanted
73
112
  * ({@link runWithoutTenant}). The empty string — rather than
@@ -102,6 +141,13 @@ export function isTenancyEngaged() {
102
141
  export function getCurrentTenantId() {
103
142
  return storage.getStore()?.tenantId ?? null;
104
143
  }
144
+ /**
145
+ * Every tenant readable in the current async scope, acting tenant
146
+ * first. Empty outside any scope / inside {@link runWithoutTenant}.
147
+ */
148
+ export function getCurrentTenantScope() {
149
+ return storage.getStore()?.tenantIds ?? [];
150
+ }
105
151
  /**
106
152
  * Run `fn` with `tenantId` applied to every query it issues.
107
153
  *
@@ -124,7 +170,51 @@ export function runWithTenant(tenantId, fn) {
124
170
  'deliberately un-scoped work.');
125
171
  }
126
172
  engaged = true;
127
- return storage.run({ tenantId }, fn);
173
+ return storage.run({ tenantId, tenantIds: [tenantId] }, fn);
174
+ }
175
+ /**
176
+ * Run `fn` with a scope spanning SEVERAL tenants — a parent and its
177
+ * children, a group and its members.
178
+ *
179
+ * `tenantIds[0]` is the acting tenant: it is published as
180
+ * {@link TENANT_GUC}, so writes and audit stay attributed to one
181
+ * subject, while reads may span the whole list via
182
+ * {@link TENANT_SCOPE_GUC}.
183
+ *
184
+ * The caller owns the expansion. This module deliberately does not walk
185
+ * a hierarchy: which tenants a principal may read is an authorization
186
+ * decision, and inferring it from a table here would put that decision
187
+ * out of reach of review. Resolve the list once, from your own closure
188
+ * table or membership rows, then hand it over.
189
+ *
190
+ * @example
191
+ * ```ts
192
+ * // A group administrator reads across the group's schools.
193
+ * const scope = [group.id, ...descendantIds];
194
+ * await runWithTenantScope(scope, async () => handler(body, ctx));
195
+ * ```
196
+ */
197
+ export function runWithTenantScope(tenantIds, fn) {
198
+ if (tenantIds.length === 0) {
199
+ throw new Error('runWithTenantScope requires at least one tenantId. Use runWithoutTenant() for ' +
200
+ 'deliberately un-scoped work.');
201
+ }
202
+ for (const id of tenantIds) {
203
+ if (!id) {
204
+ throw new Error('runWithTenantScope requires non-empty tenant ids.');
205
+ }
206
+ if (id.includes(SCOPE_SEPARATOR)) {
207
+ // Encoding this would split one id into two and grant read access
208
+ // to a tenant nobody authorized.
209
+ throw new Error(`runWithTenantScope: tenant id ${JSON.stringify(id)} contains ${JSON.stringify(SCOPE_SEPARATOR)}, which is the scope separator.`);
210
+ }
211
+ }
212
+ // De-duplicate while preserving order so the acting tenant stays first
213
+ // and a caller passing [parent, ...children] that already contains the
214
+ // parent does not write it twice.
215
+ const unique = [...new Set(tenantIds)];
216
+ engaged = true;
217
+ return storage.run({ tenantId: unique[0], tenantIds: unique }, fn);
128
218
  }
129
219
  /**
130
220
  * Run `fn` with NO tenant applied, clearing any inherited scope.
@@ -141,7 +231,18 @@ export function runWithTenant(tenantId, fn) {
141
231
  */
142
232
  export function runWithoutTenant(fn) {
143
233
  engaged = true;
144
- return storage.run({ tenantId: null }, fn);
234
+ return storage.run({ tenantId: null, tenantIds: [] }, fn);
235
+ }
236
+ /**
237
+ * The pair of values to publish for the current scope. Both are written
238
+ * together so a connection can never carry one request's acting tenant
239
+ * beside another's readable set.
240
+ */
241
+ function currentGucValues() {
242
+ return {
243
+ tenant: getCurrentTenantId() ?? NO_TENANT,
244
+ scope: getCurrentTenantScope().join(SCOPE_SEPARATOR),
245
+ };
145
246
  }
146
247
  /**
147
248
  * Last value applied to each physical connection.
@@ -153,6 +254,14 @@ export function runWithoutTenant(fn) {
153
254
  * the GUC.
154
255
  */
155
256
  const appliedByClient = new WeakMap();
257
+ /**
258
+ * Memo key for the applied pair. `\u0000` cannot appear in either value
259
+ * (Postgres rejects NUL in text, and the scope separator is a comma), so
260
+ * distinct pairs cannot collide onto one key.
261
+ */
262
+ function memoKey(tenant, scope) {
263
+ return `${tenant}\u0000${scope}`;
264
+ }
156
265
  /**
157
266
  * Ensure `client`'s session GUC matches the current scope, issuing
158
267
  * `set_config` only when it differs.
@@ -162,13 +271,21 @@ const appliedByClient = new WeakMap();
162
271
  * only injection-safe way to write one.
163
272
  */
164
273
  export async function applyTenantToClient(client) {
165
- const want = getCurrentTenantId() ?? NO_TENANT;
274
+ const { tenant, scope } = currentGucValues();
275
+ const want = memoKey(tenant, scope);
166
276
  if (appliedByClient.get(client) === want)
167
277
  return;
168
278
  // Record BEFORE awaiting: a rejected set_config must not leave the
169
279
  // memo claiming a value the server never accepted.
170
280
  appliedByClient.delete(client);
171
- await client.query(`SELECT set_config($1, $2, false)`, [TENANT_GUC, want]);
281
+ // One statement, so the acting tenant and the readable set can never
282
+ // be left half-applied by a connection dropped between two queries.
283
+ await client.query(`SELECT set_config($1, $2, false), set_config($3, $4, false)`, [
284
+ TENANT_GUC,
285
+ tenant,
286
+ TENANT_SCOPE_GUC,
287
+ scope,
288
+ ]);
172
289
  appliedByClient.set(client, want);
173
290
  }
174
291
  /**
@@ -184,8 +301,13 @@ export async function applyTenantToClient(client) {
184
301
  export async function applyTenantToTransaction(client) {
185
302
  if (!engaged)
186
303
  return;
187
- const want = getCurrentTenantId() ?? NO_TENANT;
188
- await client.query(`SELECT set_config($1, $2, true)`, [TENANT_GUC, want]);
304
+ const { tenant, scope } = currentGucValues();
305
+ await client.query(`SELECT set_config($1, $2, true), set_config($3, $4, true)`, [
306
+ TENANT_GUC,
307
+ tenant,
308
+ TENANT_SCOPE_GUC,
309
+ scope,
310
+ ]);
189
311
  }
190
312
  /**
191
313
  * Reset module state. Test-only — production code has no reason to
@@ -1 +1 @@
1
- {"version":3,"file":"tenant.js","sourceRoot":"","sources":["../../src/query/tenant.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,eAAe,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,SAAS,GAAG,EAAE,CAAC;AAOrB,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAe,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB,6DAA6D;AAC7D,MAAM,UAAU,gBAAgB;IAC9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,QAAQ,EAAE,EAAE,QAAQ,IAAI,IAAI,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAAI,QAAgB,EAAE,EAAoB;IACrE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,0EAA0E;YACxE,8BAA8B,CACjC,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,IAAI,CAAC;IACf,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAI,EAAoB;IACtD,OAAO,GAAG,IAAI,CAAC;IACf,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,eAAe,GAAG,IAAI,OAAO,EAAsB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAkB;IAC1D,MAAM,IAAI,GAAG,kBAAkB,EAAE,IAAI,SAAS,CAAC;IAC/C,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI;QAAE,OAAO;IACjD,mEAAmE;IACnE,mDAAmD;IACnD,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3E,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAkB;IAC/D,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,IAAI,GAAG,kBAAkB,EAAE,IAAI,SAAS,CAAC;IAC/C,MAAM,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,GAAG,KAAK,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"tenant.js","sourceRoot":"","sources":["../../src/query/tenant.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,eAAe,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B;;;;;;GAMG;AACH,MAAM,SAAS,GAAG,EAAE,CAAC;AAYrB,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAe,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB,6DAA6D;AAC7D,MAAM,UAAU,gBAAgB;IAC9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,OAAO,CAAC,QAAQ,EAAE,EAAE,QAAQ,IAAI,IAAI,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,IAAI,EAAE,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAAI,QAAgB,EAAE,EAAoB;IACrE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,0EAA0E;YACxE,8BAA8B,CACjC,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,IAAI,CAAC;IACf,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,kBAAkB,CAAI,SAAmB,EAAE,EAAoB;IAC7E,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,gFAAgF;YAC9E,8BAA8B,CACjC,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YACjC,kEAAkE;YAClE,iCAAiC;YACjC,MAAM,IAAI,KAAK,CACb,iCAAiC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,aAAa,IAAI,CAAC,SAAS,CAC5E,eAAe,CAChB,iCAAiC,CACnC,CAAC;QACJ,CAAC;IACH,CAAC;IACD,uEAAuE;IACvE,uEAAuE;IACvE,kCAAkC;IAClC,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IACvC,OAAO,GAAG,IAAI,CAAC;IACf,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAW,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAI,EAAoB;IACtD,OAAO,GAAG,IAAI,CAAC;IACf,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB;IACvB,OAAO;QACL,MAAM,EAAE,kBAAkB,EAAE,IAAI,SAAS;QACzC,KAAK,EAAE,qBAAqB,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC;KACrD,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,eAAe,GAAG,IAAI,OAAO,EAAsB,CAAC;AAE1D;;;;GAIG;AACH,SAAS,OAAO,CAAC,MAAc,EAAE,KAAa;IAC5C,OAAO,GAAG,MAAM,SAAS,KAAK,EAAE,CAAC;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAkB;IAC1D,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACpC,IAAI,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI;QAAE,OAAO;IACjD,mEAAmE;IACnE,mDAAmD;IACnD,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,qEAAqE;IACrE,oEAAoE;IACpE,MAAM,MAAM,CAAC,KAAK,CAAC,6DAA6D,EAAE;QAChF,UAAU;QACV,MAAM;QACN,gBAAgB;QAChB,KAAK;KACN,CAAC,CAAC;IACH,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAkB;IAC/D,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,KAAK,CAAC,2DAA2D,EAAE;QAC9E,UAAU;QACV,MAAM;QACN,gBAAgB;QAChB,KAAK;KACN,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,GAAG,KAAK,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@venturekit/data",
3
- "version": "0.0.24",
3
+ "version": "0.0.26",
4
4
  "description": "Database and data layer for VentureKit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@aws-sdk/client-secrets-manager": "^3.1091.0",
33
- "@venturekit/core": "0.0.24",
33
+ "@venturekit/core": "0.0.26",
34
34
  "pg": "^8.12.0"
35
35
  },
36
36
  "devDependencies": {