@fabricorg/databricks-testkit 0.1.0 → 0.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/index.cjs +179 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -5
- package/dist/index.d.ts +39 -5
- package/dist/index.js +174 -19
- package/dist/index.js.map +1 -1
- package/package.json +12 -14
- package/LICENSE +0 -21
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context.ts","../src/assert.ts","../src/mock-client.ts","../src/live-suite.ts","../src/pollers.ts","../src/live-checks.ts","../src/lakebase-checks.ts","../src/databricks-http.ts","../src/platform-checks.ts","../src/volume-checks.ts","../src/autoloader-checks.ts"],"names":["createDuckDbContext","createWorkspaceContext","required","resolve","randomUUID"],"mappings":";;;;;;;;;;;;;;AAwBO,SAAS,cAAA,CAAe,GAAA,GAA0C,OAAA,CAAQ,GAAA,EAAkB;AACjG,EAAA,MAAM,OAAA,GAAU,IAAI,gBAAA,IAAoB,OAAA;AACxC,EAAA,IAAI,OAAA,KAAY,OAAA,IAAW,OAAA,KAAY,MAAA,EAAQ;AAC7C,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iDAAA,EAAoD,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,EAChF;AACA,EAAA,IAAI,OAAA,KAAY,MAAA,IAAU,GAAA,CAAI,aAAA,KAAkB,GAAA,EAAK;AACnD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAYA,eAAsB,sBAAA,CACpB,OAAA,GAAgC,EAAC,EACN;AAC3B,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,IAAO,OAAA,CAAQ,GAAA;AACnC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,cAAA,CAAe,GAAG,CAAA;AACrD,EAAA,IAAI,YAAY,OAAA,EAAS;AACvB,IAAA,MAAM,EAAE,mBAAA,EAAAA,oBAAAA,EAAoB,GAAI,MAAM,OAAO,8BAAqB,CAAA;AAClE,IAAA,OAAOA,oBAAAA,CAAoB,EAAE,MAAA,EAAQ,OAAA,CAAQ,QAAQ,CAAA;AAAA,EACvD;AACA,EAAA,MAAM,EAAE,sBAAA,EAAAC,uBAAAA,EAAuB,GAAI,MAAM,OAAO,iCAAwB,CAAA;AACxE,EAAA,OAAOA,uBAAAA,CAAuB;AAAA,IAC5B,GAAA;AAAA,IACA,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,GAAI,QAAQ,WAAA,GAAc,EAAE,aAAa,OAAA,CAAQ,WAAA,KAAgB;AAAC,GACnE,CAAA;AACH;;;ACvDO,SAAS,WAAA,CAAY,KAAuB,KAAA,EAAe;AAChE,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,IAAA,CAAK,KAAK,CAAA;AAC7B,EAAA,OAAO;AAAA,IACL,MAAM,eAAe,QAAA,EAAiC;AACpD,MAAA,MAAM,OAAO,MAAM,GAAA,CAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,MAAM,CAAA,CAAE,CAAA;AAClE,MAAA,MAAM,SAAS,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,IAAK,OAAO,GAAG,CAAA;AAC9C,MAAA,IAAI,WAAW,QAAA,EAAU;AACvB,QAAA,MAAM,IAAI,MAAM,CAAA,SAAA,EAAY,MAAM,YAAY,QAAQ,CAAA,aAAA,EAAgB,MAAM,CAAA,CAAE,CAAA;AAAA,MAChF;AAAA,IACF,CAAA;AAAA;AAAA,IAGA,MAAM,cAAc,QAAA,EAA6D;AAC/E,MAAA,MAAM,OAAO,MAAM,GAAA,CAAI,KAAA,CAAM,CAAA,cAAA,EAAiB,MAAM,CAAA,CAAE,CAAA;AACtD,MAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,QAAA,MAAM,MAAM,IAAA,CAAK,IAAA;AAAA,UAAK,CAAC,GAAA,KACrB,MAAA,CAAO,OAAA,CAAQ,OAAO,EAAE,KAAA,CAAM,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM,YAAA,CAAa,IAAI,GAAG,CAAA,EAAG,KAAK,CAAC;AAAA,SAC/E;AACA,QAAA,IAAI,CAAC,GAAA,EAAK;AACR,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,CAAA,SAAA,EAAY,MAAM,CAAA,2BAAA,EAA8B,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA,OAAA,EAC7D,IAAA,CAAK,MAAM,CAAA,OAAA,EAAU,IAAA,CAAK,UAAU,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAC,GAAG,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,SAAA,GAAO,EAAE,CAAA;AAAA,WAC/F;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA,MAAM,aAAA,CAAc,UAAA,EAAoB,OAAA,GAAgC,EAAC,EAAkB;AACzF,MAAA,MAAM,UAAU,OAAA,CAAQ,OAAA,GAAU,CAAA,UAAA,EAAa,OAAA,CAAQ,OAAO,CAAA,CAAA,GAAK,EAAA;AACnE,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,KAAA,CAAM,iBAAiB,MAAM,CAAA,EAAG,OAAO,CAAA,CAAE,CAAA;AAChE,MAAA,MAAM,eAAA,CAAgB,UAAA,EAAY,IAAA,EAAM,CAAA,MAAA,EAAS,MAAM,CAAA,CAAE,CAAA;AAAA,IAC3D;AAAA,GACF;AACF;AAGA,eAAsB,wBAAA,CACpB,GAAA,EACA,GAAA,EACA,MAAA,EACA,UAAA,EACe;AACf,EAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,KAAA,CAAM,KAAK,MAAM,CAAA;AACxC,EAAA,MAAM,eAAA,CAAgB,UAAA,EAAY,IAAA,EAAM,OAAO,CAAA;AACjD;AAEA,SAAS,YAAA,CAAa,GAAY,CAAA,EAAqB;AACrD,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,IAAA;AACpB,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA,GAAI,IAAA;AAE7E,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,MAAM,QAAA,EAAU;AAClD,IAAA,OACE,EAAE,OAAA,CAAQ,GAAA,EAAK,GAAG,CAAA,CAAE,QAAQ,aAAA,EAAe,EAAE,CAAA,KAC7C,CAAA,CAAE,QAAQ,GAAA,EAAK,GAAG,CAAA,CAAE,OAAA,CAAQ,eAAe,EAAE,CAAA;AAAA,EAEjD;AACA,EAAA,OAAO,KAAA;AACT;;;ACtCO,SAAS,0BAAA,GAAmD;AACjE,EAAA,MAAM,SAA2C,EAAE,GAAA,EAAK,EAAC,EAAG,IAAA,EAAM,EAAC,EAAE;AACrE,EAAA,MAAM,QAAwB,EAAC;AAE/B,EAAA,SAAS,IAAA,CAAK,QAAwB,IAAA,EAAsB;AAC1D,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,MAAM,CAAA,CAAE,SAAA,CAAU,CAAC,CAAA,KAAM,IAAA,CAAK,UAAA,CAAW,CAAA,CAAE,UAAU,CAAC,CAAA;AAC3E,IAAA,IAAI,UAAU,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,mCAAmC,MAAM,CAAA,cAAA,EAAiB,IAAI,CAAA,mBAAA,EACxC,OAAO,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,UAAU,EAAE,IAAA,CAAK,IAAI,KAAK,QAAQ,CAAA;AAAA,OACtF;AAAA,IACF;AACA,IAAA,OAAO,OAAO,MAAM,CAAA,CAAE,OAAO,KAAA,EAAO,CAAC,EAAE,CAAC,CAAA;AAAA,EAC1C;AAEA,EAAA,MAAM,MAAA,GAA+B;AAAA,IACnC,MAAM,GAAA,CAAO,IAAA,EAAc,KAAA,EAA+D;AACxF,MAAA,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAM,OAAO,CAAA;AACzC,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA;AAC/B,MAAA,IAAI,MAAA,CAAO,KAAA,EAAO,MAAM,MAAA,CAAO,KAAA;AAC/B,MAAA,OAAO,MAAA,CAAO,QAAA;AAAA,IAChB,CAAA;AAAA,IACA,MAAM,IAAA,CACJ,IAAA,EACA,IAAA,EACA,KAAA,EACA;AACA,MAAA,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,QAAQ,IAAA,EAAM,IAAA,EAAM,OAAO,CAAA;AAChD,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,EAAQ,IAAI,CAAA;AAChC,MAAA,IAAI,MAAA,CAAO,KAAA,EAAO,MAAM,MAAA,CAAO,KAAA;AAC/B,MAAA,OAAO,MAAA,CAAO,QAAA;AAAA,IAChB,CAAA;AAAA,IACA,KAAA,CAAM,MAAA,EAAQ,UAAA,EAAY,QAAA,EAAU;AAClC,MAAA,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK,EAAE,UAAA,EAAY,UAAU,CAAA;AAC5C,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,UAAA,CAAW,MAAA,EAAQ,UAAA,EAAY,KAAA,EAAO;AACpC,MAAA,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK,EAAE,UAAA,EAAY,OAAO,CAAA;AACzC,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAA,CAAQ,QAAQ,UAAA,EAAY;AAC1B,MAAA,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,KAAW,MAAA,IAAU,CAAA,CAAE,IAAA,CAAK,UAAA,CAAW,UAAU,CAAC,CAAA;AAAA,IACjF;AAAA,GACF;AACA,EAAA,OAAO,MAAA;AACT;ACbO,SAAS,gBAAgB,IAAA,EAAuC;AACrE,EAAA,OAAO,EAAE,GAAA,EAAK,CAAC,YAAY,YAAA,CAAa,IAAA,EAAM,OAAO,CAAA,EAAE;AACzD;AAEA,eAAsB,YAAA,CACpB,IAAA,EACA,OAAA,GAA4B,EAAC,EACM;AACnC,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,IAAO,OAAA,CAAQ,GAAA;AAChC,EAAA,IAAI,GAAA,CAAI,aAAA,KAAkB,GAAA,EAAK,OAAO,MAAA;AAEtC,EAAA,MAAMC,YAAW,CAAC,GAAI,IAAA,CAAK,QAAA,IAAY,EAAG,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,IAAA,CAAK,MAAA,CAAO,IAAI,CAAC,KAAA,KAAU,KAAA,CAAM,EAAE,CAAC,CAAA;AAC1D,EAAA,KAAA,MAAW,MAAMA,SAAAA,EAAU;AACzB,IAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA,QAAS,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,EAAE,CAAA,gBAAA,CAAkB,CAAA;AAAA,EAClF;AAEA,EAAA,MAAM,SAAA,GAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACzC,EAAA,MAAM,cAAA,GAAiB,QAAQ,SAAA,KAAc,MAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,IAAU,mBAAA,CAAoB,GAAG,CAAA;AACxD,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAc,MAAM,uBAAuB,EAAE,GAAA,EAAK,QAAQ,CAAA;AACpF,EAAA,MAAM,UAA6B,EAAC;AAEpC,EAAA,IAAI;AACF,IAAA,KAAA,MAAW,KAAA,IAAS,KAAK,MAAA,EAAQ;AAC/B,MAAA,IAAI,MAAM,UAAA,IAAc,CAAC,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,EAAG;AAC9C,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,IAAI,KAAA,CAAM,EAAA;AAAA,UACV,aAAa,KAAA,CAAM,WAAA;AAAA,UACnB,MAAA,EAAQ,gBAAA;AAAA,UACR,UAAA,EAAY;AAAA,SACb,CAAA;AACD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,MAAA,GAAS,YAAY,GAAA,EAAI;AAC/B,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAU,MAAM,KAAA,CAAM,GAAA,CAAI,EAAE,GAAA,EAAK,SAAA,EAAW,QAAQ,CAAA;AAC1D,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,IAAI,KAAA,CAAM,EAAA;AAAA,UACV,aAAa,KAAA,CAAM,WAAA;AAAA,UACnB,MAAA,EAAQ,MAAA;AAAA,UACR,YAAY,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,GAAA,KAAQ,MAAM,CAAA;AAAA,UACjD,GAAI,OAAA,KAAY,KAAA,CAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAS,WAAA,CAAY,OAAA,EAAS,GAAG,CAAA;AAAE,SACvE,CAAA;AAAA,MACH,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,UACX,IAAI,KAAA,CAAM,EAAA;AAAA,UACV,aAAa,KAAA,CAAM,WAAA;AAAA,UACnB,MAAA,EAAQ,MAAA;AAAA,UACR,YAAY,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,GAAA,KAAQ,MAAM,CAAA;AAAA,UACjD,KAAA,EAAO,WAAW,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAA,EAAG,GAAG;AAAA,SAC9E,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAA,SAAE;AACA,IAAA,IAAI,cAAA,EAAgB,MAAM,SAAA,CAAU,KAAA,EAAM;AAAA,EAC5C;AAEA,EAAA,MAAM,UAAUA,SAAAA,CAAS,KAAA;AAAA,IACvB,CAAC,EAAA,KAAO,OAAA,CAAQ,IAAA,CAAK,CAAC,WAAW,MAAA,CAAO,EAAA,KAAO,EAAE,CAAA,EAAG,MAAA,KAAW;AAAA,GACjE;AACA,EAAA,MAAM,QAAA,GAAyB;AAAA,IAC7B,aAAA,EAAe,CAAA;AAAA,IACf,IAAA,EAAM,uBAAA;AAAA,IACN,SAAA;AAAA,IACA,UAAA,EAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,IACnC,OAAA;AAAA,IACA,QAAA,EAAAA,SAAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,IAAI,IAAA,CAAK,YAAA;AACP,IAAA,MAAM,WAAA,CAAY,KAAK,YAAA,EAAc,CAAA,EAAG,KAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAC;AAAA,CAAI,CAAA;AAC/E,EAAA,IAAI,IAAA,CAAK,WAAW,MAAM,WAAA,CAAY,KAAK,SAAA,EAAW,WAAA,CAAY,QAAQ,CAAC,CAAA;AAC3E,EAAA,OAAO,QAAA;AACT;AAEA,eAAe,WAAA,CAAY,MAAc,QAAA,EAAiC;AACxE,EAAA,MAAM,MAAM,OAAA,CAAQ,IAAI,GAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC9C,EAAA,MAAM,SAAA,CAAU,IAAA,EAAM,QAAA,EAAU,MAAM,CAAA;AACxC;AAEA,SAAS,UAAA,CAAW,MAAc,GAAA,EAAiD;AACjF,EAAA,IAAI,MAAA,GAAS,IAAA;AACb,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC/C,IAAA,IAAI,CAAC,SAAS,KAAA,CAAM,MAAA,GAAS,KAAK,CAAC,qCAAA,CAAsC,IAAA,CAAK,IAAI,CAAA,EAAG;AACrF,IAAA,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,CAAE,KAAK,YAAY,CAAA;AAAA,EAChD;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,WAAA,CAAY,OAAgB,GAAA,EAAkD;AACrF,EAAA,OAAO,IAAA,CAAK,MAAM,UAAA,CAAW,IAAA,CAAK,UAAU,KAAK,CAAA,EAAG,GAAG,CAAC,CAAA;AAC1D;AAEA,SAAS,IAAI,KAAA,EAAuB;AAClC,EAAA,OAAO,MACJ,UAAA,CAAW,GAAA,EAAK,OAAO,CAAA,CACvB,UAAA,CAAW,KAAK,MAAM,CAAA,CACtB,WAAW,GAAA,EAAK,MAAM,EACtB,UAAA,CAAW,GAAA,EAAK,QAAQ,CAAA,CACxB,UAAA,CAAW,KAAK,QAAQ,CAAA;AAC7B;AAEO,SAAS,YAAY,QAAA,EAAgC;AAC1D,EAAA,MAAM,QAAA,GAAW,SAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAA,KAAW,MAAA,CAAO,MAAA,KAAW,MAAM,CAAA,CAAE,MAAA;AAC/E,EAAA,MAAM,OAAA,GAAU,SAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,MAAA,KAAW,MAAA,CAAO,MAAA,KAAW,gBAAgB,CAAA,CAAE,MAAA;AACxF,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,OAAA,CAAQ,MAAA,CAAO,CAAC,GAAA,EAAK,MAAA,KAAW,GAAA,GAAM,MAAA,CAAO,UAAA,EAAY,CAAC,CAAA,GAAI,GAAA;AACvF,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,OAAA,CACpB,GAAA,CAAI,CAAC,MAAA,KAAW;AACf,IAAA,MAAM,IAAA,GACJ,MAAA,CAAO,MAAA,KAAW,MAAA,GACd,qBAAqB,GAAA,CAAI,MAAA,CAAO,KAAA,IAAS,cAAc,CAAC,CAAA,GAAA,CAAA,GACxD,MAAA,CAAO,MAAA,KAAW,mBAChB,qCAAA,GACA,EAAA;AACR,IAAA,OAAO,CAAA,8CAAA,EAAiD,GAAA,CAAI,MAAA,CAAO,EAAE,CAAC,WAAW,MAAA,CAAO,UAAA,GAAa,GAAI,CAAA,EAAA,EAAK,IAAI,CAAA,WAAA,CAAA;AAAA,EACpH,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACZ,EAAA,OAAO,CAAA;AAAA,yCAAA,EAAoF,QAAA,CAAS,QAAQ,MAAM,CAAA,YAAA,EAAe,QAAQ,CAAA,WAAA,EAAc,OAAO,WAAW,OAAO,CAAA;AAAA,EAAO,KAAK;AAAA;AAAA,CAAA;AAC9L;;;AChLA,IAAM,2CAA2B,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,QAAA,EAAU,UAAU,CAAC,CAAA;AAE5E,eAAsB,sBACpB,MAAA,EACA,UAAA,EACA,QAAA,EACA,OAAA,GAAuB,EAAC,EACU;AAClC,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,IAAK,QAAQ,SAAA,IAAa,GAAA,CAAA;AACpD,EAAA,MAAM,QAAA,GAAW,QAAQ,cAAA,IAAkB,GAAA;AAC3C,EAAA,MAAM,IAAA,GAAO,sBAAsB,kBAAA,CAAmB,UAAU,CAAC,CAAA,SAAA,EAAY,kBAAA,CAAmB,QAAQ,CAAC,CAAA,CAAA;AACzG,EAAA,IAAI,MAAA,GAA0C,MAAM,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AACnE,EAAA,OAAO,CAAC,wBAAA,CAAyB,GAAA,CAAI,MAAA,CAAO,MAAA,EAAQ,KAAA,IAAS,EAAE,CAAA,IAAK,IAAA,CAAK,GAAA,EAAI,GAAI,QAAA,EAAU;AACzF,IAAA,IAAI,OAAA,CAAQ,QAAQ,OAAA,EAAS,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,QAAQ,CAAA,YAAA,CAAc,CAAA;AACtF,IAAA,MAAM,cAAA,CAAe,QAAA,EAAU,OAAA,CAAQ,MAAM,CAAA;AAC7C,IAAA,MAAA,GAAS,MAAM,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AAAA,EAChC;AACA,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,MAAA,EAAQ,KAAA,IAAS,SAAA;AACtC,EAAA,IAAI,UAAU,WAAA,EAAa;AACzB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,QAAQ,CAAA,UAAA,EAAa,KAAK,CAAA,mBAAA,CAAqB,CAAA;AAAA,EACpF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,cAAA,CAAe,IAAY,MAAA,EAAqC;AACvE,EAAA,OAAO,IAAI,OAAA,CAAQ,CAACC,QAAAA,EAAS,MAAA,KAAW;AACtC,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,iBAAiB,CAAC,CAAA;AACnC,MAAA;AAAA,IACF;AACA,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAWA,QAAAA,EAAS,EAAE,CAAA;AACpC,IAAA,MAAA,EAAQ,gBAAA;AAAA,MACN,OAAA;AAAA,MACA,MAAM;AACJ,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,iBAAiB,CAAC,CAAA;AAAA,MACrC,CAAA;AAAA,MACA,EAAE,MAAM,IAAA;AAAK,KACf;AAAA,EACF,CAAC,CAAA;AACH;;;AC5CO,SAAS,iBAAA,GAA+B;AAC7C,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,KAAA;AAAA,IACJ,WAAA,EAAa,oCAAA;AAAA,IACb,MAAM,GAAA,CAAI,EAAE,SAAA,EAAU,EAAG;AACvB,MAAA,MAAM,IAAA,GAAO,MAAM,SAAA,CAAU,KAAA,CAAM,yBAAyB,CAAA;AAC5D,MAAA,IAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,WAAW,CAAA,KAAM,CAAA;AACnC,QAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAC/D,MAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,MAAA,EAAO;AAAA,IAC7B;AAAA,GACF;AACF;AAOO,SAAS,mBAAA,CACd,KAAA,EACA,IAAA,EACA,OAAA,EACM;AACN,EAAA,KAAA,MAAW,YAAY,OAAA,EAAS;AAC9B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,CAAC,GAAA,KAAQ,MAAA,CAAO,GAAA,CAAI,QAAA,IAAY,GAAA,CAAI,WAAW,CAAA,KAAM,QAAA,CAAS,IAAI,CAAA;AAC3F,IAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,KAAA,CAAM,kCAAkC,QAAA,CAAS,IAAI,CAAA,KAAA,EAAQ,KAAK,CAAA,CAAE,CAAA;AAC3F,IAAA,MAAM,UAAA,GAAa,OAAO,MAAA,CAAO,SAAA,IAAa,OAAO,WAAA,IAAe,EAAE,EAAE,WAAA,EAAY;AACpF,IAAA,IAAI,SAAS,IAAA,IAAQ,UAAA,KAAe,QAAA,CAAS,IAAA,CAAK,aAAY,EAAG;AAC/D,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,gBAAgB,QAAA,CAAS,IAAI,aAAa,UAAU,CAAA,WAAA,EAAc,SAAS,IAAI,CAAA;AAAA,OACjF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,kBAAA,CACd,QAAA,GAAW,sBAAA,EACX,OAAA,GAA0C,EAAC,EAChC;AACX,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,gBAAA;AAAA,IACJ,WAAA,EAAa,6BAAA;AAAA,IACb,YAAY,CAAC,GAAA,KAAQ,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAC,CAAA;AAAA,IAC1C,MAAM,GAAA,CAAI,EAAE,GAAA,EAAK,WAAU,EAAG;AAC5B,MAAA,MAAM,KAAA,GAAQ,IAAI,QAAQ,CAAA;AAC1B,MAAA,MAAM,OAAO,MAAM,SAAA,CAAU,KAAA,CAAM,CAAA,eAAA,EAAkB,KAAK,CAAA,CAAE,CAAA;AAC5D,MAAA,mBAAA,CAAoB,KAAA,EAAO,MAAM,OAAO,CAAA;AACxC,MAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,IAAA,CAAK,MAAA,EAAO;AAAA,IACvC;AAAA,GACF;AACF;AAEO,SAAS,uBAAA,GAAqC;AACnD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,WAAA;AAAA,IACJ,WAAA,EAAa,4CAAA;AAAA,IACb,YAAY,CAAC,GAAA,KAAQ,QAAQ,GAAA,CAAI,yBAAA,IAA6B,IAAI,wBAAwB,CAAA;AAAA,IAC1F,MAAM,GAAA,CAAI,EAAE,GAAA,EAAK,WAAU,EAAG;AAC5B,MAAA,MAAM,SAAA,CAAU,KAAA,CAAM,CAAA,cAAA,EAAiB,GAAA,CAAI,yBAAyB,CAAA,QAAA,CAAU,CAAA;AAC9E,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,CAAU,KAAA,CAAM,CAAA,cAAA,EAAiB,GAAA,CAAI,wBAAwB,CAAA,QAAA,CAAU,CAAA;AAAA,MAC/E,SAAS,KAAA,EAAO;AACd,QAAA,IAAI,uDAAA,CAAwD,IAAA,CAAK,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG;AAC/E,UAAA,OAAO,EAAE,OAAA,EAAS,GAAA,CAAI,yBAAA,EAA2B,MAAA,EAAQ,IAAI,wBAAA,EAAyB;AAAA,QACxF;AACA,QAAA,MAAM,KAAA;AAAA,MACR;AACA,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,GAAA,CAAI,wBAAwB,CAAA,aAAA,CAAe,CAAA;AAAA,IACnF;AAAA,GACF;AACF;AAEO,SAAS,WAAA,GAAyB;AACvC,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,MAAA;AAAA,IACJ,WAAA,EAAa,wCAAA;AAAA,IACb,UAAA,EAAY,CAAC,GAAA,KAAQ,OAAA,CAAQ,IAAI,eAAe,CAAA;AAAA,IAChD,MAAM,GAAA,CAAI,EAAE,GAAA,EAAK,QAAO,EAAG;AACzB,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,eAAe,CAAA;AACxC,MAAA,IAAI,CAAC,OAAO,QAAA,CAAS,KAAK,GAAG,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAC9E,MAAA,MAAM,SAAA,GAAY,MAAM,MAAA,CAAO,IAAA,CAAyB,uBAAA,EAAyB;AAAA,QAC/E,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA,MAAM,GAAA,GAAM,MAAM,oBAAA,CAAqB,MAAA,EAAiB,UAAU,MAAA,EAAQ;AAAA,QACxE,SAAA,EAAW,MAAA,CAAO,GAAA,CAAI,mBAAA,IAAuB,GAAO,CAAA;AAAA,QACpD,cAAA,EAAgB,MAAA,CAAO,GAAA,CAAI,yBAAA,IAA6B,GAAM;AAAA,OAC/D,CAAA;AACD,MAAA,MAAM,MAAA,GAAU,IAA8C,KAAA,EAAO,YAAA;AACrE,MAAA,IAAI,MAAA,KAAW,SAAA,EAAW,MAAM,IAAI,KAAA,CAAM,OAAO,KAAK,CAAA,UAAA,EAAa,MAAA,IAAU,SAAS,CAAA,CAAE,CAAA;AACxF,MAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,SAAA,CAAU,MAAA,EAAO;AAAA,IAC1C;AAAA,GACF;AACF;AAGO,SAAS,oBAAA,GAAkC;AAChD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,UAAA;AAAA,IACJ,WAAA,EAAa,uDAAA;AAAA,IACb,UAAA,EAAY,CAAC,GAAA,KAAQ,OAAA,CAAQ,IAAI,oBAAoB,CAAA;AAAA,IACrD,MAAM,GAAA,CAAI,EAAE,GAAA,EAAK,QAAO,EAAG;AACzB,MAAA,MAAM,aAAa,GAAA,CAAI,oBAAA;AACvB,MAAA,MAAM,SAAA,GAAY,MAAM,MAAA,CAAO,IAAA;AAAA,QAC7B,CAAA,mBAAA,EAAsB,kBAAA,CAAmB,UAAU,CAAC,CAAA,QAAA,CAAA;AAAA,QACpD,EAAE,cAAc,KAAA;AAAM,OACxB;AACA,MAAA,IAAI,CAAC,UAAU,SAAA,EAAW;AACxB,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,SAAA,EAAY,UAAU,CAAA,4BAAA,CAA8B,CAAA;AAAA,MACtE;AACA,MAAA,MAAM,qBAAA,CAAsB,MAAA,EAAQ,UAAA,EAAY,SAAA,CAAU,SAAA,EAAW;AAAA,QACnE,SAAA,EAAW,MAAA,CAAO,GAAA,CAAI,mBAAA,IAAuB,GAAO,CAAA;AAAA,QACpD,cAAA,EAAgB,MAAA,CAAO,GAAA,CAAI,yBAAA,IAA6B,GAAM;AAAA,OAC/D,CAAA;AACD,MAAA,OAAO,EAAE,UAAA,EAAY,QAAA,EAAU,SAAA,CAAU,SAAA,EAAU;AAAA,IACrD;AAAA,GACF;AACF;AAEO,SAAS,mBAAA,GAAiC;AAC/C,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,UAAA;AAAA,IACJ,WAAA,EAAa,gDAAA;AAAA,IACb,YAAY,CAAC,GAAA,KAAQ,QAAQ,GAAA,CAAI,sBAAA,IAA0B,IAAI,mBAAmB,CAAA;AAAA,IAClF,MAAM,GAAA,CAAI,EAAE,GAAA,EAAK,QAAO,EAAG;AACzB,MAAA,IAAI,CAAC,GAAA,CAAI,sBAAA,IAA0B,CAAC,IAAI,mBAAA,EAAqB;AAC3D,QAAA,MAAM,IAAI,MAAM,yEAAyE,CAAA;AAAA,MAC3F;AACA,MAAA,MAAM,SAAA,GAAY,MAAM,MAAA,CAAO,IAAA,CAA0B,2BAAA,EAA6B;AAAA,QACpF,QAAA,EAAU,CAAA,4BAAA,EAA+B,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA;AAAA,QACnD,KAAA,EAAO;AAAA,UACL;AAAA,YACE,QAAA,EAAU,UAAA;AAAA,YACV,qBAAqB,GAAA,CAAI,mBAAA;AAAA,YACzB,aAAA,EAAe,EAAE,aAAA,EAAe,GAAA,CAAI,sBAAA;AAAuB;AAC7D;AACF,OACD,CAAA;AACD,MAAA,IAAI,CAAC,SAAA,CAAU,MAAA,EAAQ,MAAM,IAAI,MAAM,oCAAoC,CAAA;AAC3E,MAAA,MAAM,GAAA,GAAM,MAAM,oBAAA,CAAqB,MAAA,EAAiB,UAAU,MAAA,EAAQ;AAAA,QACxE,SAAA,EAAW,MAAA,CAAO,GAAA,CAAI,mBAAA,IAAuB,GAAO,CAAA;AAAA,QACpD,cAAA,EAAgB,MAAA,CAAO,GAAA,CAAI,yBAAA,IAA6B,GAAM;AAAA,OAC/D,CAAA;AACD,MAAA,MAAM,MAAA,GAAU,IAA8C,KAAA,EAAO,YAAA;AACrE,MAAA,IAAI,MAAA,KAAW,WAAW,MAAM,IAAI,MAAM,CAAA,sBAAA,EAAyB,MAAA,IAAU,SAAS,CAAA,CAAE,CAAA;AACxF,MAAA,OAAO,EAAE,KAAA,EAAO,SAAA,CAAU,MAAA,EAAQ,YAAA,EAAc,IAAI,sBAAA,EAAuB;AAAA,IAC7E;AAAA,GACF;AACF;AAEO,SAAS,aAAA,GAA2B;AACzC,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,KAAA;AAAA,IACJ,WAAA,EAAa,qCAAA;AAAA,IACb,YAAY,CAAC,GAAA,KAAQ,QAAQ,GAAA,CAAI,oBAAA,IAAwB,IAAI,uBAAuB,CAAA;AAAA,IACpF,MAAM,GAAA,CAAI,EAAE,GAAA,EAAK,QAAO,EAAG;AACzB,MAAA,IAAI,CAAC,GAAA,CAAI,oBAAA,IAAwB,CAAC,IAAI,uBAAA,EAAyB;AAC7D,QAAA,MAAM,IAAI,MAAM,qEAAqE,CAAA;AAAA,MACvF;AACA,MAAA,MAAM,SAAA,GAAY,MAAM,MAAA,CAAO,IAAA,CAA0B,2BAAA,EAA6B;AAAA,QACpF,QAAA,EAAU,CAAA,uBAAA,EAA0B,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA;AAAA,QAC9C,UAAA,EAAY;AAAA,UACV,SAAS,GAAA,CAAI,oBAAA;AAAA,UACb,YAAA,EAAc,IAAI,yBAAA,IAA6B,QAAA;AAAA,UAC/C,UAAA,EAAY,IAAI,uBAAA,IAA2B;AAAA,SAC7C;AAAA,QACA,KAAA,EAAO;AAAA,UACL;AAAA,YACE,QAAA,EAAU,WAAA;AAAA,YACV,QAAA,EAAU;AAAA,cACR,QAAA,EAAU,CAAC,UAAA,EAAY,WAAW,CAAA;AAAA,cAClC,cAAc,GAAA,CAAI,uBAAA;AAAA,cAClB,GAAI,IAAI,wBAAA,GACJ,EAAE,mBAAmB,GAAA,CAAI,wBAAA,KACzB;AAAC;AACP;AACF;AACF,OACD,CAAA;AACD,MAAA,IAAI,CAAC,SAAA,CAAU,MAAA,EAAQ,MAAM,IAAI,MAAM,+BAA+B,CAAA;AACtE,MAAA,MAAM,GAAA,GAAM,MAAM,oBAAA,CAAqB,MAAA,EAAiB,UAAU,MAAA,EAAQ;AAAA,QACxE,SAAA,EAAW,MAAA,CAAO,GAAA,CAAI,mBAAA,IAAuB,GAAO,CAAA;AAAA,QACpD,cAAA,EAAgB,MAAA,CAAO,GAAA,CAAI,yBAAA,IAA6B,GAAM;AAAA,OAC/D,CAAA;AACD,MAAA,MAAM,MAAA,GAAU,IAA8C,KAAA,EAAO,YAAA;AACrE,MAAA,IAAI,MAAA,KAAW,WAAW,MAAM,IAAI,MAAM,CAAA,iBAAA,EAAoB,MAAA,IAAU,SAAS,CAAA,CAAE,CAAA;AACnF,MAAA,OAAO,EAAE,KAAA,EAAO,SAAA,CAAU,MAAA,EAAQ,MAAA,EAAQ,IAAI,oBAAA,EAAqB;AAAA,IACrE;AAAA,GACF;AACF;AAGO,SAAS,eAAA,CACd,EAAA,EACA,WAAA,EACA,GAAA,EACA,UAAA,EACW;AACX,EAAA,OAAO,EAAE,EAAA,EAAI,WAAA,EAAa,GAAA,EAAK,GAAI,aAAa,EAAE,UAAA,EAAW,GAAI,EAAC,EAAG;AACvE;AC7LA,SAAS,QAAA,CAAS,KAAyC,IAAA,EAAsB;AAC/E,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,IAAI,CAAA,EAAG,IAAA,EAAK;AAC9B,EAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,IAAI,CAAA,YAAA,CAAc,CAAA;AACjD,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,0BAAA,CACd,GAAA,EACA,OAAA,GAAgC,EAAC,EACP;AAC1B,EAAA,OAAO,IAAI,wBAAA,CAAyB;AAAA,IAClC,IAAA,EAAM,QAAA,CAAS,GAAA,EAAK,wBAAwB,CAAA;AAAA,IAC5C,QAAA,EAAU,QAAA,CAAS,GAAA,EAAK,4BAA4B,CAAA;AAAA,IACpD,IAAA,EAAM,QAAA,CAAS,GAAA,EAAK,wBAAwB,CAAA;AAAA,IAC5C,aAAA,EAAe,QAAA,CAAS,GAAA,EAAK,iBAAiB,CAAA;AAAA,IAC9C,QAAA,EAAU,QAAA,CAAS,GAAA,EAAK,4BAA4B,CAAA;AAAA,IACpD,KAAA,EAAO,qBAAqB,QAAA,CAAS,GAAA,EAAK,iBAAiB,CAAA,EAAG,GAAA,EAAK,QAAQ,SAAS,CAAA;AAAA,IACpF,WAAW,OAAA,CAAQ,SAAA;AAAA,IACnB,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,GAAA,EAAK;AAAA,GACN,CAAA;AACH;AAEA,eAAe,cAAA,CACb,KACA,SAAA,EACiB;AACjB,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,GAAA,EAAK,iBAAiB,CAAA;AAC5C,EAAA,MAAM,QAAA,GAAW,oBAAA,CAAqB,IAAA,EAAM,GAAA,EAAK,SAAS,CAAA;AAC1D,EAAA,OAAO,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,QAAA,EAAS;AAC5D;AAGO,SAAS,uBAAA,CAAwB,OAAA,GAAgC,EAAC,EAAc;AACrF,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,qBAAA;AAAA,IACJ,WAAA,EAAa,oCAAA;AAAA,IACb,UAAA,EAAY,CAAC,GAAA,KAAQ,OAAA,CAAQ,IAAI,0BAA0B,CAAA;AAAA,IAC3D,MAAM,GAAA,CAAI,EAAE,GAAA,EAAI,EAAG;AACjB,MAAA,MAAM,UAAA,GAAa,MAAM,0BAAA,CAA2B;AAAA,QAClD,aAAA,EAAe,QAAA,CAAS,GAAA,EAAK,iBAAiB,CAAA;AAAA,QAC9C,QAAA,EAAU,QAAA,CAAS,GAAA,EAAK,4BAA4B,CAAA;AAAA,QACpD,cAAA,EAAgB,MAAM,cAAA,CAAe,GAAA,EAAK,QAAQ,SAAS,CAAA;AAAA,QAC3D,WAAW,OAAA,CAAQ;AAAA,OACpB,CAAA;AACD,MAAA,IAAI,UAAA,CAAW,SAAA,IAAa,IAAA,CAAK,GAAA,EAAI,EAAG;AACtC,QAAA,MAAM,IAAI,MAAM,wCAAwC,CAAA;AAAA,MAC1D;AACA,MAAA,OAAO,EAAE,WAAW,IAAI,IAAA,CAAK,WAAW,SAAS,CAAA,CAAE,aAAY,EAAE;AAAA,IACnE;AAAA,GACF;AACF;AAGO,SAAS,sBAAA,CAAuB,OAAA,GAAgC,EAAC,EAAc;AACpF,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,UAAA;AAAA,IACJ,WAAA,EAAa,2DAAA;AAAA,IACb,UAAA,EAAY,CAAC,GAAA,KACX,OAAA;AAAA,MACE,IAAI,0BAAA,IACF,GAAA,CAAI,sBAAA,IACJ,GAAA,CAAI,8BACJ,GAAA,CAAI;AAAA,KACR;AAAA,IACF,MAAM,GAAA,CAAI,EAAE,GAAA,EAAI,EAAG;AACjB,MAAA,MAAM,QAAA,GAAW,0BAAA,CAA2B,GAAA,EAAK,OAAO,CAAA;AACxD,MAAA,IAAI;AACF,QAAA,MAAM,QAAQ,MAAM,QAAA,CACjB,OAAA,EAAQ,CACR,MAA+B,yBAAyB,CAAA;AAC3D,QAAA,IAAI,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAG,WAAW,MAAM,CAAA,EAAG;AAC5C,UAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,QACpE;AACA,QAAA,MAAM,SAAS,kBAAA,EAAmB;AAClC,QAAA,MAAM,SAAS,MAAM,QAAA,CAClB,OAAA,EAAQ,CACR,MAA+B,yBAAyB,CAAA;AAC3D,QAAA,IAAI,OAAO,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,WAAW,MAAM,CAAA,EAAG;AAC7C,UAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,QACjF;AACA,QAAA,OAAO,EAAE,OAAA,EAAS,CAAA,EAAG,SAAA,EAAW,IAAA,EAAK;AAAA,MACvC,CAAA,SAAE;AACA,QAAA,MAAM,SAAS,KAAA,EAAM;AAAA,MACvB;AAAA,IACF;AAAA,GACF;AACF;;;AClGA,eAAsB,gBACpB,GAAA,EACA,SAAA,EACA,OAAoB,EAAC,EACrB,YAA0B,KAAA,EACP;AACnB,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,eAAA,EAAiB,OAAA,CAAQ,OAAO,EAAE,CAAA;AACnD,EAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,MAAM,6BAA6B,CAAA;AACxD,EAAA,MAAM,QAAA,GAAW,oBAAA,CAAqB,IAAA,EAAM,GAAA,EAAK,SAAS,CAAA;AAC1D,EAAA,MAAM,QAAQ,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,MAAM,QAAA,EAAS;AACvE,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA;AACxC,EAAA,OAAA,CAAQ,GAAA,CAAI,eAAA,EAAiB,CAAA,OAAA,EAAU,KAAK,CAAA,CAAE,CAAA;AAC9C,EAAA,MAAM,WAAW,MAAM,SAAA;AAAA,IACrB,cAAA,CAAe,KAAK,SAAS,CAAA,GAAI,YAAY,CAAA,EAAG,IAAI,GAAG,SAAS,CAAA,CAAA;AAAA,IAChE;AAAA,MACE,GAAG,IAAA;AAAA,MACH;AAAA;AACF,GACF;AACA,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,2BAAA,EAA8B,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,QAAA,CAAS,UAAU,CAAA,EAAA,EAAK,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,KAC7F;AAAA,EACF;AACA,EAAA,OAAO,QAAA;AACT;;;ACzBA,SAAS,IAAI,KAAA,EAAqC;AAChD,EAAA,OAAA,CAAQ,KAAA,IAAS,EAAA,EACd,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,EAAM,CAAA,CACzB,OAAO,OAAO,CAAA;AACnB;AAGO,SAAS,gBAAA,GAA8B;AAC5C,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,SAAA;AAAA,IACJ,WAAA,EAAa,gDAAA;AAAA,IACb,YAAY,CAAC,GAAA,KAAQ,QAAQ,GAAA,CAAI,qBAAA,IAAyB,IAAI,oBAAoB,CAAA;AAAA,IAClF,MAAM,GAAA,CAAI,EAAE,GAAA,EAAK,QAAO,EAAG;AACzB,MAAA,MAAM,QAAQ,GAAA,CAAI,qBAAA;AAClB,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,GAAA,CAAI,oBAAoB,CAAA;AAC7C,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,GAAA,CAAsC,uBAAA,EAAyB;AAAA,QAC3F;AAAA,OACD,CAAA;AACD,MAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAA,CAAK,QAAA,CAAS,WAAW,EAAC,EAAG,GAAA,CAAI,CAAC,WAAW,MAAA,CAAO,GAAG,CAAA,CAAE,MAAA,CAAO,OAAO,CAAC,CAAA;AAC3F,MAAA,MAAM,OAAA,GAAU,SAAS,MAAA,CAAO,CAAC,QAAQ,CAAC,MAAA,CAAO,GAAA,CAAI,GAAG,CAAC,CAAA;AACzD,MAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,QAAA,MAAM,IAAI,MAAM,CAAA,aAAA,EAAgB,KAAK,qBAAqB,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,MAChF;AACA,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,EAAc,QAAA,CAAS,MAAA,EAAO;AAAA,IAChD;AAAA,GACF;AACF;AAOO,SAAS,cAAA,CAAe,OAAA,GAAiC,EAAC,EAAc;AAC7E,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,KAAA;AAAA,IACJ,WAAA,EAAa,+CAAA;AAAA,IACb,UAAA,EAAY,CAAC,GAAA,KAAQ,OAAA,CAAQ,IAAI,iBAAiB,CAAA;AAAA,IAClD,MAAM,GAAA,CAAI,EAAE,GAAA,EAAK,QAAO,EAAG;AACzB,MAAA,MAAM,OAAO,GAAA,CAAI,iBAAA;AACjB,MAAA,MAAM,GAAA,GAAM,MAAM,MAAA,CAAO,GAAA,CAKtB,iBAAiB,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAE,CAAA;AAC9C,MAAA,IAAI,GAAA,CAAI,UAAA,EAAY,KAAA,KAAU,SAAA,EAAW;AACvC,QAAA,MAAM,IAAI,MAAM,CAAA,eAAA,EAAkB,IAAI,OAAO,GAAA,CAAI,UAAA,EAAY,KAAA,IAAS,SAAS,CAAA,CAAE,CAAA;AAAA,MACnF;AACA,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,GAAA,CAAI,sBAAsB,CAAA;AAC/C,MAAA,MAAM,SAAS,IAAI,GAAA;AAAA,QAAA,CAChB,GAAA,CAAI,SAAA,IAAa,EAAC,EAAG,GAAA,CAAI,CAAC,QAAA,KAAa,QAAA,CAAS,IAAI,CAAA,CAAE,MAAA,CAAO,OAAO;AAAA,OACvE;AACA,MAAA,MAAM,OAAA,GAAU,SAAS,MAAA,CAAO,CAAC,aAAa,CAAC,MAAA,CAAO,GAAA,CAAI,QAAQ,CAAC,CAAA;AACnE,MAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,kBAAkB,IAAI,CAAA,+BAAA,EAAkC,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,SAC5E;AAAA,MACF;AACA,MAAA,MAAM,MAAA,GAAS,GAAA,CAAI,gBAAA,IAAoB,GAAA,CAAI,OAAO,GAAA,CAAI,OAAA;AACtD,MAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,IAAI,CAAA,gBAAA,CAAkB,CAAA;AACrE,MAAA,MAAM,YAAY,IAAI,GAAA,CAAI,cAAA,EAAgB,MAAM,EAAE,QAAA,EAAS;AAC3D,MAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,GAAA,EAAK,WAAW,EAAC,EAAG,QAAQ,SAAS,CAAA;AAC5E,MAAA,MAAM,MAAA,GAAU,MAAM,QAAA,CAAS,IAAA,EAAK;AACpC,MAAA,IAAI,MAAA,CAAO,EAAA,KAAO,IAAA,IAAQ,MAAA,CAAO,WAAW,IAAA,EAAM;AAChD,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,IAAI,CAAA,+BAAA,CAAiC,CAAA;AAAA,MACzE;AACA,MAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,CAAO,IAAA,EAAM,QAAQ,IAAA,EAAK;AAAA,IACrD;AAAA,GACF;AACF;ACjEO,SAAS,oBAAoB,KAAA,EAAuB;AACzD,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAC1C,EAAA,IAAI,CAAC,kCAAA,CAAmC,IAAA,CAAK,UAAU,CAAA,EAAG;AACxD,IAAA,MAAM,IAAI,MAAM,8DAA8D,CAAA;AAAA,EAChF;AACA,EAAA,OAAO,UAAA;AACT;AAEA,eAAsB,qBAAA,CACpB,GAAA,EACA,SAAA,EACA,SAAA,EACe;AACf,EAAA,MAAM,eAAA,CAAgB,KAAK,CAAA,uBAAA,EAA0B,SAAS,IAAI,EAAE,MAAA,EAAQ,KAAA,EAAM,EAAG,SAAS,CAAA;AAChG;AAEA,eAAsB,gBAAA,CACpB,GAAA,EACA,IAAA,EACA,IAAA,EACA,SAAA,EACe;AACf,EAAA,MAAM,eAAA;AAAA,IACJ,GAAA;AAAA,IACA,oBAAoB,IAAI,CAAA,CAAA;AAAA,IACxB,EAAE,MAAA,EAAQ,KAAA,EAAO,IAAA,EAAuB;AAAA,IACxC;AAAA,GACF;AACF;AAEA,eAAsB,gBAAA,CACpB,GAAA,EACA,IAAA,EACA,SAAA,EACe;AACf,EAAA,MAAM,eAAA,CAAgB,KAAK,CAAA,iBAAA,EAAoB,IAAI,IAAI,EAAE,MAAA,EAAQ,QAAA,EAAS,EAAG,SAAS,CAAA;AACxF;AAGO,SAAS,aAAA,CAAc,OAAA,GAAgC,EAAC,EAAc;AAC3E,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,WAAA;AAAA,IACJ,WAAA,EAAa,2CAAA;AAAA,IACb,UAAA,EAAY,CAAC,GAAA,KAAQ,OAAA,CAAQ,IAAI,eAAe,CAAA;AAAA,IAChD,MAAM,GAAA,CAAI,EAAE,GAAA,EAAI,EAAG;AACjB,MAAA,MAAM,IAAA,GAAO,mBAAA,CAAoB,GAAA,CAAI,eAAyB,CAAA;AAC9D,MAAA,MAAM,UAAU,GAAA,CAAI,iBAAA,IAAqB,SAAA,EAAW,OAAA,CAAQ,oBAAoB,GAAG,CAAA;AACnF,MAAA,MAAM,EAAA,GAAA,CAAM,OAAA,CAAQ,QAAA,IAAY,UAAA,GAAY;AAC5C,MAAA,MAAM,SAAA,GAAY,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AACnC,MAAA,MAAM,IAAA,GAAO,CAAA,EAAG,SAAS,CAAA,OAAA,EAAU,EAAE,CAAA,IAAA,CAAA;AACrC,MAAA,MAAM,QAAA,GAAW,oBAAoB,IAAI,CAAA,CAAA;AACzC,MAAA,MAAM,OAAO,IAAI,WAAA,GAAc,MAAA,CAAO,CAAA,gCAAA,EAAmC,EAAE,CAAA,CAAE,CAAA;AAC7E,MAAA,MAAM,qBAAA,CAAsB,GAAA,EAAK,SAAA,EAAW,OAAA,CAAQ,SAAS,CAAA;AAC7D,MAAA,IAAI;AACF,QAAA,MAAM,gBAAA,CAAiB,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,QAAQ,SAAS,CAAA;AACzD,QAAA,MAAM,UAAA,GAAa,MAAM,eAAA,CAAgB,GAAA,EAAK,UAAU,EAAC,EAAG,QAAQ,SAAS,CAAA;AAC7E,QAAA,MAAM,SAAS,IAAI,UAAA,CAAW,MAAM,UAAA,CAAW,aAAa,CAAA;AAC5D,QAAA,IAAI,MAAA,CAAO,MAAA,KAAW,IAAA,CAAK,MAAA,IAAU,MAAA,CAAO,IAAA,CAAK,CAAC,KAAA,EAAO,KAAA,KAAU,KAAA,KAAU,IAAA,CAAK,KAAK,CAAC,CAAA,EAAG;AACzF,UAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,QAC9D;AACA,QAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO,KAAK,MAAA,EAAO;AAAA,MAC5C,CAAA,SAAE;AACA,QAAA,MAAM,gBAAA,CAAiB,KAAK,IAAA,EAAM,OAAA,CAAQ,SAAS,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAAA,MAC5E;AAAA,IACF;AAAA,GACF;AACF;ACxDO,SAAS,wBAAA,CAAyB,OAAA,GAAkC,EAAC,EAAc;AACxF,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,YAAA;AAAA,IACJ,WAAA,EAAa,2EAAA;AAAA,IACb,UAAA,EAAY,CAAC,GAAA,KACX,OAAA;AAAA,MACE,IAAI,+BAAA,IACF,GAAA,CAAI,yBAAA,IACJ,GAAA,CAAI,+BACJ,GAAA,CAAI;AAAA,KACR;AAAA,IACF,MAAM,GAAA,CAAI,EAAE,GAAA,EAAK,MAAA,EAAQ,WAAU,EAAG;AACpC,MAAA,MAAM,aAAa,GAAA,CAAI,+BAAA;AACvB,MAAA,IAAI,UAAA,KAAe,IAAI,oBAAA,EAAsB;AAC3C,QAAA,MAAM,IAAI,MAAM,qEAAqE,CAAA;AAAA,MACvF;AACA,MAAA,MAAM,IAAA,GAAO,mBAAA,CAAoB,GAAA,CAAI,eAAyB,CAAA;AAC9D,MAAA,MAAM,cAAc,GAAA,CAAI,2BAAA;AACxB,MAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,WAAA,IAAe,IAAI,UAAA,CAAW,MAAM,QAAA,CAAS,OAAA,CAAQ,WAAW,CAAC,CAAC,CAAA;AACvF,MAAA,MAAM,EAAA,GAAA,CAAM,OAAA,CAAQ,QAAA,IAAYC,UAAAA,GAAY;AAC5C,MAAA,MAAM,WAAW,GAAA,CAAI,iBAAA,IAAqB,YAAA,EAAc,OAAA,CAAQ,oBAAoB,GAAG,CAAA;AACvF,MAAA,MAAM,YAAY,CAAA,EAAG,IAAI,CAAA,WAAA,EAAc,OAAO,IAAI,EAAE,CAAA,CAAA;AACpD,MAAA,MAAM,cAAc,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,QAAA,CAAS,WAAW,CAAC,CAAA,CAAA;AACzD,MAAA,MAAM,qBAAA,CAAsB,GAAA,EAAK,SAAA,EAAW,OAAA,CAAQ,SAAS,CAAA;AAC7D,MAAA,IAAI;AACF,QAAA,MAAM,gBAAA,CAAiB,GAAA,EAAK,WAAA,EAAa,IAAA,EAAM,QAAQ,SAAS,CAAA;AAChE,QAAA,MAAM,SAAA,GAAY,MAAM,MAAA,CAAO,IAAA;AAAA,UAC7B,CAAA,mBAAA,EAAsB,kBAAA,CAAmB,UAAU,CAAC,CAAA,QAAA,CAAA;AAAA,UACpD,EAAE,cAAc,IAAA;AAAK,SACvB;AACA,QAAA,IAAI,CAAC,SAAA,CAAU,SAAA,EAAW,MAAM,IAAI,MAAM,4CAA4C,CAAA;AACtF,QAAA,MAAM,qBAAA,CAAsB,MAAA,EAAQ,UAAA,EAAY,SAAA,CAAU,SAAA,EAAW;AAAA,UACnE,SAAA,EAAW,MAAA,CAAO,GAAA,CAAI,mBAAA,IAAuB,GAAO,CAAA;AAAA,UACpD,cAAA,EAAgB,MAAA,CAAO,GAAA,CAAI,yBAAA,IAA6B,GAAM;AAAA,SAC/D,CAAA;AACD,QAAA,MAAM,QAAQ,GAAA,CAAI,yBAAA;AAClB,QAAA,MAAM,IAAA,GAAO,MAAM,SAAA,CAAU,KAAA;AAAA,UAC3B,oGAAoG,KAAK,CAAA;AAAA,SAC3G;AACA,QAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,KAAK,CAAC,CAAA;AACpC,QAAA,MAAM,UAAU,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,WAAW,CAAC,CAAA;AAC5C,QAAA,IAAI,QAAQ,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,gCAAA,EAAmC,KAAK,CAAA,CAAE,CAAA;AACzE,QAAA,IAAI,OAAA,KAAY,CAAA;AACd,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,OAAO,CAAA,iBAAA,EAAoB,KAAK,CAAA,CAAE,CAAA;AAC5E,QAAA,OAAO,EAAE,UAAA,EAAY,KAAA,EAAO,IAAA,EAAM,OAAO,OAAA,EAAQ;AAAA,MACnD,CAAA,SAAE;AACA,QAAA,MAAM,gBAAA,CAAiB,KAAK,WAAA,EAAa,OAAA,CAAQ,SAAS,CAAA,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AAAA,MACnF;AAAA,IACF;AAAA,GACF;AACF","file":"index.js","sourcesContent":["import type { TableFixture } from './fixtures.js';\n\nexport type TestProfile = 'local' | 'live';\n\n/**\n * One SQL surface, two engines (ADR-0006). `local` executes on DuckDB\n * in-process; `live` executes on a Databricks SQL warehouse via the SQL\n * Statement Execution API. Params are positional `?` in both profiles — the\n * workspace context transparently rewrites them to the named markers the\n * Statement Execution API requires.\n */\nexport interface ExecutionContext {\n readonly profile: TestProfile;\n /** Execute a statement, discarding any result. */\n exec(sql: string, params?: readonly unknown[]): Promise<void>;\n /** Execute a query and return normalized row objects (bigint→number, timestamps→ISO). */\n query(sql: string, params?: readonly unknown[]): Promise<Record<string, unknown>[]>;\n /** Create + seed a table from a declarative fixture. */\n loadFixture(fixture: TableFixture): Promise<void>;\n /** Qualify a bare table name for this context (schema/catalog scoping). */\n qual(table: string): string;\n close(): Promise<void>;\n}\n\nexport function resolveProfile(env: Record<string, string | undefined> = process.env): TestProfile {\n const profile = env.DBX_TEST_PROFILE ?? 'local';\n if (profile !== 'local' && profile !== 'live') {\n throw new Error(`DBX_TEST_PROFILE must be 'local' or 'live', got '${profile}'`);\n }\n if (profile === 'live' && env.DBX_TEST_LIVE !== '1') {\n throw new Error(\n 'DBX_TEST_PROFILE=live requires DBX_TEST_LIVE=1 (live suites are always gated)',\n );\n }\n return profile;\n}\n\nexport interface CreateContextOptions {\n profile?: TestProfile;\n env?: Record<string, string | undefined>;\n /** local profile: schema to create + qualify tables with. live profile: schema within the catalog. */\n schema?: string;\n /** Live profile only: observe each submitted SQL statement. */\n onStatement?: (statement: { sql: string; statementId?: string }) => void;\n}\n\n/** Profile-dispatched factory. Lazy-imports each engine so the unused one stays out of the bundle. */\nexport async function createExecutionContext(\n options: CreateContextOptions = {},\n): Promise<ExecutionContext> {\n const env = options.env ?? process.env;\n const profile = options.profile ?? resolveProfile(env);\n if (profile === 'local') {\n const { createDuckDbContext } = await import('./duckdb-context.js');\n return createDuckDbContext({ schema: options.schema });\n }\n const { createWorkspaceContext } = await import('./workspace-context.js');\n return createWorkspaceContext({\n env,\n schema: options.schema,\n ...(options.onStatement ? { onStatement: options.onStatement } : {}),\n });\n}\n","import type { ExecutionContext } from './context.js';\nimport { compareToGolden } from './golden.js';\n\n/**\n * Framework-free table assertions — they throw plain Errors so they work\n * under vitest, cucumber-js steps, or the live check runner alike.\n */\nexport function expectTable(ctx: ExecutionContext, table: string) {\n const target = ctx.qual(table);\n return {\n async toHaveRowCount(expected: number): Promise<void> {\n const rows = await ctx.query(`SELECT COUNT(*) AS n FROM ${target}`);\n const actual = Number(rows[0]?.n ?? Number.NaN);\n if (actual !== expected) {\n throw new Error(`Expected ${target} to have ${expected} rows, found ${actual}`);\n }\n },\n\n /** Every partial row must match at least one table row on its own keys. */\n async toContainRows(partials: readonly Record<string, unknown>[]): Promise<void> {\n const rows = await ctx.query(`SELECT * FROM ${target}`);\n for (const partial of partials) {\n const hit = rows.some((row) =>\n Object.entries(partial).every(([key, value]) => looselyEqual(row[key], value)),\n );\n if (!hit) {\n throw new Error(\n `Expected ${target} to contain a row matching ${JSON.stringify(partial)}; ` +\n `have ${rows.length} rows: ${JSON.stringify(rows.slice(0, 5))}${rows.length > 5 ? ' …' : ''}`,\n );\n }\n }\n },\n\n /**\n * Compare `SELECT * ORDER BY <orderBy>` against a committed golden JSON\n * file. Set DBX_TEST_UPDATE_GOLDEN=1 to (re)write the golden instead —\n * a reviewable, versioned event.\n */\n async toMatchGolden(goldenPath: string, options: { orderBy?: string } = {}): Promise<void> {\n const orderBy = options.orderBy ? ` ORDER BY ${options.orderBy}` : '';\n const rows = await ctx.query(`SELECT * FROM ${target}${orderBy}`);\n await compareToGolden(goldenPath, rows, `table ${target}`);\n },\n };\n}\n\n/** Compare query results (not a whole table) against a golden file. */\nexport async function expectQueryToMatchGolden(\n ctx: ExecutionContext,\n sql: string,\n params: readonly unknown[],\n goldenPath: string,\n): Promise<void> {\n const rows = await ctx.query(sql, params);\n await compareToGolden(goldenPath, rows, 'query');\n}\n\nfunction looselyEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a === 'number' && typeof b === 'number') return Math.abs(a - b) < 1e-9;\n // Timestamps normalize to 'YYYY-MM-DD HH:MM:SS'; allow ISO-style expectations.\n if (typeof a === 'string' && typeof b === 'string') {\n return (\n a.replace('T', ' ').replace(/(\\.\\d+)?Z?$/, '') ===\n b.replace('T', ' ').replace(/(\\.\\d+)?Z?$/, '')\n );\n }\n return false;\n}\n","/**\n * Framework-free fake of the Databricks REST client surface, for unit tests\n * of orchestration logic (submit → poll → terminal). Queue responses per\n * (method, path-prefix); every call is recorded for assertions. Works under\n * vitest without vi.fn so it is equally usable from cucumber-js worlds.\n */\nexport interface RecordedCall {\n method: 'GET' | 'POST';\n path: string;\n body?: unknown;\n query?: Record<string, string | number | boolean | undefined>;\n}\n\nexport interface MockDatabricksClient {\n get<T>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T>;\n post<T>(\n path: string,\n body?: unknown,\n query?: Record<string, string | number | boolean | undefined>,\n options?: unknown,\n ): Promise<T>;\n /** Queue the next response for calls whose path starts with `pathPrefix`. FIFO per prefix. */\n queue(method: 'GET' | 'POST', pathPrefix: string, response: unknown): MockDatabricksClient;\n /** Queue an error for the next matching call. */\n queueError(method: 'GET' | 'POST', pathPrefix: string, error: Error): MockDatabricksClient;\n readonly calls: readonly RecordedCall[];\n callsTo(method: 'GET' | 'POST', pathPrefix: string): RecordedCall[];\n}\n\ntype Queued = { pathPrefix: string; response?: unknown; error?: Error };\n\nexport function createMockDatabricksClient(): MockDatabricksClient {\n const queues: Record<'GET' | 'POST', Queued[]> = { GET: [], POST: [] };\n const calls: RecordedCall[] = [];\n\n function take(method: 'GET' | 'POST', path: string): Queued {\n const index = queues[method].findIndex((q) => path.startsWith(q.pathPrefix));\n if (index === -1) {\n throw new Error(\n `MockDatabricksClient: no queued ${method} response for ${path}. ` +\n `Queued prefixes: ${queues[method].map((q) => q.pathPrefix).join(', ') || '(none)'}`,\n );\n }\n return queues[method].splice(index, 1)[0] as Queued;\n }\n\n const client: MockDatabricksClient = {\n async get<T>(path: string, query?: Record<string, string | number | boolean | undefined>) {\n calls.push({ method: 'GET', path, query });\n const queued = take('GET', path);\n if (queued.error) throw queued.error;\n return queued.response as T;\n },\n async post<T>(\n path: string,\n body?: unknown,\n query?: Record<string, string | number | boolean | undefined>,\n ) {\n calls.push({ method: 'POST', path, body, query });\n const queued = take('POST', path);\n if (queued.error) throw queued.error;\n return queued.response as T;\n },\n queue(method, pathPrefix, response) {\n queues[method].push({ pathPrefix, response });\n return client;\n },\n queueError(method, pathPrefix, error) {\n queues[method].push({ pathPrefix, error });\n return client;\n },\n calls,\n callsTo(method, pathPrefix) {\n return calls.filter((c) => c.method === method && c.path.startsWith(pathPrefix));\n },\n };\n return client;\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { ExecutionContext } from './context.js';\nimport {\n type WorkspaceClientLike,\n createClientFromEnv,\n createWorkspaceContext,\n} from './workspace-context.js';\n\nexport type LiveCheckStatus = 'pass' | 'fail' | 'not-configured';\n\nexport interface LiveCheckContext {\n env: Record<string, string | undefined>;\n warehouse: ExecutionContext;\n client: WorkspaceClientLike;\n}\n\nexport interface LiveCheck {\n id: string;\n description: string;\n configured?: (env: Record<string, string | undefined>) => boolean;\n run(context: LiveCheckContext): Promise<unknown>;\n}\n\nexport interface LiveCheckResult {\n id: string;\n description: string;\n status: LiveCheckStatus;\n durationMs: number;\n details?: unknown;\n error?: string;\n}\n\nexport interface LiveEvidence {\n schemaVersion: 1;\n kind: 'databricks-live-suite';\n startedAt: string;\n finishedAt: string;\n success: boolean;\n required: string[];\n results: LiveCheckResult[];\n}\n\nexport interface LiveSuiteSpec {\n checks: readonly LiveCheck[];\n required?: readonly string[];\n evidencePath?: string;\n junitPath?: string;\n env?: Record<string, string | undefined>;\n}\n\nexport interface LiveSuiteRuntime {\n warehouse?: ExecutionContext;\n client?: WorkspaceClientLike;\n}\n\nexport interface DefinedLiveSuite {\n run(runtime?: LiveSuiteRuntime): Promise<LiveEvidence | undefined>;\n}\n\n/**\n * Define an explicitly gated live suite. Without DBX_TEST_LIVE=1, run() is a\n * silent no-op so the same command is safe in ordinary CI matrices.\n */\nexport function defineLiveSuite(spec: LiveSuiteSpec): DefinedLiveSuite {\n return { run: (runtime) => runLiveSuite(spec, runtime) };\n}\n\nexport async function runLiveSuite(\n spec: LiveSuiteSpec,\n runtime: LiveSuiteRuntime = {},\n): Promise<LiveEvidence | undefined> {\n const env = spec.env ?? process.env;\n if (env.DBX_TEST_LIVE !== '1') return undefined;\n\n const required = [...(spec.required ?? [])];\n const known = new Set(spec.checks.map((check) => check.id));\n for (const id of required) {\n if (!known.has(id)) throw new Error(`Required live check '${id}' is not defined`);\n }\n\n const startedAt = new Date().toISOString();\n const ownedWarehouse = runtime.warehouse === undefined;\n const client = runtime.client ?? createClientFromEnv(env);\n const warehouse = runtime.warehouse ?? (await createWorkspaceContext({ env, client }));\n const results: LiveCheckResult[] = [];\n\n try {\n for (const check of spec.checks) {\n if (check.configured && !check.configured(env)) {\n results.push({\n id: check.id,\n description: check.description,\n status: 'not-configured',\n durationMs: 0,\n });\n continue;\n }\n const before = performance.now();\n try {\n const details = await check.run({ env, warehouse, client });\n results.push({\n id: check.id,\n description: check.description,\n status: 'pass',\n durationMs: Math.round(performance.now() - before),\n ...(details === undefined ? {} : { details: redactValue(details, env) }),\n });\n } catch (error) {\n results.push({\n id: check.id,\n description: check.description,\n status: 'fail',\n durationMs: Math.round(performance.now() - before),\n error: redactText(error instanceof Error ? error.message : String(error), env),\n });\n }\n }\n } finally {\n if (ownedWarehouse) await warehouse.close();\n }\n\n const success = required.every(\n (id) => results.find((result) => result.id === id)?.status === 'pass',\n );\n const evidence: LiveEvidence = {\n schemaVersion: 1,\n kind: 'databricks-live-suite',\n startedAt,\n finishedAt: new Date().toISOString(),\n success,\n required,\n results,\n };\n\n if (spec.evidencePath)\n await writeReport(spec.evidencePath, `${JSON.stringify(evidence, null, 2)}\\n`);\n if (spec.junitPath) await writeReport(spec.junitPath, renderJUnit(evidence));\n return evidence;\n}\n\nasync function writeReport(path: string, contents: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, contents, 'utf8');\n}\n\nfunction redactText(text: string, env: Record<string, string | undefined>): string {\n let output = text;\n for (const [name, value] of Object.entries(env)) {\n if (!value || value.length < 6 || !/(TOKEN|SECRET|PASSWORD|BEARER|KEY)/i.test(name)) continue;\n output = output.split(value).join('[REDACTED]');\n }\n return output;\n}\n\nfunction redactValue(value: unknown, env: Record<string, string | undefined>): unknown {\n return JSON.parse(redactText(JSON.stringify(value), env)) as unknown;\n}\n\nfunction xml(value: string): string {\n return value\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('\"', '"')\n .replaceAll(\"'\", ''');\n}\n\nexport function renderJUnit(evidence: LiveEvidence): string {\n const failures = evidence.results.filter((result) => result.status === 'fail').length;\n const skipped = evidence.results.filter((result) => result.status === 'not-configured').length;\n const seconds = evidence.results.reduce((sum, result) => sum + result.durationMs, 0) / 1000;\n const cases = evidence.results\n .map((result) => {\n const body =\n result.status === 'fail'\n ? `<failure message=\"${xml(result.error ?? 'check failed')}\"/>`\n : result.status === 'not-configured'\n ? '<skipped message=\"not configured\"/>'\n : '';\n return ` <testcase classname=\"databricks-live\" name=\"${xml(result.id)}\" time=\"${result.durationMs / 1000}\">${body}</testcase>`;\n })\n .join('\\n');\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<testsuite name=\"databricks-live\" tests=\"${evidence.results.length}\" failures=\"${failures}\" skipped=\"${skipped}\" time=\"${seconds}\">\\n${cases}\\n</testsuite>\\n`;\n}\n","import type { WorkspaceClientLike } from './workspace-context.js';\n\nexport interface PollOptions {\n pollIntervalMs?: number;\n timeoutMs?: number;\n signal?: AbortSignal;\n}\n\nconst TERMINAL_PIPELINE_STATES = new Set(['COMPLETED', 'FAILED', 'CANCELED']);\n\nexport async function waitForPipelineUpdate(\n client: WorkspaceClientLike,\n pipelineId: string,\n updateId: string,\n options: PollOptions = {},\n): Promise<Record<string, unknown>> {\n const deadline = Date.now() + (options.timeoutMs ?? 900_000);\n const interval = options.pollIntervalMs ?? 10_000;\n const path = `/api/2.0/pipelines/${encodeURIComponent(pipelineId)}/updates/${encodeURIComponent(updateId)}`;\n let update: { update?: { state?: string } } = await client.get(path);\n while (!TERMINAL_PIPELINE_STATES.has(update.update?.state ?? '') && Date.now() < deadline) {\n if (options.signal?.aborted) throw new Error(`Pipeline update ${updateId} was aborted`);\n await abortableDelay(interval, options.signal);\n update = await client.get(path);\n }\n const state = update.update?.state ?? 'UNKNOWN';\n if (state !== 'COMPLETED') {\n throw new Error(`Pipeline update ${updateId} ended in ${state} (wanted COMPLETED)`);\n }\n return update as Record<string, unknown>;\n}\n\nfunction abortableDelay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error('Polling aborted'));\n return;\n }\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(new Error('Polling aborted'));\n },\n { once: true },\n );\n });\n}\n","import { waitForDatabricksRun } from '@fabric-harness/databricks';\nimport type { LiveCheck } from './live-suite.js';\nimport { waitForPipelineUpdate } from './pollers.js';\n\nexport function sqlRoundTripCheck(): LiveCheck {\n return {\n id: 'sql',\n description: 'SQL Statement Execution round-trip',\n async run({ warehouse }) {\n const rows = await warehouse.query('SELECT 1 AS dbx_test_ok');\n if (Number(rows[0]?.dbx_test_ok) !== 1)\n throw new Error('SQL round-trip returned an unexpected value');\n return { rows: rows.length };\n },\n };\n}\n\nexport interface DeltaColumnContract {\n name: string;\n type?: string;\n}\n\nexport function assertDeltaContract(\n table: string,\n rows: readonly Record<string, unknown>[],\n columns: readonly DeltaColumnContract[],\n): void {\n for (const expected of columns) {\n const actual = rows.find((row) => String(row.col_name ?? row.column_name) === expected.name);\n if (!actual) throw new Error(`Delta contract missing column '${expected.name}' in ${table}`);\n const actualType = String(actual.data_type ?? actual.column_type ?? '').toLowerCase();\n if (expected.type && actualType !== expected.type.toLowerCase()) {\n throw new Error(\n `Delta column ${expected.name} has type ${actualType}, expected ${expected.type}`,\n );\n }\n }\n}\n\nexport function deltaContractCheck(\n tableEnv = 'DBX_TEST_DELTA_TABLE',\n columns: readonly DeltaColumnContract[] = [],\n): LiveCheck {\n return {\n id: 'delta-contract',\n description: 'Delta table schema contract',\n configured: (env) => Boolean(env[tableEnv]),\n async run({ env, warehouse }) {\n const table = env[tableEnv] as string;\n const rows = await warehouse.query(`DESCRIBE TABLE ${table}`);\n assertDeltaContract(table, rows, columns);\n return { table, columns: rows.length };\n },\n };\n}\n\nexport function unityCatalogAccessCheck(): LiveCheck {\n return {\n id: 'uc-grants',\n description: 'Unity Catalog allow/deny access assertions',\n configured: (env) => Boolean(env.DBX_TEST_UC_ALLOWED_TABLE && env.DBX_TEST_UC_DENIED_TABLE),\n async run({ env, warehouse }) {\n await warehouse.query(`SELECT * FROM ${env.DBX_TEST_UC_ALLOWED_TABLE} LIMIT 1`);\n try {\n await warehouse.query(`SELECT * FROM ${env.DBX_TEST_UC_DENIED_TABLE} LIMIT 1`);\n } catch (error) {\n if (/permission.?denied|insufficient.?priv|403|unauthoriz/i.test(String(error))) {\n return { allowed: env.DBX_TEST_UC_ALLOWED_TABLE, denied: env.DBX_TEST_UC_DENIED_TABLE };\n }\n throw error;\n }\n throw new Error(`Expected access to ${env.DBX_TEST_UC_DENIED_TABLE} to be denied`);\n },\n };\n}\n\nexport function jobRunCheck(): LiveCheck {\n return {\n id: 'jobs',\n description: 'Databricks Job run-now reaches SUCCESS',\n configured: (env) => Boolean(env.DBX_TEST_JOB_ID),\n async run({ env, client }) {\n const jobId = Number(env.DBX_TEST_JOB_ID);\n if (!Number.isFinite(jobId)) throw new Error('DBX_TEST_JOB_ID must be numeric');\n const submitted = await client.post<{ run_id: number }>('/api/2.1/jobs/run-now', {\n job_id: jobId,\n });\n const run = await waitForDatabricksRun(client as never, submitted.run_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n const result = (run as { state?: { result_state?: string } }).state?.result_state;\n if (result !== 'SUCCESS') throw new Error(`Job ${jobId} ended in ${result ?? 'UNKNOWN'}`);\n return { jobId, runId: submitted.run_id };\n },\n };\n}\n\n/** Trigger the deployed Lakeflow pipeline and require a completed update. */\nexport function pipelineRefreshCheck(): LiveCheck {\n return {\n id: 'pipeline',\n description: 'Lakeflow telemetry pipeline refresh reaches COMPLETED',\n configured: (env) => Boolean(env.DBX_TEST_PIPELINE_ID),\n async run({ env, client }) {\n const pipelineId = env.DBX_TEST_PIPELINE_ID as string;\n const submitted = await client.post<{ update_id?: string }>(\n `/api/2.0/pipelines/${encodeURIComponent(pipelineId)}/updates`,\n { full_refresh: false },\n );\n if (!submitted.update_id) {\n throw new Error(`Pipeline ${pipelineId} did not return an update_id`);\n }\n await waitForPipelineUpdate(client, pipelineId, submitted.update_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n return { pipelineId, updateId: submitted.update_id };\n },\n };\n}\n\nexport function notebookSubmitCheck(): LiveCheck {\n return {\n id: 'notebook',\n description: 'Databricks notebook submit run reaches SUCCESS',\n configured: (env) => Boolean(env.DBX_TEST_NOTEBOOK_PATH && env.DBX_TEST_CLUSTER_ID),\n async run({ env, client }) {\n if (!env.DBX_TEST_NOTEBOOK_PATH || !env.DBX_TEST_CLUSTER_ID) {\n throw new Error('Notebook submit requires DBX_TEST_NOTEBOOK_PATH and DBX_TEST_CLUSTER_ID');\n }\n const submitted = await client.post<{ run_id?: number }>('/api/2.1/jobs/runs/submit', {\n run_name: `fabric-experiments-notebook-${Date.now()}`,\n tasks: [\n {\n task_key: 'notebook',\n existing_cluster_id: env.DBX_TEST_CLUSTER_ID,\n notebook_task: { notebook_path: env.DBX_TEST_NOTEBOOK_PATH },\n },\n ],\n });\n if (!submitted.run_id) throw new Error('Notebook submit returned no run_id');\n const run = await waitForDatabricksRun(client as never, submitted.run_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n const result = (run as { state?: { result_state?: string } }).state?.result_state;\n if (result !== 'SUCCESS') throw new Error(`Notebook run ended in ${result ?? 'UNKNOWN'}`);\n return { runId: submitted.run_id, notebookPath: env.DBX_TEST_NOTEBOOK_PATH };\n },\n };\n}\n\nexport function dbtBuildCheck(): LiveCheck {\n return {\n id: 'dbt',\n description: 'Databricks dbt task reaches SUCCESS',\n configured: (env) => Boolean(env.DBX_TEST_DBT_GIT_URL && env.DATABRICKS_WAREHOUSE_ID),\n async run({ env, client }) {\n if (!env.DBX_TEST_DBT_GIT_URL || !env.DATABRICKS_WAREHOUSE_ID) {\n throw new Error('dbt build requires DBX_TEST_DBT_GIT_URL and DATABRICKS_WAREHOUSE_ID');\n }\n const submitted = await client.post<{ run_id?: number }>('/api/2.1/jobs/runs/submit', {\n run_name: `fabric-experiments-dbt-${Date.now()}`,\n git_source: {\n git_url: env.DBX_TEST_DBT_GIT_URL,\n git_provider: env.DBX_TEST_DBT_GIT_PROVIDER ?? 'gitHub',\n git_branch: env.DBX_TEST_DBT_GIT_BRANCH ?? 'main',\n },\n tasks: [\n {\n task_key: 'dbt_build',\n dbt_task: {\n commands: ['dbt deps', 'dbt build'],\n warehouse_id: env.DATABRICKS_WAREHOUSE_ID,\n ...(env.DBX_TEST_DBT_PROJECT_DIR\n ? { project_directory: env.DBX_TEST_DBT_PROJECT_DIR }\n : {}),\n },\n },\n ],\n });\n if (!submitted.run_id) throw new Error('dbt submit returned no run_id');\n const run = await waitForDatabricksRun(client as never, submitted.run_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n const result = (run as { state?: { result_state?: string } }).state?.result_state;\n if (result !== 'SUCCESS') throw new Error(`dbt run ended in ${result ?? 'UNKNOWN'}`);\n return { runId: submitted.run_id, gitUrl: env.DBX_TEST_DBT_GIT_URL };\n },\n };\n}\n\n/** Wrap product-specific checks such as Auto Loader, Lakebase, notebooks, or dbt. */\nexport function customLiveCheck(\n id: string,\n description: string,\n run: LiveCheck['run'],\n configured?: LiveCheck['configured'],\n): LiveCheck {\n return { id, description, run, ...(configured ? { configured } : {}) };\n}\n","import {\n LakebaseDatabaseProvider,\n type LakebasePoolFactory,\n exchangeLakebaseCredential,\n} from '@fabricorg/experiments-db-pool';\nimport type { LiveCheck } from './live-suite.js';\nimport { resolveTokenProvider } from './workspace-context.js';\n\nexport interface LakebaseCheckOptions {\n fetchImpl?: typeof fetch;\n poolFactory?: LakebasePoolFactory;\n}\n\nfunction required(env: Record<string, string | undefined>, name: string): string {\n const value = env[name]?.trim();\n if (!value) throw new Error(`${name} is required`);\n return value;\n}\n\nexport function createLakebaseTestProvider(\n env: Record<string, string | undefined>,\n options: LakebaseCheckOptions = {},\n): LakebaseDatabaseProvider {\n return new LakebaseDatabaseProvider({\n host: required(env, 'DBX_TEST_LAKEBASE_HOST'),\n database: required(env, 'DBX_TEST_LAKEBASE_DATABASE'),\n user: required(env, 'DBX_TEST_LAKEBASE_USER'),\n workspaceHost: required(env, 'DATABRICKS_HOST'),\n endpoint: required(env, 'DBX_TEST_LAKEBASE_ENDPOINT'),\n token: resolveTokenProvider(required(env, 'DATABRICKS_HOST'), env, options.fetchImpl),\n fetchImpl: options.fetchImpl,\n poolFactory: options.poolFactory,\n max: 1,\n });\n}\n\nasync function workspaceToken(\n env: Record<string, string | undefined>,\n fetchImpl?: typeof fetch,\n): Promise<string> {\n const host = required(env, 'DATABRICKS_HOST');\n const provider = resolveTokenProvider(host, env, fetchImpl);\n return typeof provider === 'string' ? provider : provider();\n}\n\n/** Verify the workspace identity can exchange a short-lived Lakebase credential. */\nexport function lakebaseCredentialCheck(options: LakebaseCheckOptions = {}): LiveCheck {\n return {\n id: 'lakebase-credential',\n description: 'Lakebase OAuth credential exchange',\n configured: (env) => Boolean(env.DBX_TEST_LAKEBASE_ENDPOINT),\n async run({ env }) {\n const credential = await exchangeLakebaseCredential({\n workspaceHost: required(env, 'DATABRICKS_HOST'),\n endpoint: required(env, 'DBX_TEST_LAKEBASE_ENDPOINT'),\n workspaceToken: await workspaceToken(env, options.fetchImpl),\n fetchImpl: options.fetchImpl,\n });\n if (credential.expiresAt <= Date.now()) {\n throw new Error('Lakebase credential is already expired');\n }\n return { expiresAt: new Date(credential.expiresAt).toISOString() };\n },\n };\n}\n\n/** Exercise the production provider before and after an explicit credential/pool refresh. */\nexport function lakebaseRoundTripCheck(options: LakebaseCheckOptions = {}): LiveCheck {\n return {\n id: 'lakebase',\n description: 'Lakebase provider query and credential refresh round-trip',\n configured: (env) =>\n Boolean(\n env.DBX_TEST_LAKEBASE_ENDPOINT &&\n env.DBX_TEST_LAKEBASE_HOST &&\n env.DBX_TEST_LAKEBASE_DATABASE &&\n env.DBX_TEST_LAKEBASE_USER,\n ),\n async run({ env }) {\n const provider = createLakebaseTestProvider(env, options);\n try {\n const first = await provider\n .getPool()\n .query<{ dbx_test_ok: number }>('SELECT 1 AS dbx_test_ok');\n if (Number(first.rows[0]?.dbx_test_ok) !== 1) {\n throw new Error('Lakebase round-trip returned an unexpected value');\n }\n await provider.refreshCredentials();\n const second = await provider\n .getPool()\n .query<{ dbx_test_ok: number }>('SELECT 1 AS dbx_test_ok');\n if (Number(second.rows[0]?.dbx_test_ok) !== 1) {\n throw new Error('Lakebase post-refresh round-trip returned an unexpected value');\n }\n return { queries: 2, refreshed: true };\n } finally {\n await provider.close();\n }\n },\n };\n}\n","import { resolveTokenProvider } from './workspace-context.js';\n\nexport async function databricksFetch(\n env: Record<string, string | undefined>,\n pathOrUrl: string,\n init: RequestInit = {},\n fetchImpl: typeof fetch = fetch,\n): Promise<Response> {\n const host = env.DATABRICKS_HOST?.replace(/\\/$/, '');\n if (!host) throw new Error('DATABRICKS_HOST is required');\n const provider = resolveTokenProvider(host, env, fetchImpl);\n const token = typeof provider === 'string' ? provider : await provider();\n const headers = new Headers(init.headers);\n headers.set('authorization', `Bearer ${token}`);\n const response = await fetchImpl(\n /^https?:\\/\\//.test(pathOrUrl) ? pathOrUrl : `${host}${pathOrUrl}`,\n {\n ...init,\n headers,\n },\n );\n if (!response.ok) {\n const body = await response.text();\n throw new Error(\n `Databricks request failed: ${response.status} ${response.statusText}: ${body.slice(0, 500)}`,\n );\n }\n return response;\n}\n","import { databricksFetch } from './databricks-http.js';\nimport type { LiveCheck } from './live-suite.js';\n\nfunction csv(value: string | undefined): string[] {\n return (value ?? '')\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\n/** Assert secret key metadata only; values are never requested. */\nexport function secretScopeCheck(): LiveCheck {\n return {\n id: 'secrets',\n description: 'Databricks secret scope contains expected keys',\n configured: (env) => Boolean(env.DBX_TEST_SECRET_SCOPE && env.DBX_TEST_SECRET_KEYS),\n async run({ env, client }) {\n const scope = env.DBX_TEST_SECRET_SCOPE as string;\n const expected = csv(env.DBX_TEST_SECRET_KEYS);\n const response = await client.get<{ secrets?: { key?: string }[] }>('/api/2.0/secrets/list', {\n scope,\n });\n const actual = new Set((response.secrets ?? []).map((secret) => secret.key).filter(Boolean));\n const missing = expected.filter((key) => !actual.has(key));\n if (missing.length > 0) {\n throw new Error(`Secret scope ${scope} is missing keys: ${missing.join(', ')}`);\n }\n return { scope, expectedKeys: expected.length };\n },\n };\n}\n\nexport interface AppHealthCheckOptions {\n fetchImpl?: typeof fetch;\n}\n\n/** Verify app state, resource bindings, and the gateway-authenticated application health route. */\nexport function appHealthCheck(options: AppHealthCheckOptions = {}): LiveCheck {\n return {\n id: 'app',\n description: 'Databricks App is running, bound, and healthy',\n configured: (env) => Boolean(env.DBX_TEST_APP_NAME),\n async run({ env, client }) {\n const name = env.DBX_TEST_APP_NAME as string;\n const app = await client.get<{\n app_status?: { state?: string };\n resources?: { name?: string }[];\n url?: string;\n app_url?: string;\n }>(`/api/2.0/apps/${encodeURIComponent(name)}`);\n if (app.app_status?.state !== 'RUNNING') {\n throw new Error(`Databricks App ${name} is ${app.app_status?.state ?? 'UNKNOWN'}`);\n }\n const expected = csv(env.DBX_TEST_APP_RESOURCES);\n const actual = new Set(\n (app.resources ?? []).map((resource) => resource.name).filter(Boolean),\n );\n const missing = expected.filter((resource) => !actual.has(resource));\n if (missing.length > 0) {\n throw new Error(\n `Databricks App ${name} is missing resource bindings: ${missing.join(', ')}`,\n );\n }\n const appUrl = env.DBX_TEST_APP_URL ?? app.url ?? app.app_url;\n if (!appUrl) throw new Error(`Databricks App ${name} returned no URL`);\n const healthUrl = new URL('/api/healthz', appUrl).toString();\n const response = await databricksFetch(env, healthUrl, {}, options.fetchImpl);\n const health = (await response.json()) as { ok?: boolean; status?: string };\n if (health.ok !== true && health.status !== 'ok') {\n throw new Error(`Databricks App ${name} health probe did not report ok`);\n }\n return { name, bindings: actual.size, health: 'ok' };\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport { databricksFetch } from './databricks-http.js';\nimport type { LiveCheck } from './live-suite.js';\n\nexport interface VolumeIOCheckOptions {\n fetchImpl?: typeof fetch;\n randomId?: () => string;\n}\n\nexport function normalizeVolumeRoot(value: string): string {\n const normalized = value.replace(/\\/$/, '');\n if (!/^\\/Volumes\\/[^/]+\\/[^/]+\\/[^/]+$/.test(normalized)) {\n throw new Error('DBX_TEST_VOLUME must be /Volumes/<catalog>/<schema>/<volume>');\n }\n return normalized;\n}\n\nexport async function ensureVolumeDirectory(\n env: Record<string, string | undefined>,\n directory: string,\n fetchImpl?: typeof fetch,\n): Promise<void> {\n await databricksFetch(env, `/api/2.0/fs/directories${directory}`, { method: 'PUT' }, fetchImpl);\n}\n\nexport async function uploadVolumeFile(\n env: Record<string, string | undefined>,\n path: string,\n body: BodyInit | Uint8Array,\n fetchImpl?: typeof fetch,\n): Promise<void> {\n await databricksFetch(\n env,\n `/api/2.0/fs/files${path}`,\n { method: 'PUT', body: body as BodyInit },\n fetchImpl,\n );\n}\n\nexport async function deleteVolumeFile(\n env: Record<string, string | undefined>,\n path: string,\n fetchImpl?: typeof fetch,\n): Promise<void> {\n await databricksFetch(env, `/api/2.0/fs/files${path}`, { method: 'DELETE' }, fetchImpl);\n}\n\n/** Upload, download, and delete a small probe through the Databricks Files API. */\nexport function volumeIOCheck(options: VolumeIOCheckOptions = {}): LiveCheck {\n return {\n id: 'volume-io',\n description: 'Unity Catalog volume Files API round-trip',\n configured: (env) => Boolean(env.DBX_TEST_VOLUME),\n async run({ env }) {\n const root = normalizeVolumeRoot(env.DBX_TEST_VOLUME as string);\n const prefix = (env.DBX_TEST_ENV_NAME ?? 'fx-live').replace(/[^A-Za-z0-9_.-]/g, '_');\n const id = (options.randomId ?? randomUUID)();\n const directory = `${root}/${prefix}`;\n const file = `${directory}/probe-${id}.txt`;\n const filePath = `/api/2.0/fs/files${file}`;\n const body = new TextEncoder().encode(`fabric-experiments-volume-probe:${id}`);\n await ensureVolumeDirectory(env, directory, options.fetchImpl);\n try {\n await uploadVolumeFile(env, file, body, options.fetchImpl);\n const downloaded = await databricksFetch(env, filePath, {}, options.fetchImpl);\n const actual = new Uint8Array(await downloaded.arrayBuffer());\n if (actual.length !== body.length || actual.some((value, index) => value !== body[index])) {\n throw new Error('Volume round-trip returned different bytes');\n }\n return { volume: root, bytes: body.length };\n } finally {\n await deleteVolumeFile(env, file, options.fetchImpl).catch(() => undefined);\n }\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { basename, resolve } from 'node:path';\nimport type { LiveCheck } from './live-suite.js';\nimport { waitForPipelineUpdate } from './pollers.js';\nimport {\n deleteVolumeFile,\n ensureVolumeDirectory,\n normalizeVolumeRoot,\n uploadVolumeFile,\n} from './volume-checks.js';\n\nexport interface AutoLoaderCheckOptions {\n fetchImpl?: typeof fetch;\n fixtureBody?: Uint8Array;\n randomId?: () => string;\n}\n\n/** Exercise Files API -> isolated Lakeflow pipeline -> Delta output. */\nexport function autoLoaderIngestionCheck(options: AutoLoaderCheckOptions = {}): LiveCheck {\n return {\n id: 'autoloader',\n description: 'Isolated Auto Loader fixture ingestion reaches Delta without rescued rows',\n configured: (env) =>\n Boolean(\n env.DBX_TEST_AUTOLOADER_PIPELINE_ID &&\n env.DBX_TEST_AUTOLOADER_TABLE &&\n env.DBX_TEST_AUTOLOADER_FIXTURE &&\n env.DBX_TEST_VOLUME,\n ),\n async run({ env, client, warehouse }) {\n const pipelineId = env.DBX_TEST_AUTOLOADER_PIPELINE_ID as string;\n if (pipelineId === env.DBX_TEST_PIPELINE_ID) {\n throw new Error('DBX_TEST_AUTOLOADER_PIPELINE_ID must not be the production pipeline');\n }\n const root = normalizeVolumeRoot(env.DBX_TEST_VOLUME as string);\n const fixturePath = env.DBX_TEST_AUTOLOADER_FIXTURE as string;\n const body = options.fixtureBody ?? new Uint8Array(await readFile(resolve(fixturePath)));\n const id = (options.randomId ?? randomUUID)();\n const runName = (env.DBX_TEST_ENV_NAME ?? 'autoloader').replace(/[^A-Za-z0-9_.-]/g, '_');\n const directory = `${root}/exposures/${runName}/${id}`;\n const destination = `${directory}/${basename(fixturePath)}`;\n await ensureVolumeDirectory(env, directory, options.fetchImpl);\n try {\n await uploadVolumeFile(env, destination, body, options.fetchImpl);\n const submitted = await client.post<{ update_id?: string }>(\n `/api/2.0/pipelines/${encodeURIComponent(pipelineId)}/updates`,\n { full_refresh: true },\n );\n if (!submitted.update_id) throw new Error('Auto Loader pipeline returned no update_id');\n await waitForPipelineUpdate(client, pipelineId, submitted.update_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n const table = env.DBX_TEST_AUTOLOADER_TABLE as string;\n const rows = await warehouse.query(\n `SELECT COUNT(*) AS n, SUM(CASE WHEN _rescued_data IS NOT NULL THEN 1 ELSE 0 END) AS rescued FROM ${table}`,\n );\n const count = Number(rows[0]?.n ?? 0);\n const rescued = Number(rows[0]?.rescued ?? 0);\n if (count < 1) throw new Error(`Auto Loader produced no rows in ${table}`);\n if (rescued !== 0)\n throw new Error(`Auto Loader produced ${rescued} rescued rows in ${table}`);\n return { pipelineId, table, rows: count, rescued };\n } finally {\n await deleteVolumeFile(env, destination, options.fetchImpl).catch(() => undefined);\n }\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/assert.ts","../src/mock-client.ts","../src/live-suite.ts","../src/pollers.ts","../src/live-checks.ts","../src/lakebase-checks.ts","../src/lakebase-branch.ts","../src/databricks-http.ts","../src/platform-checks.ts","../src/volume-checks.ts","../src/autoloader-checks.ts"],"names":["createDuckDbContext","createWorkspaceContext","required","resolve","randomUUID"],"mappings":"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","file":"index.js","sourcesContent":["import type { TableFixture } from './fixtures.js';\n\nexport type TestProfile = 'local' | 'live';\n\n/**\n * One SQL surface, two engines (ADR-0006). `local` executes on DuckDB\n * in-process; `live` executes on a Databricks SQL warehouse via the SQL\n * Statement Execution API. Params are positional `?` in both profiles — the\n * workspace context transparently rewrites them to the named markers the\n * Statement Execution API requires.\n */\nexport interface ExecutionContext {\n readonly profile: TestProfile;\n /** Execute a statement, discarding any result. */\n exec(sql: string, params?: readonly unknown[]): Promise<void>;\n /** Execute a query and return normalized row objects (bigint→number, timestamps→ISO). */\n query(sql: string, params?: readonly unknown[]): Promise<Record<string, unknown>[]>;\n /** Create + seed a table from a declarative fixture. */\n loadFixture(fixture: TableFixture): Promise<void>;\n /** Qualify a bare table name for this context (schema/catalog scoping). */\n qual(table: string): string;\n close(): Promise<void>;\n}\n\nexport function resolveProfile(env: Record<string, string | undefined> = process.env): TestProfile {\n const profile = env.DBX_TEST_PROFILE ?? 'local';\n if (profile !== 'local' && profile !== 'live') {\n throw new Error(`DBX_TEST_PROFILE must be 'local' or 'live', got '${profile}'`);\n }\n if (profile === 'live' && env.DBX_TEST_LIVE !== '1') {\n throw new Error(\n 'DBX_TEST_PROFILE=live requires DBX_TEST_LIVE=1 (live suites are always gated)',\n );\n }\n return profile;\n}\n\nexport interface CreateContextOptions {\n profile?: TestProfile;\n env?: Record<string, string | undefined>;\n /** local profile: schema to create + qualify tables with. live profile: schema within the catalog. */\n schema?: string;\n /** Live profile only: observe each submitted SQL statement. */\n onStatement?: (statement: { sql: string; statementId?: string }) => void;\n}\n\n/** Profile-dispatched factory. Lazy-imports each engine so the unused one stays out of the bundle. */\nexport async function createExecutionContext(\n options: CreateContextOptions = {},\n): Promise<ExecutionContext> {\n const env = options.env ?? process.env;\n const profile = options.profile ?? resolveProfile(env);\n if (profile === 'local') {\n const { createDuckDbContext } = await import('./duckdb-context.js');\n return createDuckDbContext({ schema: options.schema });\n }\n const { createWorkspaceContext } = await import('./workspace-context.js');\n return createWorkspaceContext({\n env,\n schema: options.schema,\n ...(options.onStatement ? { onStatement: options.onStatement } : {}),\n });\n}\n","import type { ExecutionContext } from './context.js';\nimport { compareToGolden } from './golden.js';\n\n/**\n * Framework-free table assertions — they throw plain Errors so they work\n * under vitest, cucumber-js steps, or the live check runner alike.\n */\nexport function expectTable(ctx: ExecutionContext, table: string) {\n const target = ctx.qual(table);\n return {\n async toHaveRowCount(expected: number): Promise<void> {\n const rows = await ctx.query(`SELECT COUNT(*) AS n FROM ${target}`);\n const actual = Number(rows[0]?.n ?? Number.NaN);\n if (actual !== expected) {\n throw new Error(`Expected ${target} to have ${expected} rows, found ${actual}`);\n }\n },\n\n /** Every partial row must match at least one table row on its own keys. */\n async toContainRows(partials: readonly Record<string, unknown>[]): Promise<void> {\n const rows = await ctx.query(`SELECT * FROM ${target}`);\n for (const partial of partials) {\n const hit = rows.some((row) =>\n Object.entries(partial).every(([key, value]) => looselyEqual(row[key], value)),\n );\n if (!hit) {\n throw new Error(\n `Expected ${target} to contain a row matching ${JSON.stringify(partial)}; ` +\n `have ${rows.length} rows: ${JSON.stringify(rows.slice(0, 5))}${rows.length > 5 ? ' …' : ''}`,\n );\n }\n }\n },\n\n /**\n * Compare `SELECT * ORDER BY <orderBy>` against a committed golden JSON\n * file. Set DBX_TEST_UPDATE_GOLDEN=1 to (re)write the golden instead —\n * a reviewable, versioned event.\n */\n async toMatchGolden(goldenPath: string, options: { orderBy?: string } = {}): Promise<void> {\n const orderBy = options.orderBy ? ` ORDER BY ${options.orderBy}` : '';\n const rows = await ctx.query(`SELECT * FROM ${target}${orderBy}`);\n await compareToGolden(goldenPath, rows, `table ${target}`);\n },\n };\n}\n\n/** Compare query results (not a whole table) against a golden file. */\nexport async function expectQueryToMatchGolden(\n ctx: ExecutionContext,\n sql: string,\n params: readonly unknown[],\n goldenPath: string,\n): Promise<void> {\n const rows = await ctx.query(sql, params);\n await compareToGolden(goldenPath, rows, 'query');\n}\n\nfunction looselyEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a === 'number' && typeof b === 'number') return Math.abs(a - b) < 1e-9;\n // Timestamps normalize to 'YYYY-MM-DD HH:MM:SS'; allow ISO-style expectations.\n if (typeof a === 'string' && typeof b === 'string') {\n return (\n a.replace('T', ' ').replace(/(\\.\\d+)?Z?$/, '') ===\n b.replace('T', ' ').replace(/(\\.\\d+)?Z?$/, '')\n );\n }\n return false;\n}\n","/**\n * Framework-free fake of the Databricks REST client surface, for unit tests\n * of orchestration logic (submit → poll → terminal). Queue responses per\n * (method, path-prefix); every call is recorded for assertions. Works under\n * vitest without vi.fn so it is equally usable from cucumber-js worlds.\n */\nexport interface RecordedCall {\n method: 'GET' | 'POST' | 'DELETE';\n path: string;\n body?: unknown;\n query?: Record<string, string | number | boolean | undefined>;\n}\n\nexport interface MockDatabricksClient {\n get<T>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T>;\n post<T>(\n path: string,\n body?: unknown,\n query?: Record<string, string | number | boolean | undefined>,\n options?: unknown,\n ): Promise<T>;\n request<T>(\n method: 'GET' | 'POST' | 'DELETE',\n path: string,\n body?: unknown,\n query?: Record<string, string | number | boolean | undefined>,\n options?: unknown,\n ): Promise<T>;\n /** Queue the next response for calls whose path starts with `pathPrefix`. FIFO per prefix. */\n queue(\n method: 'GET' | 'POST' | 'DELETE',\n pathPrefix: string,\n response: unknown,\n ): MockDatabricksClient;\n /** Queue an error for the next matching call. */\n queueError(\n method: 'GET' | 'POST' | 'DELETE',\n pathPrefix: string,\n error: Error,\n ): MockDatabricksClient;\n readonly calls: readonly RecordedCall[];\n callsTo(method: 'GET' | 'POST' | 'DELETE', pathPrefix: string): RecordedCall[];\n}\n\ntype Queued = { pathPrefix: string; response?: unknown; error?: Error };\n\nexport function createMockDatabricksClient(): MockDatabricksClient {\n const queues: Record<'GET' | 'POST' | 'DELETE', Queued[]> = { GET: [], POST: [], DELETE: [] };\n const calls: RecordedCall[] = [];\n\n function take(method: 'GET' | 'POST' | 'DELETE', path: string): Queued {\n const index = queues[method].findIndex((q) => path.startsWith(q.pathPrefix));\n if (index === -1) {\n throw new Error(\n `MockDatabricksClient: no queued ${method} response for ${path}. ` +\n `Queued prefixes: ${queues[method].map((q) => q.pathPrefix).join(', ') || '(none)'}`,\n );\n }\n return queues[method].splice(index, 1)[0] as Queued;\n }\n\n const client: MockDatabricksClient = {\n async get<T>(path: string, query?: Record<string, string | number | boolean | undefined>) {\n calls.push({ method: 'GET', path, query });\n const queued = take('GET', path);\n if (queued.error) throw queued.error;\n return queued.response as T;\n },\n async post<T>(\n path: string,\n body?: unknown,\n query?: Record<string, string | number | boolean | undefined>,\n ) {\n calls.push({ method: 'POST', path, body, query });\n const queued = take('POST', path);\n if (queued.error) throw queued.error;\n return queued.response as T;\n },\n async request<T>(\n method: 'GET' | 'POST' | 'DELETE',\n path: string,\n body?: unknown,\n query?: Record<string, string | number | boolean | undefined>,\n ) {\n calls.push({ method, path, body, query });\n const queued = take(method, path);\n if (queued.error) throw queued.error;\n return queued.response as T;\n },\n queue(method, pathPrefix, response) {\n queues[method].push({ pathPrefix, response });\n return client;\n },\n queueError(method, pathPrefix, error) {\n queues[method].push({ pathPrefix, error });\n return client;\n },\n calls,\n callsTo(method, pathPrefix) {\n return calls.filter((c) => c.method === method && c.path.startsWith(pathPrefix));\n },\n };\n return client;\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { ExecutionContext } from './context.js';\nimport {\n type WorkspaceClientLike,\n createClientFromEnv,\n createWorkspaceContext,\n} from './workspace-context.js';\n\nexport type LiveCheckStatus = 'pass' | 'fail' | 'not-configured';\n\nexport interface LiveCheckContext {\n env: Record<string, string | undefined>;\n warehouse: ExecutionContext;\n client: WorkspaceClientLike;\n}\n\nexport interface LiveCheck {\n id: string;\n description: string;\n configured?: (env: Record<string, string | undefined>) => boolean;\n run(context: LiveCheckContext): Promise<unknown>;\n}\n\nexport interface LiveCheckResult {\n id: string;\n description: string;\n status: LiveCheckStatus;\n durationMs: number;\n details?: unknown;\n error?: string;\n}\n\nexport interface LiveEvidence {\n schemaVersion: 1;\n kind: 'databricks-live-suite';\n startedAt: string;\n finishedAt: string;\n success: boolean;\n required: string[];\n results: LiveCheckResult[];\n}\n\nexport interface LiveSuiteSpec {\n checks: readonly LiveCheck[];\n required?: readonly string[];\n evidencePath?: string;\n junitPath?: string;\n env?: Record<string, string | undefined>;\n}\n\nexport interface LiveSuiteRuntime {\n warehouse?: ExecutionContext;\n client?: WorkspaceClientLike;\n}\n\nexport interface DefinedLiveSuite {\n run(runtime?: LiveSuiteRuntime): Promise<LiveEvidence | undefined>;\n}\n\n/**\n * Define an explicitly gated live suite. Without DBX_TEST_LIVE=1, run() is a\n * silent no-op so the same command is safe in ordinary CI matrices.\n */\nexport function defineLiveSuite(spec: LiveSuiteSpec): DefinedLiveSuite {\n return { run: (runtime) => runLiveSuite(spec, runtime) };\n}\n\nexport async function runLiveSuite(\n spec: LiveSuiteSpec,\n runtime: LiveSuiteRuntime = {},\n): Promise<LiveEvidence | undefined> {\n const env = spec.env ?? process.env;\n if (env.DBX_TEST_LIVE !== '1') return undefined;\n\n const required = [...(spec.required ?? [])];\n const known = new Set(spec.checks.map((check) => check.id));\n for (const id of required) {\n if (!known.has(id)) throw new Error(`Required live check '${id}' is not defined`);\n }\n\n const startedAt = new Date().toISOString();\n const ownedWarehouse = runtime.warehouse === undefined;\n const client = runtime.client ?? createClientFromEnv(env);\n const warehouse = runtime.warehouse ?? (await createWorkspaceContext({ env, client }));\n const results: LiveCheckResult[] = [];\n\n try {\n for (const check of spec.checks) {\n if (check.configured && !check.configured(env)) {\n results.push({\n id: check.id,\n description: check.description,\n status: 'not-configured',\n durationMs: 0,\n });\n continue;\n }\n const before = performance.now();\n try {\n const details = await check.run({ env, warehouse, client });\n results.push({\n id: check.id,\n description: check.description,\n status: 'pass',\n durationMs: Math.round(performance.now() - before),\n ...(details === undefined ? {} : { details: redactValue(details, env) }),\n });\n } catch (error) {\n results.push({\n id: check.id,\n description: check.description,\n status: 'fail',\n durationMs: Math.round(performance.now() - before),\n error: redactText(error instanceof Error ? error.message : String(error), env),\n });\n }\n }\n } finally {\n if (ownedWarehouse) await warehouse.close();\n }\n\n const success = required.every(\n (id) => results.find((result) => result.id === id)?.status === 'pass',\n );\n const evidence: LiveEvidence = {\n schemaVersion: 1,\n kind: 'databricks-live-suite',\n startedAt,\n finishedAt: new Date().toISOString(),\n success,\n required,\n results,\n };\n\n if (spec.evidencePath)\n await writeReport(spec.evidencePath, `${JSON.stringify(evidence, null, 2)}\\n`);\n if (spec.junitPath) await writeReport(spec.junitPath, renderJUnit(evidence));\n return evidence;\n}\n\nasync function writeReport(path: string, contents: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, contents, 'utf8');\n}\n\nfunction redactText(text: string, env: Record<string, string | undefined>): string {\n let output = text;\n for (const [name, value] of Object.entries(env)) {\n if (!value || value.length < 6 || !/(TOKEN|SECRET|PASSWORD|BEARER|KEY)/i.test(name)) continue;\n output = output.split(value).join('[REDACTED]');\n }\n return output;\n}\n\nfunction redactValue(value: unknown, env: Record<string, string | undefined>): unknown {\n return JSON.parse(redactText(JSON.stringify(value), env)) as unknown;\n}\n\nfunction xml(value: string): string {\n return value\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('\"', '"')\n .replaceAll(\"'\", ''');\n}\n\nexport function renderJUnit(evidence: LiveEvidence): string {\n const failures = evidence.results.filter((result) => result.status === 'fail').length;\n const skipped = evidence.results.filter((result) => result.status === 'not-configured').length;\n const seconds = evidence.results.reduce((sum, result) => sum + result.durationMs, 0) / 1000;\n const cases = evidence.results\n .map((result) => {\n const body =\n result.status === 'fail'\n ? `<failure message=\"${xml(result.error ?? 'check failed')}\"/>`\n : result.status === 'not-configured'\n ? '<skipped message=\"not configured\"/>'\n : '';\n return ` <testcase classname=\"databricks-live\" name=\"${xml(result.id)}\" time=\"${result.durationMs / 1000}\">${body}</testcase>`;\n })\n .join('\\n');\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<testsuite name=\"databricks-live\" tests=\"${evidence.results.length}\" failures=\"${failures}\" skipped=\"${skipped}\" time=\"${seconds}\">\\n${cases}\\n</testsuite>\\n`;\n}\n","import type { WorkspaceClientLike } from './workspace-context.js';\n\nexport interface PollOptions {\n pollIntervalMs?: number;\n timeoutMs?: number;\n signal?: AbortSignal;\n}\n\nconst TERMINAL_PIPELINE_STATES = new Set(['COMPLETED', 'FAILED', 'CANCELED']);\n\nexport async function waitForPipelineUpdate(\n client: WorkspaceClientLike,\n pipelineId: string,\n updateId: string,\n options: PollOptions = {},\n): Promise<Record<string, unknown>> {\n const deadline = Date.now() + (options.timeoutMs ?? 900_000);\n const interval = options.pollIntervalMs ?? 10_000;\n const path = `/api/2.0/pipelines/${encodeURIComponent(pipelineId)}/updates/${encodeURIComponent(updateId)}`;\n let update: { update?: { state?: string } } = await client.get(path);\n while (!TERMINAL_PIPELINE_STATES.has(update.update?.state ?? '') && Date.now() < deadline) {\n if (options.signal?.aborted) throw new Error(`Pipeline update ${updateId} was aborted`);\n await abortableDelay(interval, options.signal);\n update = await client.get(path);\n }\n const state = update.update?.state ?? 'UNKNOWN';\n if (state !== 'COMPLETED') {\n throw new Error(`Pipeline update ${updateId} ended in ${state} (wanted COMPLETED)`);\n }\n return update as Record<string, unknown>;\n}\n\nfunction abortableDelay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error('Polling aborted'));\n return;\n }\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n reject(new Error('Polling aborted'));\n },\n { once: true },\n );\n });\n}\n","import { waitForDatabricksRun } from '@fabric-harness/databricks';\nimport type { LiveCheck } from './live-suite.js';\nimport { waitForPipelineUpdate } from './pollers.js';\n\nexport function sqlRoundTripCheck(): LiveCheck {\n return {\n id: 'sql',\n description: 'SQL Statement Execution round-trip',\n async run({ warehouse }) {\n const rows = await warehouse.query('SELECT 1 AS dbx_test_ok');\n if (Number(rows[0]?.dbx_test_ok) !== 1)\n throw new Error('SQL round-trip returned an unexpected value');\n return { rows: rows.length };\n },\n };\n}\n\n/** Fail closed if governance checks accidentally run with bootstrap or administrator credentials. */\nexport function restrictedPrincipalCheck(): LiveCheck {\n return {\n id: 'restricted-principal',\n description: 'Live checks use the designated least-privilege service principal',\n configured: (env) => Boolean(env.DBX_TEST_RESTRICTED_PRINCIPAL_ID),\n async run({ env }) {\n const expected = env.DBX_TEST_RESTRICTED_PRINCIPAL_ID?.toLowerCase();\n const actual = env.DATABRICKS_CLIENT_ID?.toLowerCase();\n if (!expected || !actual) {\n throw new Error(\n 'Restricted-principal check requires DBX_TEST_RESTRICTED_PRINCIPAL_ID and DATABRICKS_CLIENT_ID',\n );\n }\n if (actual !== expected) {\n throw new Error(`Live suite is using principal '${actual}', expected '${expected}'`);\n }\n return { principalId: actual };\n },\n };\n}\n\nexport interface DeltaColumnContract {\n name: string;\n type?: string;\n}\n\nexport function assertDeltaContract(\n table: string,\n rows: readonly Record<string, unknown>[],\n columns: readonly DeltaColumnContract[],\n): void {\n for (const expected of columns) {\n const actual = rows.find((row) => String(row.col_name ?? row.column_name) === expected.name);\n if (!actual) throw new Error(`Delta contract missing column '${expected.name}' in ${table}`);\n const actualType = String(actual.data_type ?? actual.column_type ?? '').toLowerCase();\n if (expected.type && actualType !== expected.type.toLowerCase()) {\n throw new Error(\n `Delta column ${expected.name} has type ${actualType}, expected ${expected.type}`,\n );\n }\n }\n}\n\nexport function deltaContractCheck(\n tableEnv = 'DBX_TEST_DELTA_TABLE',\n columns: readonly DeltaColumnContract[] = [],\n): LiveCheck {\n return {\n id: 'delta-contract',\n description: 'Delta table schema contract',\n configured: (env) => Boolean(env[tableEnv]),\n async run({ env, warehouse }) {\n const table = env[tableEnv] as string;\n const rows = await warehouse.query(`DESCRIBE TABLE ${table}`);\n assertDeltaContract(table, rows, columns);\n return { table, columns: rows.length };\n },\n };\n}\n\nexport function unityCatalogAccessCheck(): LiveCheck {\n return {\n id: 'uc-grants',\n description: 'Unity Catalog allow/deny access assertions',\n configured: (env) => Boolean(env.DBX_TEST_UC_ALLOWED_TABLE && env.DBX_TEST_UC_DENIED_TABLE),\n async run({ env, warehouse }) {\n await warehouse.query(`SELECT * FROM ${env.DBX_TEST_UC_ALLOWED_TABLE} LIMIT 1`);\n try {\n await warehouse.query(`SELECT * FROM ${env.DBX_TEST_UC_DENIED_TABLE} LIMIT 1`);\n } catch (error) {\n if (/permission.?denied|insufficient.?priv|403|unauthoriz/i.test(String(error))) {\n return { allowed: env.DBX_TEST_UC_ALLOWED_TABLE, denied: env.DBX_TEST_UC_DENIED_TABLE };\n }\n throw error;\n }\n throw new Error(`Expected access to ${env.DBX_TEST_UC_DENIED_TABLE} to be denied`);\n },\n };\n}\n\nexport function jobRunCheck(): LiveCheck {\n return {\n id: 'jobs',\n description: 'Databricks Job run-now reaches SUCCESS',\n configured: (env) => Boolean(env.DBX_TEST_JOB_ID),\n async run({ env, client }) {\n const jobId = Number(env.DBX_TEST_JOB_ID);\n if (!Number.isFinite(jobId)) throw new Error('DBX_TEST_JOB_ID must be numeric');\n const submitted = await client.post<{ run_id: number }>('/api/2.1/jobs/run-now', {\n job_id: jobId,\n });\n const run = await waitForDatabricksRun(client as never, submitted.run_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n const result = (run as { state?: { result_state?: string } }).state?.result_state;\n if (result !== 'SUCCESS') throw new Error(`Job ${jobId} ended in ${result ?? 'UNKNOWN'}`);\n return { jobId, runId: submitted.run_id };\n },\n };\n}\n\n/** Trigger the deployed Lakeflow pipeline and require a completed update. */\nexport function pipelineRefreshCheck(): LiveCheck {\n return {\n id: 'pipeline',\n description: 'Lakeflow telemetry pipeline refresh reaches COMPLETED',\n configured: (env) => Boolean(env.DBX_TEST_PIPELINE_ID),\n async run({ env, client }) {\n const pipelineId = env.DBX_TEST_PIPELINE_ID as string;\n const submitted = await client.post<{ update_id?: string }>(\n `/api/2.0/pipelines/${encodeURIComponent(pipelineId)}/updates`,\n { full_refresh: false },\n );\n if (!submitted.update_id) {\n throw new Error(`Pipeline ${pipelineId} did not return an update_id`);\n }\n await waitForPipelineUpdate(client, pipelineId, submitted.update_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n return { pipelineId, updateId: submitted.update_id };\n },\n };\n}\n\nexport function notebookSubmitCheck(): LiveCheck {\n return {\n id: 'notebook',\n description: 'Databricks notebook submit run reaches SUCCESS',\n configured: (env) =>\n Boolean(\n env.DBX_TEST_NOTEBOOK_PATH &&\n (env.DBX_TEST_CLUSTER_ID || env.DBX_TEST_NOTEBOOK_SERVERLESS === '1'),\n ),\n async run({ env, client }) {\n if (\n !env.DBX_TEST_NOTEBOOK_PATH ||\n (!env.DBX_TEST_CLUSTER_ID && env.DBX_TEST_NOTEBOOK_SERVERLESS !== '1')\n ) {\n throw new Error(\n 'Notebook submit requires DBX_TEST_NOTEBOOK_PATH and either DBX_TEST_CLUSTER_ID or DBX_TEST_NOTEBOOK_SERVERLESS=1',\n );\n }\n const submitted = await client.post<{ run_id?: number }>('/api/2.1/jobs/runs/submit', {\n run_name: `fabric-experiments-notebook-${Date.now()}`,\n tasks: [\n {\n task_key: 'notebook',\n ...(env.DBX_TEST_CLUSTER_ID ? { existing_cluster_id: env.DBX_TEST_CLUSTER_ID } : {}),\n notebook_task: { notebook_path: env.DBX_TEST_NOTEBOOK_PATH },\n },\n ],\n });\n if (!submitted.run_id) throw new Error('Notebook submit returned no run_id');\n const run = await waitForDatabricksRun(client as never, submitted.run_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n const result = (run as { state?: { result_state?: string } }).state?.result_state;\n if (result !== 'SUCCESS') throw new Error(`Notebook run ended in ${result ?? 'UNKNOWN'}`);\n return { runId: submitted.run_id, notebookPath: env.DBX_TEST_NOTEBOOK_PATH };\n },\n };\n}\n\nexport function dbtBuildCheck(): LiveCheck {\n return {\n id: 'dbt',\n description: 'Databricks dbt task reaches SUCCESS',\n configured: (env) =>\n Boolean(\n (env.DBX_TEST_DBT_GIT_URL || env.DBX_TEST_DBT_PROJECT_DIR) && env.DATABRICKS_WAREHOUSE_ID,\n ),\n async run({ env, client }) {\n if (\n (!env.DBX_TEST_DBT_GIT_URL && !env.DBX_TEST_DBT_PROJECT_DIR) ||\n !env.DATABRICKS_WAREHOUSE_ID\n ) {\n throw new Error(\n 'dbt build requires DBX_TEST_DBT_GIT_URL or DBX_TEST_DBT_PROJECT_DIR, plus DATABRICKS_WAREHOUSE_ID',\n );\n }\n const sourceVars = JSON.stringify({\n source_catalog: env.DBX_TEST_DBT_SOURCE_CATALOG ?? env.DBX_TEST_CATALOG,\n source_schema: env.DBX_TEST_DBT_SOURCE_SCHEMA,\n });\n const serverless = env.DBX_TEST_DBT_SERVERLESS === '1';\n const request = {\n run_name: `fabric-experiments-dbt-${Date.now()}`,\n ...(env.DBX_TEST_DBT_GIT_URL\n ? {\n git_source: {\n git_url: env.DBX_TEST_DBT_GIT_URL,\n git_provider: env.DBX_TEST_DBT_GIT_PROVIDER ?? 'gitHub',\n git_branch: env.DBX_TEST_DBT_GIT_BRANCH ?? 'main',\n },\n }\n : {}),\n tasks: [\n {\n task_key: 'dbt_build',\n ...(serverless ? { environment_key: 'dbt' } : {}),\n dbt_task: {\n commands: ['dbt deps', `dbt build --vars '${sourceVars}'`],\n warehouse_id: env.DATABRICKS_WAREHOUSE_ID,\n ...(env.DBX_TEST_CATALOG ? { catalog: env.DBX_TEST_CATALOG } : {}),\n ...(env.DBX_TEST_SCHEMA ? { schema: env.DBX_TEST_SCHEMA } : {}),\n ...(env.DBX_TEST_DBT_GIT_URL ? {} : { source: 'WORKSPACE' }),\n ...(env.DBX_TEST_DBT_PROJECT_DIR\n ? { project_directory: env.DBX_TEST_DBT_PROJECT_DIR }\n : {}),\n },\n },\n ],\n ...(serverless\n ? {\n environments: [\n {\n environment_key: 'dbt',\n spec: {\n environment_version: '2',\n dependencies: ['dbt-databricks>=1.8,<2'],\n },\n },\n ],\n }\n : {}),\n };\n const submitted = await client.post<{ run_id?: number }>(\n '/api/2.1/jobs/runs/submit',\n request,\n );\n if (!submitted.run_id) throw new Error('dbt submit returned no run_id');\n const run = await waitForDatabricksRun(client as never, submitted.run_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n const result = (run as { state?: { result_state?: string } }).state?.result_state;\n if (result !== 'SUCCESS') throw new Error(`dbt run ended in ${result ?? 'UNKNOWN'}`);\n return {\n runId: submitted.run_id,\n source: env.DBX_TEST_DBT_GIT_URL ?? env.DBX_TEST_DBT_PROJECT_DIR,\n };\n },\n };\n}\n\n/** Wrap product-specific checks such as Auto Loader, Lakebase, notebooks, or dbt. */\nexport function customLiveCheck(\n id: string,\n description: string,\n run: LiveCheck['run'],\n configured?: LiveCheck['configured'],\n): LiveCheck {\n return { id, description, run, ...(configured ? { configured } : {}) };\n}\n","import {\n LakebaseDatabaseProvider,\n type LakebasePoolFactory,\n exchangeLakebaseCredential,\n} from '@fabricorg/experiments-db-pool';\nimport type { LiveCheck } from './live-suite.js';\nimport { resolveTokenProvider } from './workspace-context.js';\n\nexport interface LakebaseCheckOptions {\n fetchImpl?: typeof fetch;\n poolFactory?: LakebasePoolFactory;\n}\n\nfunction required(env: Record<string, string | undefined>, name: string): string {\n const value = env[name]?.trim();\n if (!value) throw new Error(`${name} is required`);\n return value;\n}\n\nexport function createLakebaseTestProvider(\n env: Record<string, string | undefined>,\n options: LakebaseCheckOptions = {},\n): LakebaseDatabaseProvider {\n return new LakebaseDatabaseProvider({\n host: required(env, 'DBX_TEST_LAKEBASE_HOST'),\n database: required(env, 'DBX_TEST_LAKEBASE_DATABASE'),\n user: required(env, 'DBX_TEST_LAKEBASE_USER'),\n workspaceHost: required(env, 'DATABRICKS_HOST'),\n endpoint: required(env, 'DBX_TEST_LAKEBASE_ENDPOINT'),\n token: resolveTokenProvider(required(env, 'DATABRICKS_HOST'), env, options.fetchImpl),\n fetchImpl: options.fetchImpl,\n poolFactory: options.poolFactory,\n max: 1,\n });\n}\n\nasync function workspaceToken(\n env: Record<string, string | undefined>,\n fetchImpl?: typeof fetch,\n): Promise<string> {\n const host = required(env, 'DATABRICKS_HOST');\n const provider = resolveTokenProvider(host, env, fetchImpl);\n return typeof provider === 'string' ? provider : provider();\n}\n\n/** Verify the workspace identity can exchange a short-lived Lakebase credential. */\nexport function lakebaseCredentialCheck(options: LakebaseCheckOptions = {}): LiveCheck {\n return {\n id: 'lakebase-credential',\n description: 'Lakebase OAuth credential exchange',\n configured: (env) => Boolean(env.DBX_TEST_LAKEBASE_ENDPOINT),\n async run({ env }) {\n const credential = await exchangeLakebaseCredential({\n workspaceHost: required(env, 'DATABRICKS_HOST'),\n endpoint: required(env, 'DBX_TEST_LAKEBASE_ENDPOINT'),\n workspaceToken: await workspaceToken(env, options.fetchImpl),\n fetchImpl: options.fetchImpl,\n });\n if (credential.expiresAt <= Date.now()) {\n throw new Error('Lakebase credential is already expired');\n }\n return { expiresAt: new Date(credential.expiresAt).toISOString() };\n },\n };\n}\n\n/** Exercise the production provider before and after an explicit credential/pool refresh. */\nexport function lakebaseRoundTripCheck(options: LakebaseCheckOptions = {}): LiveCheck {\n return {\n id: 'lakebase',\n description: 'Lakebase provider query and credential refresh round-trip',\n configured: (env) =>\n Boolean(\n env.DBX_TEST_LAKEBASE_ENDPOINT &&\n env.DBX_TEST_LAKEBASE_HOST &&\n env.DBX_TEST_LAKEBASE_DATABASE &&\n env.DBX_TEST_LAKEBASE_USER,\n ),\n async run({ env }) {\n const provider = createLakebaseTestProvider(env, options);\n try {\n const first = await provider\n .getPool()\n .query<{ dbx_test_ok: number }>('SELECT 1 AS dbx_test_ok');\n if (Number(first.rows[0]?.dbx_test_ok) !== 1) {\n throw new Error('Lakebase round-trip returned an unexpected value');\n }\n await provider.refreshCredentials();\n const second = await provider\n .getPool()\n .query<{ dbx_test_ok: number }>('SELECT 1 AS dbx_test_ok');\n if (Number(second.rows[0]?.dbx_test_ok) !== 1) {\n throw new Error('Lakebase post-refresh round-trip returned an unexpected value');\n }\n return { queries: 2, refreshed: true };\n } finally {\n await provider.close();\n }\n },\n };\n}\n","import { createClientFromEnv } from './workspace-context.js';\n\nexport interface LakebaseControlClient {\n get<T>(path: string, query?: Record<string, string | number | boolean | undefined>): Promise<T>;\n post<T>(\n path: string,\n body?: unknown,\n query?: Record<string, string | number | boolean | undefined>,\n ): Promise<T>;\n request<T>(\n method: 'DELETE',\n path: string,\n body?: unknown,\n query?: Record<string, string | number | boolean | undefined>,\n ): Promise<T>;\n}\n\nexport interface EphemeralLakebaseBranch {\n project: string;\n branch: string;\n branchId: string;\n endpoint: string;\n host: string;\n databaseResource: string;\n database: string;\n createdAt: string;\n expiresAt: string;\n}\n\nexport interface LakebaseBranchOptions {\n env?: Record<string, string | undefined>;\n client?: LakebaseControlClient;\n project?: string;\n branchId: string;\n ttlMs: number;\n pollIntervalMs?: number;\n timeoutMs?: number;\n now?: () => Date;\n}\n\ninterface Operation<T = unknown> {\n name?: string;\n done?: boolean;\n error?: { code?: number; message?: string };\n response?: T;\n}\n\ninterface Branch {\n name: string;\n branch_id?: string;\n create_time?: string;\n status?: { current_state?: string };\n}\n\ninterface Endpoint {\n name: string;\n endpoint_id?: string;\n status?: { hosts?: { host?: string }; current_state?: string };\n}\n\ninterface Database {\n name: string;\n status?: { postgres_database?: string };\n}\n\nconst DEFAULT_POLL_INTERVAL_MS = 2_000;\nconst DEFAULT_TIMEOUT_MS = 5 * 60_000;\n\nexport function resolveLakebaseProject(\n env: Record<string, string | undefined>,\n explicit?: string,\n): string {\n const project = explicit ?? env.DBX_TEST_LAKEBASE_PROJECT;\n if (!project || !/^projects\\/[a-z0-9][a-z0-9-]{0,62}$/.test(project)) {\n throw new Error(\n `Lakebase project must look like projects/fabric-experiments; got '${project ?? ''}'`,\n );\n }\n return project;\n}\n\nexport function toLakebaseBranchId(environmentName: string): string {\n const normalized = environmentName\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n const prefixed = normalized.startsWith('fx-') ? normalized : `fx-${normalized}`;\n const trimmed = prefixed.slice(0, 63).replace(/-+$/g, '');\n if (!/^fx-[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(trimmed)) {\n throw new Error(`Cannot derive a safe Lakebase branch ID from '${environmentName}'`);\n }\n return trimmed;\n}\n\nexport async function createEphemeralLakebaseBranch(\n options: LakebaseBranchOptions,\n): Promise<EphemeralLakebaseBranch> {\n const env = options.env ?? process.env;\n const client = options.client ?? (createClientFromEnv(env) as LakebaseControlClient);\n const project = resolveLakebaseProject(env, options.project);\n const branchId = toLakebaseBranchId(options.branchId);\n const ttlSeconds = Math.max(60, Math.ceil(options.ttlMs / 1_000));\n const operation = await client.post<Operation<Branch>>(\n `/api/2.0/postgres/${project}/branches`,\n { spec: { ttl: `${ttlSeconds}s` } },\n { branch_id: branchId, replace_existing: false },\n );\n const branch = await waitForOperation(client, operation, options);\n const branchName = branch?.name ?? `${project}/branches/${branchId}`;\n const [endpointResult, databaseResult] = await Promise.all([\n client.get<{ endpoints?: Endpoint[] }>(`/api/2.0/postgres/${branchName}/endpoints`),\n client.get<{ databases?: Database[] }>(`/api/2.0/postgres/${branchName}/databases`),\n ]);\n const endpoint =\n endpointResult.endpoints?.find((item) => item.endpoint_id === 'primary') ??\n endpointResult.endpoints?.[0];\n const database = databaseResult.databases?.[0];\n const host = endpoint?.status?.hosts?.host;\n const postgresDatabase = database?.status?.postgres_database;\n if (!endpoint?.name || !host || !database?.name || !postgresDatabase) {\n throw new Error(`Lakebase branch '${branchName}' did not expose an endpoint and database`);\n }\n const createdAt = branch?.create_time ?? (options.now?.() ?? new Date()).toISOString();\n return {\n project,\n branch: branchName,\n branchId,\n endpoint: endpoint.name,\n host,\n databaseResource: database.name,\n database: postgresDatabase,\n createdAt,\n expiresAt: new Date(Date.parse(createdAt) + ttlSeconds * 1_000).toISOString(),\n };\n}\n\nexport async function deleteEphemeralLakebaseBranch(\n branch: Pick<EphemeralLakebaseBranch, 'branch'>,\n options: Omit<LakebaseBranchOptions, 'branchId' | 'ttlMs' | 'project'> = {},\n): Promise<void> {\n if (!/^projects\\/[a-z0-9-]+\\/branches\\/fx-[a-z0-9-]+$/.test(branch.branch)) {\n throw new Error(`Refusing to delete non-ephemeral Lakebase branch '${branch.branch}'`);\n }\n const env = options.env ?? process.env;\n const client = options.client ?? (createClientFromEnv(env) as LakebaseControlClient);\n const operation = await client.request<Operation>(\n 'DELETE',\n `/api/2.0/postgres/${branch.branch}`,\n undefined,\n { purge: true },\n );\n await waitForOperation(client, operation, options);\n}\n\nasync function waitForOperation<T>(\n client: LakebaseControlClient,\n initial: Operation<T>,\n options: Pick<LakebaseBranchOptions, 'pollIntervalMs' | 'timeoutMs'>,\n): Promise<T | undefined> {\n let operation = initial;\n const deadline = Date.now() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n while (!operation.done) {\n if (!operation.name) throw new Error('Lakebase operation did not return an operation name');\n if (Date.now() >= deadline) throw new Error(`Lakebase operation '${operation.name}' timed out`);\n await delay(options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);\n operation = await client.get<Operation<T>>(`/api/2.0/postgres/${operation.name}`);\n }\n if (operation.error) {\n throw new Error(\n `Lakebase operation failed${operation.error.code ? ` (${operation.error.code})` : ''}: ${\n operation.error.message ?? 'unknown error'\n }`,\n );\n }\n return operation.response;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { resolveTokenProvider } from './workspace-context.js';\n\nexport async function databricksFetch(\n env: Record<string, string | undefined>,\n pathOrUrl: string,\n init: RequestInit = {},\n fetchImpl: typeof fetch = fetch,\n): Promise<Response> {\n const host = env.DATABRICKS_HOST?.replace(/\\/$/, '');\n if (!host) throw new Error('DATABRICKS_HOST is required');\n const provider = resolveTokenProvider(host, env, fetchImpl);\n const token = typeof provider === 'string' ? provider : await provider();\n const headers = new Headers(init.headers);\n headers.set('authorization', `Bearer ${token}`);\n const response = await fetchImpl(\n /^https?:\\/\\//.test(pathOrUrl) ? pathOrUrl : `${host}${pathOrUrl}`,\n {\n ...init,\n headers,\n },\n );\n if (!response.ok) {\n const body = await response.text();\n throw new Error(\n `Databricks request failed: ${response.status} ${response.statusText}: ${body.slice(0, 500)}`,\n );\n }\n return response;\n}\n","import { databricksFetch } from './databricks-http.js';\nimport type { LiveCheck } from './live-suite.js';\n\nfunction csv(value: string | undefined): string[] {\n return (value ?? '')\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\n/** Assert secret key metadata only; values are never requested. */\nexport function secretScopeCheck(): LiveCheck {\n return {\n id: 'secrets',\n description: 'Databricks secret scope contains expected keys',\n configured: (env) => Boolean(env.DBX_TEST_SECRET_SCOPE && env.DBX_TEST_SECRET_KEYS),\n async run({ env, client }) {\n const scope = env.DBX_TEST_SECRET_SCOPE as string;\n const expected = csv(env.DBX_TEST_SECRET_KEYS);\n const response = await client.get<{ secrets?: { key?: string }[] }>('/api/2.0/secrets/list', {\n scope,\n });\n const actual = new Set((response.secrets ?? []).map((secret) => secret.key).filter(Boolean));\n const missing = expected.filter((key) => !actual.has(key));\n if (missing.length > 0) {\n throw new Error(`Secret scope ${scope} is missing keys: ${missing.join(', ')}`);\n }\n return { scope, expectedKeys: expected.length };\n },\n };\n}\n\nexport interface AppHealthCheckOptions {\n fetchImpl?: typeof fetch;\n}\n\n/** Verify app state, resource bindings, and the gateway-authenticated application health route. */\nexport function appHealthCheck(options: AppHealthCheckOptions = {}): LiveCheck {\n return {\n id: 'app',\n description: 'Databricks App is running, bound, and healthy',\n configured: (env) => Boolean(env.DBX_TEST_APP_NAME),\n async run({ env, client }) {\n const name = env.DBX_TEST_APP_NAME as string;\n const app = await client.get<{\n app_status?: { state?: string };\n resources?: { name?: string }[];\n url?: string;\n app_url?: string;\n }>(`/api/2.0/apps/${encodeURIComponent(name)}`);\n if (app.app_status?.state !== 'RUNNING') {\n throw new Error(`Databricks App ${name} is ${app.app_status?.state ?? 'UNKNOWN'}`);\n }\n const expected = csv(env.DBX_TEST_APP_RESOURCES);\n const actual = new Set(\n (app.resources ?? []).map((resource) => resource.name).filter(Boolean),\n );\n const missing = expected.filter((resource) => !actual.has(resource));\n if (missing.length > 0) {\n throw new Error(\n `Databricks App ${name} is missing resource bindings: ${missing.join(', ')}`,\n );\n }\n const appUrl = env.DBX_TEST_APP_URL ?? app.url ?? app.app_url;\n if (!appUrl) throw new Error(`Databricks App ${name} returned no URL`);\n const healthUrl = new URL('/api/healthz', appUrl).toString();\n const response = await databricksFetch(env, healthUrl, {}, options.fetchImpl);\n const health = (await response.json()) as { ok?: boolean; status?: string };\n if (health.ok !== true && health.status !== 'ok') {\n throw new Error(`Databricks App ${name} health probe did not report ok`);\n }\n return { name, bindings: actual.size, health: 'ok' };\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport { databricksFetch } from './databricks-http.js';\nimport type { LiveCheck } from './live-suite.js';\n\nexport interface VolumeIOCheckOptions {\n fetchImpl?: typeof fetch;\n randomId?: () => string;\n}\n\nexport function normalizeVolumeRoot(value: string): string {\n const normalized = value.replace(/\\/$/, '');\n if (!/^\\/Volumes\\/[^/]+\\/[^/]+\\/[^/]+$/.test(normalized)) {\n throw new Error('DBX_TEST_VOLUME must be /Volumes/<catalog>/<schema>/<volume>');\n }\n return normalized;\n}\n\nexport async function ensureVolumeDirectory(\n env: Record<string, string | undefined>,\n directory: string,\n fetchImpl?: typeof fetch,\n): Promise<void> {\n await databricksFetch(env, `/api/2.0/fs/directories${directory}`, { method: 'PUT' }, fetchImpl);\n}\n\nexport async function uploadVolumeFile(\n env: Record<string, string | undefined>,\n path: string,\n body: BodyInit | Uint8Array,\n fetchImpl?: typeof fetch,\n): Promise<void> {\n await databricksFetch(\n env,\n `/api/2.0/fs/files${path}`,\n { method: 'PUT', body: body as BodyInit },\n fetchImpl,\n );\n}\n\nexport async function deleteVolumeFile(\n env: Record<string, string | undefined>,\n path: string,\n fetchImpl?: typeof fetch,\n): Promise<void> {\n await databricksFetch(env, `/api/2.0/fs/files${path}`, { method: 'DELETE' }, fetchImpl);\n}\n\n/** Upload, download, and delete a small probe through the Databricks Files API. */\nexport function volumeIOCheck(options: VolumeIOCheckOptions = {}): LiveCheck {\n return {\n id: 'volume-io',\n description: 'Unity Catalog volume Files API round-trip',\n configured: (env) => Boolean(env.DBX_TEST_VOLUME),\n async run({ env }) {\n const root = normalizeVolumeRoot(env.DBX_TEST_VOLUME as string);\n const prefix = (env.DBX_TEST_ENV_NAME ?? 'fx-live').replace(/[^A-Za-z0-9_.-]/g, '_');\n const id = (options.randomId ?? randomUUID)();\n const directory = `${root}/${prefix}`;\n const file = `${directory}/probe-${id}.txt`;\n const filePath = `/api/2.0/fs/files${file}`;\n const body = new TextEncoder().encode(`fabric-experiments-volume-probe:${id}`);\n await ensureVolumeDirectory(env, directory, options.fetchImpl);\n try {\n await uploadVolumeFile(env, file, body, options.fetchImpl);\n const downloaded = await databricksFetch(env, filePath, {}, options.fetchImpl);\n const actual = new Uint8Array(await downloaded.arrayBuffer());\n if (actual.length !== body.length || actual.some((value, index) => value !== body[index])) {\n throw new Error('Volume round-trip returned different bytes');\n }\n return { volume: root, bytes: body.length };\n } finally {\n await deleteVolumeFile(env, file, options.fetchImpl).catch(() => undefined);\n }\n },\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { basename, resolve } from 'node:path';\nimport type { LiveCheck } from './live-suite.js';\nimport { waitForPipelineUpdate } from './pollers.js';\nimport {\n deleteVolumeFile,\n ensureVolumeDirectory,\n normalizeVolumeRoot,\n uploadVolumeFile,\n} from './volume-checks.js';\n\nexport interface AutoLoaderCheckOptions {\n fetchImpl?: typeof fetch;\n fixtureBody?: Uint8Array;\n randomId?: () => string;\n}\n\n/** Exercise Files API -> isolated Lakeflow pipeline -> Delta output. */\nexport function autoLoaderIngestionCheck(options: AutoLoaderCheckOptions = {}): LiveCheck {\n return {\n id: 'autoloader',\n description: 'Isolated Auto Loader fixture ingestion reaches Delta without rescued rows',\n configured: (env) =>\n Boolean(\n env.DBX_TEST_AUTOLOADER_PIPELINE_ID &&\n env.DBX_TEST_AUTOLOADER_TABLE &&\n env.DBX_TEST_AUTOLOADER_FIXTURE &&\n env.DBX_TEST_VOLUME,\n ),\n async run({ env, client, warehouse }) {\n const pipelineId = env.DBX_TEST_AUTOLOADER_PIPELINE_ID as string;\n if (pipelineId === env.DBX_TEST_PIPELINE_ID) {\n throw new Error('DBX_TEST_AUTOLOADER_PIPELINE_ID must not be the production pipeline');\n }\n const root = normalizeVolumeRoot(env.DBX_TEST_VOLUME as string);\n const fixturePath = env.DBX_TEST_AUTOLOADER_FIXTURE as string;\n const body = options.fixtureBody ?? new Uint8Array(await readFile(resolve(fixturePath)));\n const id = (options.randomId ?? randomUUID)();\n const runName = (env.DBX_TEST_ENV_NAME ?? 'autoloader').replace(/[^A-Za-z0-9_.-]/g, '_');\n const directory = `${root}/exposures/${runName}/${id}`;\n const destination = `${directory}/${basename(fixturePath)}`;\n await ensureVolumeDirectory(env, directory, options.fetchImpl);\n try {\n await uploadVolumeFile(env, destination, body, options.fetchImpl);\n const submitted = await client.post<{ update_id?: string }>(\n `/api/2.0/pipelines/${encodeURIComponent(pipelineId)}/updates`,\n { full_refresh: true },\n );\n if (!submitted.update_id) throw new Error('Auto Loader pipeline returned no update_id');\n await waitForPipelineUpdate(client, pipelineId, submitted.update_id, {\n timeoutMs: Number(env.DBX_TEST_TIMEOUT_MS ?? 900_000),\n pollIntervalMs: Number(env.DBX_TEST_POLL_INTERVAL_MS ?? 10_000),\n });\n const table = env.DBX_TEST_AUTOLOADER_TABLE as string;\n const rows = await warehouse.query(\n `SELECT COUNT(*) AS n, SUM(CASE WHEN _rescued_data IS NOT NULL THEN 1 ELSE 0 END) AS rescued FROM ${table}`,\n );\n const count = Number(rows[0]?.n ?? 0);\n const rescued = Number(rows[0]?.rescued ?? 0);\n if (count < 1) throw new Error(`Auto Loader produced no rows in ${table}`);\n if (rescued !== 0)\n throw new Error(`Auto Loader produced ${rescued} rescued rows in ${table}`);\n return { pipelineId, table, rows: count, rescued };\n } finally {\n await deleteVolumeFile(env, destination, options.fetchImpl).catch(() => undefined);\n }\n },\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabricorg/databricks-testkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Testing toolkit for Databricks artifacts — DuckDB/local + live workspace execution contexts, fixtures, golden results, and cross-engine parity suites.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,12 +30,16 @@
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
|
-
"files": [
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
"files": ["dist"],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsup",
|
|
36
|
+
"type-check": "tsc --noEmit",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"clean": "rm -rf dist"
|
|
39
|
+
},
|
|
36
40
|
"dependencies": {
|
|
37
41
|
"@fabric-harness/databricks": "^1.2.3",
|
|
38
|
-
"@fabricorg/experiments-db-pool": "
|
|
42
|
+
"@fabricorg/experiments-db-pool": "workspace:*"
|
|
39
43
|
},
|
|
40
44
|
"peerDependencies": {
|
|
41
45
|
"@duckdb/node-api": ">=1.4.0",
|
|
@@ -51,16 +55,10 @@
|
|
|
51
55
|
},
|
|
52
56
|
"devDependencies": {
|
|
53
57
|
"@duckdb/node-api": "1.5.4-r.1",
|
|
58
|
+
"@fabricorg/experiments-warehouse": "workspace:*",
|
|
54
59
|
"@types/node": "^22.15.3",
|
|
55
60
|
"tsup": "^8.3.5",
|
|
56
61
|
"typescript": "^5.8.3",
|
|
57
|
-
"vitest": "^2.1.8"
|
|
58
|
-
"@fabricorg/experiments-warehouse": "0.0.1"
|
|
59
|
-
},
|
|
60
|
-
"scripts": {
|
|
61
|
-
"build": "tsup",
|
|
62
|
-
"type-check": "tsc --noEmit",
|
|
63
|
-
"test": "vitest run",
|
|
64
|
-
"clean": "rm -rf dist"
|
|
62
|
+
"vitest": "^2.1.8"
|
|
65
63
|
}
|
|
66
|
-
}
|
|
64
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Fabric
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
|
13
|
-
all copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
-
THE SOFTWARE.
|