@fabricorg/databricks-bdd 0.1.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/LICENSE +21 -0
- package/README.md +81 -0
- package/dist/chunk-EW5VNRZP.js +199 -0
- package/dist/chunk-EW5VNRZP.js.map +1 -0
- package/dist/chunk-LFEU3ZHD.js +80 -0
- package/dist/chunk-LFEU3ZHD.js.map +1 -0
- package/dist/chunk-YNOLRERF.js +42 -0
- package/dist/chunk-YNOLRERF.js.map +1 -0
- package/dist/evidence-formatter.cjs +85 -0
- package/dist/evidence-formatter.cjs.map +1 -0
- package/dist/evidence-formatter.d.cts +38 -0
- package/dist/evidence-formatter.d.ts +38 -0
- package/dist/evidence-formatter.js +3 -0
- package/dist/evidence-formatter.js.map +1 -0
- package/dist/index.cjs +272 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +119 -0
- package/dist/index.d.ts +119 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/parameter-types.cjs +47 -0
- package/dist/parameter-types.cjs.map +1 -0
- package/dist/parameter-types.d.cts +7 -0
- package/dist/parameter-types.d.ts +7 -0
- package/dist/parameter-types.js +3 -0
- package/dist/parameter-types.js.map +1 -0
- package/dist/steps.cjs +689 -0
- package/dist/steps.cjs.map +1 -0
- package/dist/steps.d.cts +2 -0
- package/dist/steps.d.ts +2 -0
- package/dist/steps.js +453 -0
- package/dist/steps.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/steps.ts"],"names":[],"mappings":";;;;;;;;;AA+CA,mBAAA,CAAoB,eAAe,CAAA;AACnC,iBAAA,CAAkB,GAAM,CAAA;AACxB,sBAAA,EAAuB;AAEvB,SAAA,CAAU,YAAY;AACpB,EAAA,IAAI,cAAA,OAAqB,MAAA,EAAQ;AACjC,EAAA,MAAM,UAAU,MAAM,sBAAA,CAAuB,EAAE,OAAA,EAAS,QAAQ,CAAA;AAChE,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,KAAA,CAAM,+BAA+B,CAAA;AAChE,IAAA,IAAI,OAAO,IAAA,CAAK,CAAC,CAAA,EAAG,iBAAiB,MAAM,CAAA,EAAG;AAC5C,MAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAAA,IACzE;AAAA,EACF,CAAA,SAAE;AACA,IAAA,MAAM,QAAQ,KAAA,EAAM;AAAA,EACtB;AACF,CAAC,CAAA;AAED,MAAA,CAAO,SAAiC,EAAE,MAAA,EAAO,EAAG;AAClD,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAC1C,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,IAAA,EAAM,IAAA,CAAK,OAAO,CAAA;AAChD,EAAA,IAAI,QAAQ,OAAO,SAAA;AACnB,EAAA,OAAO,MAAA;AACT,CAAC,CAAA;AAED,KAAA,CAAM,iBAAuC;AAC3C,EAAA,MAAM,KAAK,OAAA,EAAQ;AACrB,CAAC,CAAA;AAED,SAAA,CAAU,eAAuC,EAAE,MAAA,EAAQ,UAAA,EAAW,EAAG;AACvE,EAAA,IAAI,MAAA,CAAO,WAAW,QAAA,EAAU;AAChC,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,MAAM,UAAA,CAAW,IAAA;AAAA,IACjB,GAAI,KAAK,eAAA,GAAkB,EAAE,aAAa,IAAA,CAAK,eAAA,KAAoB,EAAC;AAAA,IACpE,GAAI,IAAA,CAAK,OAAA,GAAU,EAAE,KAAK,aAAA,CAAc,IAAA,CAAK,OAAO,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,GAAK,CAAA,KAAM;AAAC,GAC7E;AACA,EAAA,MAAM,IAAA,CAAK,OAAO,IAAA,CAAK,SAAA,CAAU,UAAU,IAAA,EAAM,CAAC,GAAG,kBAAkB,CAAA;AACzE,CAAC,CAAA;AAID,KAAA,CAAM,0BAA0B,iBAAuC;AAGrE,EAAA,IAAI,IAAA,CAAK,OAAA,KAAY,MAAA,EAAQ,MAAM,KAAK,OAAA,EAAQ;AAClD,CAAC,CAAA;AAED,KAAA,CAAM,uBAAuB,iBAAuC;AAClE,EAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAQ;AAC3B,IAAA,MAAM,IAAI,MAAM,oEAAoE,CAAA;AAAA,EACtF;AACA,EAAA,MAAM,QAAA,GAAW,0BAAA,CAA2B,OAAA,CAAQ,GAAG,CAAA;AACvD,EAAA,IAAA,CAAK,YAAA,GAAe,SAAS,OAAA,EAAQ;AACrC,EAAA,IAAA,CAAK,WAAW,YAAY;AAC1B,IAAA,IAAA,CAAK,YAAA,GAAe,MAAA;AACpB,IAAA,MAAM,SAAS,KAAA,EAAM;AAAA,EACvB,CAAC,CAAA;AACD,EAAA,MAAM,IAAA,CAAK,YAAA,CAAa,KAAA,CAAM,8BAA8B,CAAA;AAC9D,CAAC,CAAA;AAED,KAAA;AAAA,EACE,sCAAA;AAAA,EACA,SAAiC,SAAiB,MAAA,EAAgB;AAChE,IAAA,IAAA,CAAK,OAAA,CAAQ,SAAS,MAAM,CAAA;AAAA,EAC9B;AACF,CAAA;AAEA,KAAA;AAAA,EACE,wBAAA;AAAA,EACA,eAAuC,OAAe,IAAA,EAAiB;AACrE,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,IAAA,MAAM,IAAI,WAAA,CAAY,YAAA,CAAa,OAAO,IAAA,CAAK,GAAA,EAAK,CAAC,CAAA;AAAA,EACvD;AACF,CAAA;AAEA,KAAA;AAAA,EACE,iDAAA;AAAA,EACA,eAAuC,KAAA,EAAe,MAAA,EAAgB,IAAA,EAAiB;AACrF,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,IAAA,MAAM,GAAA,CAAI,YAAY,EAAE,KAAA,EAAO,QAAQ,IAAA,EAAM,IAAA,CAAK,MAAA,EAAO,EAAG,CAAA;AAAA,EAC9D;AACF,CAAA;AAEA,KAAA;AAAA,EACE,8CAAA;AAAA,EACA,eAAuC,OAAe,MAAA,EAAgB;AACpE,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,IAAA,MAAM,GAAA,CAAI,YAAY,EAAE,KAAA,EAAO,QAAQ,IAAA,EAAM,IAAI,CAAA;AAAA,EACnD;AACF,CAAA;AAEA,KAAA;AAAA,EACE,6DAAA;AAAA,EACA,eAAuC,KAAA,EAAe,MAAA,EAAgB,UAAA,EAAoB;AACxF,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,IAAA,MAAM,IAAI,WAAA,CAAY,EAAE,KAAA,EAAO,MAAA,EAAQ,YAAY,CAAA;AAAA,EACrD;AACF,CAAA;AAEA,KAAA;AAAA,EACE,4CAAA;AAAA,EACA,eAAuC,kBAA0B,IAAA,EAAiB;AAChF,IAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAQ;AAC3B,MAAA,MAAM,IAAI,MAAM,qEAAqE,CAAA;AAAA,IACvF;AACA,IAAA,MAAM,WAAA,GAAc,gBAAA,CAAiB,UAAA,CAAW,GAAG,CAAA,GAC/C,OAAA,CAAQ,GAAA,CAAI,gBAAA,CAAiB,KAAA,CAAM,CAAC,CAAC,CAAA,GACrC,gBAAA;AACJ,IAAA,IAAI,CAAC,WAAA,EAAa,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,gBAAgB,CAAA,mBAAA,CAAqB,CAAA;AAClF,IAAA,MAAM,IAAA,GAAO,oBAAoB,WAAW,CAAA;AAC5C,IAAA,MAAM,IAAA,GAAO,KAAK,MAAA,EAAO;AACzB,IAAA,MAAM,eAAe,IAAA,CAAK,CAAC,CAAA,EAAG,MAAA,EAAQ,MAAK,IAAK,EAAA;AAChD,IAAA,IAAI,YAAA,IAAgB,CAAC,yCAAA,CAA0C,IAAA,CAAK,YAAY,CAAA,EAAG;AACjF,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,+BAAA,EAAkC,YAAY,CAAA,CAAA,CAAG,CAAA;AAAA,IACnE;AACA,IAAA,IAAI,IAAA,CAAK,IAAA,CAAK,CAAC,GAAA,KAAA,CAAS,GAAA,CAAI,QAAQ,IAAA,EAAK,IAAK,EAAA,MAAQ,YAAY,CAAA,EAAG;AACnE,MAAA,MAAM,IAAI,MAAM,8DAA8D,CAAA;AAAA,IAChF;AACA,IAAA,MAAM,SAAA,GAAY,CAAA,EAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,iBAAA,IAAqB,KAAA,EAAO,OAAA,CAAQ,kBAAA,EAAoB,GAAG,CAAC,CAAA,CAAA,EAAI,UAAA,EAAY,CAAA,CAAA;AAC9G,IAAA,MAAM,SAAA,GAAY,CAAA,EAAG,IAAI,CAAA,EAAG,YAAA,GAAe,IAAI,YAAY,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA;AAC/E,IAAA,MAAM,qBAAA,CAAsB,OAAA,CAAQ,GAAA,EAAK,SAAS,CAAA;AAClD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAI,CAAA,CAAE,MAAA,CAAO,CAAC,IAAA,KAAyB,OAAA,CAAQ,IAAI,CAAC,CAAA;AACxF,IAAA,IAAI,MAAM,MAAA,KAAW,CAAA,EAAG,MAAM,IAAI,MAAM,6CAA6C,CAAA;AACrF,IAAA,KAAA,MAAW,UAAU,KAAA,EAAO;AAC1B,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,MAAM,CAAA;AAC9C,MAAA,MAAM,OAAA,GAAU,QAAA,CAAS,OAAA,CAAQ,GAAA,IAAO,QAAQ,CAAA;AAChD,MAAA,IAAI,QAAQ,UAAA,CAAW,IAAI,CAAA,IAAK,UAAA,CAAW,OAAO,CAAA,EAAG;AACnD,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,4CAAA,EAA+C,MAAM,CAAA,CAAE,CAAA;AAAA,MACzE;AACA,MAAA,MAAM,cAAc,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,QAAA,CAAS,MAAM,CAAC,CAAA,CAAA;AACpD,MAAA,MAAM,gBAAA,CAAiB,OAAA,CAAQ,GAAA,EAAK,WAAA,EAAa,IAAI,WAAW,MAAM,QAAA,CAAS,QAAQ,CAAC,CAAC,CAAA;AACzF,MAAA,IAAA,CAAK,WAAW,MAAM,gBAAA,CAAiB,OAAA,CAAQ,GAAA,EAAK,WAAW,CAAC,CAAA;AAAA,IAClE;AAAA,EACF;AACF,CAAA;AAEA,KAAA;AAAA,EACE,yCAAA;AAAA,EACA,eAAuC,cAAsB,IAAA,EAAiB;AAC5E,IAAA,IAAI,IAAA,CAAK,YAAY,MAAA,EAAQ;AAC3B,MAAA,MAAM,IAAI,MAAM,qEAAqE,CAAA;AAAA,IACvF;AACA,IAAA,MAAM,SAAA,GAAY,sBAAsB,YAAA,CAAa,OAAA,CAAQ,iBAAiB,GAAG,CAAA,CAAE,aAAa,CAAA,CAAA;AAChG,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,SAAS,CAAA,UAAA,CAAY,CAAA;AACrD,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,SAAS,CAAA,cAAA,CAAgB,CAAA;AAC7D,IAAA,MAAM,gBAAgB,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,SAAS,OAAO,CAAA,IAAK,YAAA;AAC1D,IAAA,IAAI,CAAC,QAAA,IAAY,CAAC,YAAA,EAAc;AAC9B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,SAAS,CAAA,eAAA,EAAkB,SAAS,CAAA,cAAA,CAAgB,CAAA;AAAA,IACjF;AACA,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,OAAA,EAAQ;AACnC,IAAA,MAAM,MAAA,GAAS,KAAK,MAAA,EAAO,CAAE,IAAI,CAAC,GAAA,KAAQ,cAAA,CAAe,GAAG,CAAC,CAAA;AAC7D,IAAA,IAAI,OAAO,MAAA,KAAW,CAAA,EAAG,MAAM,IAAI,MAAM,8BAA8B,CAAA;AACvE,IAAA,MAAM,kBAAkB,CAAA,EAAA,EAAK,aAAA,CAAc,UAAA,CAAW,GAAA,EAAK,IAAI,CAAC,CAAA,EAAA,CAAA;AAChE,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,OAAA,CAAQ,IAAA;AAAA,QACZ,CAAA,MAAA,EAAS,KAAA,CAAM,UAAA,CAAW,IAAA,CAAK,IAAI,CAAC,CAAA,IAAA,EAAO,KAAA,CAAM,aAAa,CAAA,CAAA,EAAI,KAAA,CAAM,SAAS,OAAO,eAAe,CAAA;AAAA,OACzG;AAAA,IACF;AACA,IAAA,IAAA,CAAK,WAAW,YAAY;AAC1B,MAAA,KAAA,MAAW,SAAS,CAAC,GAAG,MAAM,CAAA,CAAE,SAAQ,EAAG;AACzC,QAAA,MAAM,OAAA,CAAQ,IAAA;AAAA,UACZ,CAAA,OAAA,EAAU,KAAA,CAAM,UAAA,CAAW,IAAA,CAAK,IAAI,CAAC,CAAA,IAAA,EAAO,KAAA,CAAM,aAAa,CAAA,CAAA,EAAI,KAAA,CAAM,SAAS,SAAS,eAAe,CAAA;AAAA,SAC5G;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AACD,IAAA,MAAM,YAAA,GAAe;AAAA,MACnB,GAAG,OAAA,CAAQ,GAAA;AAAA,MACX,iBAAA,EAAmB,MAAA;AAAA,MACnB,gBAAA,EAAkB,MAAA;AAAA,MAClB,oBAAA,EAAsB,QAAA;AAAA,MACtB,wBAAA,EAA0B;AAAA,KAC5B;AACA,IAAA,MAAM,SAAA,GAAY,MAAM,sBAAA,CAAuB;AAAA,MAC7C,OAAA,EAAS,MAAA;AAAA,MACT,GAAA,EAAK,YAAA;AAAA,MACL,MAAA,EAAQ,IAAA,CAAK,cAAA,IAAkB,IAAA,CAAK,UAAA,CAAW,MAAA;AAAA,MAC/C,WAAA,EAAa,CAAC,EAAE,GAAA,EAAK,aAAY,KAAM;AACrC,QAAA,IAAA,CAAK,OAAA,GAAU,GAAA;AACf,QAAA,IAAA,CAAK,eAAA,GAAkB,WAAA;AAAA,MACzB;AAAA,KACD,CAAA;AACD,IAAA,IAAA,CAAK,oBAAoB,SAAS,CAAA;AAAA,EACpC;AACF,CAAA;AAIA,IAAA,CAAK,gBAAA,EAAkB,eAAuC,GAAA,EAAa;AACzE,EAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,EAAA,IAAA,CAAK,OAAA,GAAU,GAAA;AACf,EAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,EAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,EAAA,IAAI;AACF,IAAA,IAAA,CAAK,QAAA,GAAW,MAAM,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA;AAAA,EACrC,SAAS,KAAA,EAAO;AACd,IAAA,IAAA,CAAK,SAAA,GAAY,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EAC3E;AACF,CAAC,CAAA;AAED,IAAA,CAAK,mBAAA,EAAqB,eAAuC,GAAA,EAAa;AAC5E,EAAA,IAAI,CAAC,KAAK,YAAA,EAAc;AACtB,IAAA,MAAM,IAAI,MAAM,4EAAuE,CAAA;AAAA,EACzF;AACA,EAAA,IAAA,CAAK,OAAA,GAAU,GAAA;AACf,EAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,EAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,YAAA,CAAa,MAAM,GAAG,CAAA;AAChD,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,IAAA;AAAA,EACzB,SAAS,KAAA,EAAO;AACd,IAAA,IAAA,CAAK,SAAA,GAAY,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EAC3E;AACF,CAAC,CAAA;AAED,IAAA,CAAK,wBAAA,EAA0B,eAAuC,KAAA,EAAe;AACnF,EAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,EAAA,IAAA,CAAK,QAAA,GAAW,MAAM,GAAA,CAAI,KAAA,CAAM,iBAAiB,GAAA,CAAI,IAAA,CAAK,KAAK,CAAC,CAAA,CAAE,CAAA;AACpE,CAAC,CAAA;AAED,IAAA,CAAK,oBAAA,EAAsB,eAAuC,QAAA,EAAkB;AAClF,EAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,OAAA,CAAQ,GAAG,CAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,MAAM,gBAAA,CAAiB,MAAA,EAAQ,QAAQ,CAAA;AACtD,EAAA,IAAA,CAAK,UAAU,EAAE,YAAA,EAAc,OAAO,WAAA,EAAa,gBAAA,EAAkB,OAAO,cAAA,EAAe;AAC7F,CAAC,CAAA;AAED,IAAA,CAAK,4BAAA,EAA8B,eAAuC,YAAA,EAAsB;AAC9F,EAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,OAAA,CAAQ,GAAG,CAAA;AAC9C,EAAA,MAAM,mBAAA,GAAsB,GAAA,CAAI;AAAA,IAC9B,KAAK,EAAE,GAAG,OAAA,CAAQ,GAAA,EAAK,wBAAwB,YAAA,EAAa;AAAA,IAC5D,SAAA,EAAW,MAAM,IAAA,CAAK,OAAA,EAAQ;AAAA,IAC9B;AAAA,GACD,CAAA;AACD,EAAA,IAAA,CAAK,OAAA,GAAU,EAAE,YAAA,EAAc,SAAA,EAAW,kBAAkB,YAAA,EAAa;AAC3E,CAAC,CAAA;AAED,IAAA,CAAK,8BAAA,EAAgC,eAAuC,OAAA,EAAiB;AAC3F,EAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,OAAA,CAAQ,GAAG,CAAA;AAC9C,EAAA,MAAM,aAAA,GAAgB,GAAA,CAAI;AAAA,IACxB,KAAK,EAAE,GAAG,OAAA,CAAQ,GAAA,EAAK,0BAA0B,OAAA,EAAQ;AAAA,IACzD,SAAA,EAAW,MAAM,IAAA,CAAK,OAAA,EAAQ;AAAA,IAC9B;AAAA,GACD,CAAA;AACD,EAAA,IAAA,CAAK,OAAA,GAAU,EAAE,YAAA,EAAc,SAAA,EAAW,kBAAkB,YAAA,EAAa;AAC3E,CAAC,CAAA;AAED,IAAA;AAAA,EACE,6CAAA;AAAA,EACA,eAAuC,QAAA,EAAkB;AACvD,IAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,CAAI,+BAAA;AAC7B,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,CAAS,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,QAAA;AAC9E,IAAA,IAAI,CAAC,QAAA,IAAY,CAAC,SAAA,IAAa,cAAc,QAAA,EAAU;AACrD,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,OAAA,CAAQ,GAAG,CAAA;AAC9C,IAAA,MAAM,UAAA,GAAa,MAAM,iBAAA,CAAkB,MAAA,EAAQ,SAAS,CAAA;AAC5D,IAAA,MAAM,QAAA,GAAW,MAAM,mBAAA,CAAoB,MAAA,EAAQ,YAAY,EAAE,WAAA,EAAa,MAAM,CAAA;AACpF,IAAA,IAAA,CAAK,kBAAA,GAAqB,EAAE,UAAA,EAAY,QAAA,EAAS;AAAA,EACnD;AACF,CAAA;AAEA,IAAA;AAAA,EACE,wCAAA;AAAA,EACA,eAAuC,QAAA,EAAkB;AACvD,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,UAAA,CAAW,GAAG,CAAA,GAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,CAAS,KAAA,CAAM,CAAC,CAAC,CAAA,GAAI,QAAA;AAC9E,IAAA,IAAI,CAAC,SAAA,EAAW,MAAM,IAAI,KAAA,CAAM,CAAA,UAAA,EAAa,QAAQ,CAAA,mBAAA,CAAqB,CAAA;AAC1E,IAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,OAAA,CAAQ,GAAG,CAAA;AAC9C,IAAA,MAAM,UAAA,GAAa,MAAM,iBAAA,CAAkB,MAAA,EAAQ,SAAS,CAAA;AAC5D,IAAA,MAAM,QAAA,GAAW,MAAM,mBAAA,CAAoB,MAAA,EAAQ,YAAY,EAAE,WAAA,EAAa,OAAO,CAAA;AACrF,IAAA,IAAA,CAAK,kBAAA,GAAqB,EAAE,UAAA,EAAY,QAAA,EAAS;AAAA,EACnD;AACF,CAAA;AAIA,IAAA;AAAA,EACE,+BAAA;AAAA,EACA,eAAuC,OAAe,CAAA,EAAW;AAC/D,IAAA,MAAM,WAAA,CAAY,MAAM,IAAA,CAAK,OAAA,IAAW,KAAK,CAAA,CAAE,eAAe,CAAC,CAAA;AAAA,EACjE;AACF,CAAA;AAEA,IAAA;AAAA,EACE,wCAAA;AAAA,EACA,eAAuC,OAAe,IAAA,EAAiB;AACrE,IAAA,MAAM,WAAA,CAAY,MAAM,IAAA,CAAK,OAAA,EAAQ,EAAG,KAAK,CAAA,CAAE,aAAA,CAAc,eAAA,CAAgB,IAAA,CAAK,GAAA,EAAK,CAAC,CAAA;AAAA,EAC1F;AACF,CAAA;AAEA,IAAA;AAAA,EACE,kCAAA;AAAA,EACA,eAAuC,OAAe,IAAA,EAAiB;AACrE,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,IAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,IAAA,CAAK,GAAA,EAAK,CAAA;AAC3C,IAAA,MAAM,MAAA,GAAA,CAAU,KAAK,GAAA,EAAI,CAAE,CAAC,CAAA,IAAK,EAAC,EAAG,IAAA,CAAK,IAAI,CAAA;AAC9C,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,KAAA,CAAM,CAAA,OAAA,EAAU,MAAM,CAAA,MAAA,EAAS,GAAA,CAAI,IAAA,CAAK,KAAK,CAAC,CAAA,CAAE,CAAA;AACvE,IAAA,IAAI,IAAA,CAAK,MAAA,KAAW,QAAA,CAAS,MAAA,EAAQ;AACnC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,QAAA,CAAS,MAAM,YAAY,KAAK,CAAA,QAAA,EAAW,IAAA,CAAK,MAAM,CAAA,CAAE,CAAA;AAAA,IAC9F;AACA,IAAA,MAAM,WAAA,CAAY,GAAA,EAAK,KAAK,CAAA,CAAE,cAAc,QAAQ,CAAA;AAAA,EACtD;AACF,CAAA;AAEA,IAAA;AAAA,EACE,4DAAA;AAAA,EACA,eAAuC,KAAA,EAAe,MAAA,EAAgB,OAAA,EAAiB;AACrF,IAAA,MAAM,WAAA,CAAY,MAAM,IAAA,CAAK,OAAA,EAAQ,EAAG,KAAK,CAAA,CAAE,aAAA,CAAc,MAAA,EAAQ,EAAE,OAAA,EAAS,CAAA;AAAA,EAClF;AACF,CAAA;AAEA,IAAA;AAAA,EACE,iDAAA;AAAA,EACA,eAAuC,OAAe,YAAA,EAAsB;AAC1E,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,OAAA,CAAQ,GAAA,IAAO,YAAY,CAAA;AACpD,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,OAAA,CAAQ,GAAA,IAAO,QAAQ,CAAA;AAChD,IAAA,IAAI,QAAQ,UAAA,CAAW,IAAI,CAAA,IAAK,UAAA,CAAW,OAAO,CAAA,EAAG;AACnD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,oDAAA,EAAuD,YAAY,CAAA,CAAE,CAAA;AAAA,IACvF;AACA,IAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,MAAM,QAAA,CAAS,QAAA,EAAU,MAAM,CAAC,CAAA;AAG1D,IAAA,MAAM,UAAU,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAI,SAAS,MAAA,CAAO,OAAA;AACxD,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AACpC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,YAAY,CAAA,oBAAA,CAAsB,CAAA;AAAA,IACvE;AACA,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,KAAA,CAAM,kBAAkB,GAAA,CAAI,IAAA,CAAK,KAAK,CAAC,CAAA,CAAE,CAAA;AAChE,IAAA,mBAAA,CAAoB,KAAA,EAAO,MAAM,OAAO,CAAA;AAAA,EAC1C;AACF,CAAA;AAEA,IAAA,CAAK,2BAAA,EAA6B,SAAiC,CAAA,EAAW;AAC5E,EAAA,WAAA,CAAY,IAAI,CAAA;AAChB,EAAA,IAAI,IAAA,CAAK,QAAA,EAAU,MAAA,KAAW,CAAA,EAAG;AAC/B,IAAA,MAAM,IAAI,MAAM,CAAA,SAAA,EAAY,CAAC,qBAAqB,IAAA,CAAK,QAAA,EAAU,MAAM,CAAA,CAAE,CAAA;AAAA,EAC3E;AACF,CAAC,CAAA;AAED,IAAA,CAAK,oCAAA,EAAsC,SAAiC,IAAA,EAAiB;AAC3F,EAAA,WAAA,CAAY,IAAI,CAAA;AAChB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,QAAA,IAAY,EAAC;AAC/B,EAAA,KAAA,MAAW,OAAA,IAAW,eAAA,CAAgB,IAAA,CAAK,GAAA,EAAK,CAAA,EAAG;AACjD,IAAA,MAAM,MAAM,IAAA,CAAK,IAAA;AAAA,MAAK,CAAC,GAAA,KACrB,MAAA,CAAO,OAAA,CAAQ,OAAO,EAAE,KAAA,CAAM,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM,SAAA,CAAU,IAAI,GAAG,CAAA,EAAG,KAAK,CAAC;AAAA,KAC5E;AACA,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,uCAAA,EAA0C,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA,cAAA,EAAY,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAC,CAAA;AAAA,OAC/G;AAAA,IACF;AAAA,EACF;AACF,CAAC,CAAA;AAED,IAAA,CAAK,oCAAA,EAAsC,eAAuC,MAAA,EAAgB;AAChG,EAAA,WAAA,CAAY,IAAI,CAAA;AAChB,EAAA,MAAM,gBAAgB,MAAA,EAAQ,IAAA,CAAK,QAAA,IAAY,IAAI,QAAQ,CAAA;AAC7D,CAAC,CAAA;AAED,IAAA,CAAK,mCAAA,EAAqC,SAAiC,QAAA,EAAkB;AAC3F,EAAA,IAAI,CAAC,IAAA,CAAK,SAAA;AACR,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qCAAA,EAAwC,QAAQ,CAAA,mBAAA,CAAqB,CAAA;AACvF,EAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,WAAA,GAAc,QAAA,CAAS,QAAA,CAAS,WAAA,EAAa,CAAA,EAAG;AAC1E,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8CAAA,EAAiD,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,CAAE,CAAA;AAAA,EAC3F;AACF,CAAC,CAAA;AAED,IAAA,CAAK,8CAA8C,WAAiC;AAClF,EAAA,IAAI,CAAC,IAAA,CAAK,SAAA,EAAW,MAAM,IAAI,MAAM,0DAA0D,CAAA;AAC/F,EAAA,IAAI,CAAC,uDAAA,CAAwD,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,EAAG;AACzF,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mDAAA,EAAsD,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,CAAE,CAAA;AAAA,EAChG;AACF,CAAC,CAAA;AAED,IAAA;AAAA,EACE,wCAAA;AAAA,EACA,eAAuC,KAAA,EAAe;AACpD,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,KAAA;AAAA,MACrB,CAAA,0BAAA,EAA6B,GAAA,CAAI,IAAA,CAAK,KAAK,CAAC,CAAA,gCAAA;AAAA,KAC9C;AACA,IAAA,MAAM,IAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,IAAK,OAAO,GAAG,CAAA;AACzC,IAAA,IAAI,MAAM,CAAA,EAAG;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,iBAAA,EAAoB,KAAK,CAAA,sCAAA,CAAmC,CAAA;AAAA,IAClF;AAAA,EACF;AACF,CAAA;AAEA,IAAA;AAAA,EACE,mDAAA;AAAA,EACA,eAAuC,iBAAyB,OAAA,EAAiB;AAC/E,IAAA,MAAM,KAAA,GAAQ,sBAAA,CAAuB,eAAA,EAAiB,OAAO,CAAA;AAC7D,IAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,IAAA,MAAM,IAAA,GAAO,OAAO,MAAM,IAAA,CAAK,SAAQ,EAAG,KAAA,CAAM,CAAA,0BAAA,EAA6B,KAAK,CAAA,CAAE,CAAA;AACpF,IAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,IAAK,OAAO,GAAG,CAAA;AAC7C,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,QAAQ,OAAA,EAAS;AAC9C,MAAA,MAAM,IAAI,MAAM,CAAA,kBAAA,EAAqB,OAAO,YAAY,KAAK,CAAA,QAAA,EAAW,KAAK,CAAA,CAAE,CAAA;AAAA,IACjF;AAAA,EACF;AACF,CAAA;AAEA,IAAA;AAAA,EACE,mDAAA;AAAA,EACA,eAAuC,eAAA,EAAyB;AAC9D,IAAA,MAAM,KAAA,GAAQ,sBAAA,CAAuB,eAAA,EAAiB,OAAO,CAAA;AAC7D,IAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAM,IAAA,CAAK,SAAQ,EAAG,KAAA;AAAA,MACxC,6BAA6B,KAAK,CAAA,gCAAA;AAAA,KACpC;AACA,IAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,IAAK,OAAO,GAAG,CAAA;AAC7C,IAAA,IAAI,KAAA,KAAU,GAAG,MAAM,IAAI,MAAM,CAAA,EAAG,KAAK,CAAA,iBAAA,EAAoB,KAAK,CAAA,CAAE,CAAA;AAAA,EACtE;AACF,CAAA;AAEA,IAAA;AAAA,EACE,iDAAA;AAAA,EACA,eAAuC,KAAA,EAAe,GAAA,EAAa,MAAA,EAAgB;AACjF,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,EAAQ;AAC/B,IAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,KAAA,CAAM,6BAA6B,GAAA,CAAI,IAAA,CAAK,KAAK,CAAC,CAAA,CAAE,CAAA;AAC3E,IAAA,MAAM,IAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,IAAK,OAAO,GAAG,CAAA;AACzC,IAAA,MAAM,SAAA,GAAa,SAAS,GAAA,GAAO,GAAA;AACnC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,MAAM,IAAI,SAAA,EAAW;AACpC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,UAAA,EAAa,CAAC,CAAA,IAAA,EAAO,KAAK,CAAA,YAAA,EAAe,MAAM,CAAA,MAAA,EAAM,SAAS,CAAA,CAAE,CAAA;AAAA,IAClF;AAAA,EACF;AACF,CAAA;AAEA,IAAA,CAAK,gCAAA,EAAkC,SAAiC,KAAA,EAAe;AACrF,EAAA,IAAI,CAAC,IAAA,CAAK,OAAA,EAAS,MAAM,IAAI,MAAM,8DAAyD,CAAA;AAC5F,EAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,YAAA,KAAiB,KAAA,EAAO;AACvC,IAAA,MAAM,IAAI,MAAM,CAAA,iBAAA,EAAoB,IAAA,CAAK,QAAQ,YAAY,CAAA,WAAA,EAAc,KAAK,CAAA,CAAE,CAAA;AAAA,EACpF;AACF,CAAC,CAAA;AAED,IAAA;AAAA,EACE,iDAAA;AAAA,EACA,eAAuC,UAAA,EAAoB;AACzD,IAAA,IAAI,CAAC,KAAK,kBAAA,EAAoB;AAC5B,MAAA,MAAM,IAAI,MAAM,iFAA4E,CAAA;AAAA,IAC9F;AACA,IAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,OAAA,CAAQ,GAAG,CAAA;AAC9C,IAAA,MAAM,qBAAA;AAAA,MACJ,MAAA;AAAA,MACA,KAAK,kBAAA,CAAmB,UAAA;AAAA,MACxB,KAAK,kBAAA,CAAmB,QAAA;AAAA,MACxB,EAAE,WAAW,UAAA;AAAW,KAC1B;AAAA,EACF;AACF,CAAA;AAIA,SAAS,YAAY,KAAA,EAA8B;AACjD,EAAA,IAAI,MAAM,SAAA,EAAW;AACnB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,KAAA,CAAM,SAAA,CAAU,OAAO,CAAA,CAAE,CAAA;AAAA,EACzE;AACA,EAAA,IAAI,KAAA,CAAM,aAAa,IAAA,EAAM;AAC3B,IAAA,MAAM,IAAI,MAAM,+EAA0E,CAAA;AAAA,EAC5F;AACF;AAEA,SAAS,SAAA,CAAU,GAAY,CAAA,EAAqB;AAClD,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;AAC7E,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;AAEA,SAAS,sBAAA,CAAuB,OAAe,KAAA,EAAuB;AACpE,EAAA,IAAI,CAAC,KAAA,CAAM,UAAA,CAAW,GAAG,GAAG,OAAO,KAAA;AACnC,EAAA,MAAM,WAAW,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,KAAA,CAAM,CAAC,CAAC,CAAA;AAC3C,EAAA,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,mBAAA,CAAqB,CAAA;AACtE,EAAA,OAAO,QAAA;AACT;AAEA,IAAM,kBAAA,uBAAyB,GAAA,CAAI;AAAA,EACjC,gBAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,eAAe,GAAA,EAItB;AACA,EAAA,MAAM,iBAAiB,GAAA,CAAI,cAAA,IAAkB,QAAA,EAAU,IAAA,GAAO,WAAA,EAAY;AAC1E,EAAA,IAAI,CAAC,CAAC,SAAA,EAAW,QAAA,EAAU,SAAS,QAAQ,CAAA,CAAE,QAAA,CAAS,aAAa,CAAA,EAAG;AACrE,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,4BAAA,EAA+B,aAAa,CAAA,CAAA,CAAG,CAAA;AAAA,EACjE;AACA,EAAA,MAAM,SAAA,GAAY,oBAAA,CAAqB,GAAA,CAAI,SAAA,IAAa,EAAE,CAAA;AAC1D,EAAA,MAAM,cAAc,GAAA,CAAI,SAAA,IAAa,IAAI,UAAA,IAAc,EAAA,EACpD,MAAM,GAAG,CAAA,CACT,IAAI,CAAC,KAAA,KAAU,MAAM,IAAA,EAAK,CAAE,aAAa,CAAA,CACzC,OAAO,OAAO,CAAA;AACjB,EAAA,IAAI,UAAA,CAAW,MAAA,KAAW,CAAA,IAAK,UAAA,CAAW,IAAA,CAAK,CAAC,KAAA,KAAU,CAAC,kBAAA,CAAmB,GAAA,CAAI,KAAK,CAAC,CAAA,EAAG;AACzF,IAAA,MAAM,IAAI,MAAM,CAAA,iCAAA,EAAoC,GAAA,CAAI,aAAa,GAAA,CAAI,UAAA,IAAc,EAAE,CAAA,CAAA,CAAG,CAAA;AAAA,EAC9F;AACA,EAAA,OAAO,EAAE,aAAA,EAAe,SAAA,EAAW,UAAA,EAAW;AAChD","file":"steps.js","sourcesContent":["/**\n * The Databricks step library. Importing this module registers hooks and\n * steps with cucumber's global support registry — add it to your cucumber\n * config: `import: ['node_modules/@fabricorg/databricks-bdd/dist/steps.js']`\n * (or 'src/steps.ts' inside this repo, running cucumber under tsx).\n *\n * Keep step text engine-neutral (no TS-isms): the same .feature files must\n * stay executable by a future pytest-bdd step library (ADR-0006).\n */\nimport { randomUUID } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { basename, isAbsolute, relative, resolve } from 'node:path';\nimport {\n After,\n AfterStep,\n Before,\n BeforeAll,\n type DataTable,\n Given,\n Then,\n When,\n setDefaultTimeout,\n setWorldConstructor,\n} from '@cucumber/cucumber';\nimport {\n assertDeltaContract,\n compareToGolden,\n createClientFromEnv,\n createExecutionContext,\n createLakebaseTestProvider,\n dbtBuildCheck,\n deleteVolumeFile,\n ensureVolumeDirectory,\n expectTable,\n normalizeVolumeRoot,\n notebookSubmitCheck,\n resolveProfile,\n uploadVolumeFile,\n} from '@fabricorg/databricks-testkit';\nimport { redactSecrets } from './evidence-formatter.js';\nimport { coerceMatchRows, inferFixture } from './infer.js';\nimport { runJobToTerminal } from './jobs.js';\nimport { parseTableIdentifier, registerParameterTypes } from './parameter-types.js';\nimport { resolvePipelineId, startPipelineUpdate, waitForPipelineUpdate } from './pipelines.js';\nimport { liveOnlyReason } from './profile.js';\nimport { DatabricksWorld } from './world.js';\n\nsetWorldConstructor(DatabricksWorld);\nsetDefaultTimeout(60_000);\nregisterParameterTypes();\n\nBeforeAll(async () => {\n if (resolveProfile() !== 'live') return;\n const context = await createExecutionContext({ profile: 'live' });\n try {\n const rows = await context.query('SELECT 1 AS dbx_bdd_preflight');\n if (Number(rows[0]?.dbx_bdd_preflight) !== 1) {\n throw new Error('Databricks BDD preflight returned an unexpected value');\n }\n } finally {\n await context.close();\n }\n});\n\nBefore(function (this: DatabricksWorld, { pickle }) {\n const tags = pickle.tags.map((t) => t.name);\n const reason = liveOnlyReason(tags, this.profile);\n if (reason) return 'skipped';\n return undefined;\n});\n\nAfter(async function (this: DatabricksWorld) {\n await this.dispose();\n});\n\nAfterStep(async function (this: DatabricksWorld, { result, pickleStep }) {\n if (result.status !== 'FAILED') return;\n const evidence = {\n step: pickleStep.text,\n ...(this.lastStatementId ? { statementId: this.lastStatementId } : {}),\n ...(this.lastSql ? { sql: redactSecrets(this.lastSql).slice(0, 4_000) } : {}),\n };\n await this.attach(JSON.stringify(evidence, null, 2), 'application/json');\n});\n\n// ---------------------------------------------------------------- Given ----\n\nGiven('a Databricks workspace', async function (this: DatabricksWorld) {\n // local profile: DuckDB stands in — nothing to validate.\n // live profile: eagerly resolve auth + warehouse so misconfiguration fails here.\n if (this.profile === 'live') await this.context();\n});\n\nGiven('a Lakebase database', async function (this: DatabricksWorld) {\n if (this.profile !== 'live') {\n throw new Error('Lakebase steps require DBX_TEST_PROFILE=live and the @lakebase tag');\n }\n const provider = createLakebaseTestProvider(process.env);\n this.lakebasePool = provider.getPool();\n this.addCleanup(async () => {\n this.lakebasePool = undefined;\n await provider.close();\n });\n await this.lakebasePool.query('SELECT 1 AS dbx_bdd_lakebase');\n});\n\nGiven(\n 'catalog {string} and schema {string}',\n function (this: DatabricksWorld, catalog: string, schema: string) {\n this.scopeTo(catalog, schema);\n },\n);\n\nGiven(\n 'a table {string} with:',\n async function (this: DatabricksWorld, table: string, data: DataTable) {\n const ctx = await this.context();\n await ctx.loadFixture(inferFixture(table, data.raw()));\n },\n);\n\nGiven(\n 'a table {string} with schema {string} and rows:',\n async function (this: DatabricksWorld, table: string, schema: string, data: DataTable) {\n const ctx = await this.context();\n await ctx.loadFixture({ table, schema, rows: data.hashes() });\n },\n);\n\nGiven(\n 'an empty table {string} with schema {string}',\n async function (this: DatabricksWorld, table: string, schema: string) {\n const ctx = await this.context();\n await ctx.loadFixture({ table, schema, rows: [] });\n },\n);\n\nGiven(\n 'a table {string} with schema {string} from fixture {string}',\n async function (this: DatabricksWorld, table: string, schema: string, ndjsonFile: string) {\n const ctx = await this.context();\n await ctx.loadFixture({ table, schema, ndjsonFile });\n },\n);\n\nGiven(\n 'fixture files uploaded to volume {string}:',\n async function (this: DatabricksWorld, configuredVolume: string, data: DataTable) {\n if (this.profile !== 'live') {\n throw new Error('Volume upload steps require DBX_TEST_PROFILE=live and the @live tag');\n }\n const volumeValue = configuredVolume.startsWith('$')\n ? process.env[configuredVolume.slice(1)]\n : configuredVolume;\n if (!volumeValue) throw new Error(`Volume '${configuredVolume}' is not configured`);\n const root = normalizeVolumeRoot(volumeValue);\n const rows = data.hashes();\n const uploadPrefix = rows[0]?.prefix?.trim() ?? '';\n if (uploadPrefix && !/^[A-Za-z0-9_.-]+(?:\\/[A-Za-z0-9_.-]+)*$/.test(uploadPrefix)) {\n throw new Error(`Invalid volume fixture prefix '${uploadPrefix}'`);\n }\n if (rows.some((row) => (row.prefix?.trim() ?? '') !== uploadPrefix)) {\n throw new Error('All fixture rows in one upload step must use the same prefix');\n }\n const runPrefix = `${(process.env.DBX_TEST_ENV_NAME ?? 'bdd').replace(/[^A-Za-z0-9_.-]/g, '_')}/${randomUUID()}`;\n const directory = `${root}${uploadPrefix ? `/${uploadPrefix}` : ''}/${runPrefix}`;\n await ensureVolumeDirectory(process.env, directory);\n const paths = rows.map((row) => row.path).filter((path): path is string => Boolean(path));\n if (paths.length === 0) throw new Error('Fixture upload table requires a path column');\n for (const source of paths) {\n const absolute = resolve(process.cwd(), source);\n const fromCwd = relative(process.cwd(), absolute);\n if (fromCwd.startsWith('..') || isAbsolute(fromCwd)) {\n throw new Error(`Fixture path escapes the feature workspace: ${source}`);\n }\n const destination = `${directory}/${basename(source)}`;\n await uploadVolumeFile(process.env, destination, new Uint8Array(await readFile(absolute)));\n this.addCleanup(() => deleteVolumeFile(process.env, destination));\n }\n },\n);\n\nGiven(\n 'service principal {string} with grants:',\n async function (this: DatabricksWorld, principalKey: string, data: DataTable) {\n if (this.profile !== 'live') {\n throw new Error('Service-principal scenarios require DBX_TEST_PROFILE=live and @live');\n }\n const envPrefix = `DBX_TEST_PRINCIPAL_${principalKey.replace(/[^A-Za-z0-9]/g, '_').toUpperCase()}`;\n const clientId = process.env[`${envPrefix}_CLIENT_ID`];\n const clientSecret = process.env[`${envPrefix}_CLIENT_SECRET`];\n const principalName = process.env[`${envPrefix}_NAME`] ?? principalKey;\n if (!clientId || !clientSecret) {\n throw new Error(`Missing ${envPrefix}_CLIENT_ID and ${envPrefix}_CLIENT_SECRET`);\n }\n const primary = await this.context();\n const grants = data.hashes().map((row) => normalizeGrant(row));\n if (grants.length === 0) throw new Error('Grant table contains no rows');\n const quotedPrincipal = `\\`${principalName.replaceAll('`', '``')}\\``;\n for (const grant of grants) {\n await primary.exec(\n `GRANT ${grant.privileges.join(', ')} ON ${grant.securableType} ${grant.securable} TO ${quotedPrincipal}`,\n );\n }\n this.addCleanup(async () => {\n for (const grant of [...grants].reverse()) {\n await primary.exec(\n `REVOKE ${grant.privileges.join(', ')} ON ${grant.securableType} ${grant.securable} FROM ${quotedPrincipal}`,\n );\n }\n });\n const secondaryEnv = {\n ...process.env,\n DATABRICKS_BEARER: undefined,\n DATABRICKS_TOKEN: undefined,\n DATABRICKS_CLIENT_ID: clientId,\n DATABRICKS_CLIENT_SECRET: clientSecret,\n };\n const secondary = await createExecutionContext({\n profile: 'live',\n env: secondaryEnv,\n schema: this.schemaOverride ?? this.parameters.schema,\n onStatement: ({ sql, statementId }) => {\n this.lastSql = sql;\n this.lastStatementId = statementId;\n },\n });\n this.useExecutionContext(secondary);\n },\n);\n\n// ----------------------------------------------------------------- When ----\n\nWhen('I run the SQL:', async function (this: DatabricksWorld, sql: string) {\n const ctx = await this.context();\n this.lastSql = sql;\n this.lastError = null;\n this.lastRows = null;\n try {\n this.lastRows = await ctx.query(sql);\n } catch (error) {\n this.lastError = error instanceof Error ? error : new Error(String(error));\n }\n});\n\nWhen('I query Lakebase:', async function (this: DatabricksWorld, sql: string) {\n if (!this.lakebasePool) {\n throw new Error('No Lakebase database in this scenario — add Given a Lakebase database');\n }\n this.lastSql = sql;\n this.lastError = null;\n this.lastRows = null;\n try {\n const result = await this.lakebasePool.query(sql);\n this.lastRows = result.rows;\n } catch (error) {\n this.lastError = error instanceof Error ? error : new Error(String(error));\n }\n});\n\nWhen('I query table {string}', async function (this: DatabricksWorld, table: string) {\n const ctx = await this.context();\n this.lastRows = await ctx.query(`SELECT * FROM ${ctx.qual(table)}`);\n});\n\nWhen('I run job {string}', async function (this: DatabricksWorld, nameOrId: string) {\n const client = createClientFromEnv(process.env);\n const result = await runJobToTerminal(client, nameOrId);\n this.lastRun = { result_state: result.resultState, life_cycle_state: result.lifeCycleState };\n});\n\nWhen('I submit notebook {string}', async function (this: DatabricksWorld, notebookPath: string) {\n const client = createClientFromEnv(process.env);\n await notebookSubmitCheck().run({\n env: { ...process.env, DBX_TEST_NOTEBOOK_PATH: notebookPath },\n warehouse: await this.context(),\n client,\n });\n this.lastRun = { result_state: 'SUCCESS', life_cycle_state: 'TERMINATED' };\n});\n\nWhen('I run dbt build for {string}', async function (this: DatabricksWorld, project: string) {\n const client = createClientFromEnv(process.env);\n await dbtBuildCheck().run({\n env: { ...process.env, DBX_TEST_DBT_PROJECT_DIR: project },\n warehouse: await this.context(),\n client,\n });\n this.lastRun = { result_state: 'SUCCESS', life_cycle_state: 'TERMINATED' };\n});\n\nWhen(\n 'I start a full refresh of pipeline {string}',\n async function (this: DatabricksWorld, nameOrId: string) {\n const isolated = process.env.DBX_TEST_AUTOLOADER_PIPELINE_ID;\n const requested = nameOrId.startsWith('$') ? process.env[nameOrId.slice(1)] : nameOrId;\n if (!isolated || !requested || requested !== isolated) {\n throw new Error(\n 'Full refresh is restricted to DBX_TEST_AUTOLOADER_PIPELINE_ID; production pipelines are never full-refreshed by BDD tests',\n );\n }\n const client = createClientFromEnv(process.env);\n const pipelineId = await resolvePipelineId(client, requested);\n const updateId = await startPipelineUpdate(client, pipelineId, { fullRefresh: true });\n this.lastPipelineUpdate = { pipelineId, updateId };\n },\n);\n\nWhen(\n 'I start a refresh of pipeline {string}',\n async function (this: DatabricksWorld, nameOrId: string) {\n const requested = nameOrId.startsWith('$') ? process.env[nameOrId.slice(1)] : nameOrId;\n if (!requested) throw new Error(`Pipeline '${nameOrId}' is not configured`);\n const client = createClientFromEnv(process.env);\n const pipelineId = await resolvePipelineId(client, requested);\n const updateId = await startPipelineUpdate(client, pipelineId, { fullRefresh: false });\n this.lastPipelineUpdate = { pipelineId, updateId };\n },\n);\n\n// ----------------------------------------------------------------- Then ----\n\nThen(\n 'table {string} has {int} rows',\n async function (this: DatabricksWorld, table: string, n: number) {\n await expectTable(await this.context(), table).toHaveRowCount(n);\n },\n);\n\nThen(\n 'table {string} contains rows matching:',\n async function (this: DatabricksWorld, table: string, data: DataTable) {\n await expectTable(await this.context(), table).toContainRows(coerceMatchRows(data.raw()));\n },\n);\n\nThen(\n 'table {string} contains exactly:',\n async function (this: DatabricksWorld, table: string, data: DataTable) {\n const ctx = await this.context();\n const expected = coerceMatchRows(data.raw());\n const header = (data.raw()[0] ?? []).join(', ');\n const rows = await ctx.query(`SELECT ${header} FROM ${ctx.qual(table)}`);\n if (rows.length !== expected.length) {\n throw new Error(`Expected exactly ${expected.length} rows in ${table}, found ${rows.length}`);\n }\n await expectTable(ctx, table).toContainRows(expected);\n },\n);\n\nThen(\n 'table {string} matches golden {string} ordered by {string}',\n async function (this: DatabricksWorld, table: string, golden: string, orderBy: string) {\n await expectTable(await this.context(), table).toMatchGolden(golden, { orderBy });\n },\n);\n\nThen(\n 'table {string} matches schema contract {string}',\n async function (this: DatabricksWorld, table: string, contractFile: string) {\n const absolute = resolve(process.cwd(), contractFile);\n const fromCwd = relative(process.cwd(), absolute);\n if (fromCwd.startsWith('..') || isAbsolute(fromCwd)) {\n throw new Error(`Schema contract path escapes the feature workspace: ${contractFile}`);\n }\n const parsed = JSON.parse(await readFile(absolute, 'utf8')) as\n | { columns?: { name: string; type?: string }[] }\n | { name: string; type?: string }[];\n const columns = Array.isArray(parsed) ? parsed : parsed.columns;\n if (!columns || columns.length === 0) {\n throw new Error(`Schema contract ${contractFile} contains no columns`);\n }\n const ctx = await this.context();\n const rows = await ctx.query(`DESCRIBE TABLE ${ctx.qual(table)}`);\n assertDeltaContract(table, rows, columns);\n },\n);\n\nThen('the result has {int} rows', function (this: DatabricksWorld, n: number) {\n requireRows(this);\n if (this.lastRows?.length !== n) {\n throw new Error(`Expected ${n} result rows, got ${this.lastRows?.length}`);\n }\n});\n\nThen('the result contains rows matching:', function (this: DatabricksWorld, data: DataTable) {\n requireRows(this);\n const rows = this.lastRows ?? [];\n for (const partial of coerceMatchRows(data.raw())) {\n const hit = rows.some((row) =>\n Object.entries(partial).every(([key, value]) => cellEqual(row[key], value)),\n );\n if (!hit) {\n throw new Error(\n `Result does not contain a row matching ${JSON.stringify(partial)} — rows: ${JSON.stringify(rows.slice(0, 5))}`,\n );\n }\n }\n});\n\nThen('the result matches golden {string}', async function (this: DatabricksWorld, golden: string) {\n requireRows(this);\n await compareToGolden(golden, this.lastRows ?? [], 'result');\n});\n\nThen('the statement fails with {string}', function (this: DatabricksWorld, fragment: string) {\n if (!this.lastError)\n throw new Error(`Expected the statement to fail with '${fragment}', but it succeeded`);\n if (!this.lastError.message.toLowerCase().includes(fragment.toLowerCase())) {\n throw new Error(`Statement failed, but with a different error: ${this.lastError.message}`);\n }\n});\n\nThen('the statement fails with permission denied', function (this: DatabricksWorld) {\n if (!this.lastError) throw new Error('Expected a permission error, but the statement succeeded');\n if (!/permission.?denied|insufficient.?priv|403|unauthoriz/i.test(this.lastError.message)) {\n throw new Error(`Statement failed, but not with a permission error: ${this.lastError.message}`);\n }\n});\n\nThen(\n 'no rows were rescued in table {string}',\n async function (this: DatabricksWorld, table: string) {\n const ctx = await this.context();\n const rows = await ctx.query(\n `SELECT COUNT(*) AS n FROM ${ctx.qual(table)} WHERE _rescued_data IS NOT NULL`,\n );\n const n = Number(rows[0]?.n ?? Number.NaN);\n if (n !== 0) {\n throw new Error(`${n} rescued rows in ${table} — the ingestion contract drifted`);\n }\n },\n);\n\nThen(\n 'configured table {string} has at least {int} rows',\n async function (this: DatabricksWorld, configuredTable: string, minimum: number) {\n const table = resolveConfiguredValue(configuredTable, 'table');\n parseTableIdentifier(table);\n const rows = await (await this.context()).query(`SELECT COUNT(*) AS n FROM ${table}`);\n const count = Number(rows[0]?.n ?? Number.NaN);\n if (!Number.isFinite(count) || count < minimum) {\n throw new Error(`Expected at least ${minimum} rows in ${table}, found ${count}`);\n }\n },\n);\n\nThen(\n 'no rows were rescued in configured table {string}',\n async function (this: DatabricksWorld, configuredTable: string) {\n const table = resolveConfiguredValue(configuredTable, 'table');\n parseTableIdentifier(table);\n const rows = await (await this.context()).query(\n `SELECT COUNT(*) AS n FROM ${table} WHERE _rescued_data IS NOT NULL`,\n );\n const count = Number(rows[0]?.n ?? Number.NaN);\n if (count !== 0) throw new Error(`${count} rescued rows in ${table}`);\n },\n);\n\nThen(\n 'row count of {string} is within {int}% of {int}',\n async function (this: DatabricksWorld, table: string, pct: number, target: number) {\n const ctx = await this.context();\n const rows = await ctx.query(`SELECT COUNT(*) AS n FROM ${ctx.qual(table)}`);\n const n = Number(rows[0]?.n ?? Number.NaN);\n const tolerance = (target * pct) / 100;\n if (Math.abs(n - target) > tolerance) {\n throw new Error(`Row count ${n} of ${table} is outside ${target} ± ${tolerance}`);\n }\n },\n);\n\nThen('the job run reaches {runState}', function (this: DatabricksWorld, state: string) {\n if (!this.lastRun) throw new Error('No job run in this scenario — add a When I run job step');\n if (this.lastRun.result_state !== state) {\n throw new Error(`Job run ended in ${this.lastRun.result_state}, expected ${state}`);\n }\n});\n\nThen(\n 'the pipeline update completes within {duration}',\n async function (this: DatabricksWorld, durationMs: number) {\n if (!this.lastPipelineUpdate) {\n throw new Error('No pipeline update in this scenario — add a When I start ... pipeline step');\n }\n const client = createClientFromEnv(process.env);\n await waitForPipelineUpdate(\n client,\n this.lastPipelineUpdate.pipelineId,\n this.lastPipelineUpdate.updateId,\n { timeoutMs: durationMs },\n );\n },\n);\n\n// ------------------------------------------------------------------ util ---\n\nfunction requireRows(world: DatabricksWorld): void {\n if (world.lastError) {\n throw new Error(`The last statement failed: ${world.lastError.message}`);\n }\n if (world.lastRows === null) {\n throw new Error('No result captured — add a When I run the SQL / I query table step first');\n }\n}\n\nfunction cellEqual(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 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\nfunction resolveConfiguredValue(value: string, label: string): string {\n if (!value.startsWith('$')) return value;\n const resolved = process.env[value.slice(1)];\n if (!resolved) throw new Error(`${label} '${value}' is not configured`);\n return resolved;\n}\n\nconst ALLOWED_PRIVILEGES = new Set([\n 'ALL PRIVILEGES',\n 'USE CATALOG',\n 'USE SCHEMA',\n 'SELECT',\n 'MODIFY',\n 'READ VOLUME',\n 'WRITE VOLUME',\n]);\n\nfunction normalizeGrant(row: Record<string, string>): {\n securableType: string;\n securable: string;\n privileges: string[];\n} {\n const securableType = (row.securable_type ?? 'SCHEMA').trim().toUpperCase();\n if (!['CATALOG', 'SCHEMA', 'TABLE', 'VOLUME'].includes(securableType)) {\n throw new Error(`Unsupported securable_type '${securableType}'`);\n }\n const securable = parseTableIdentifier(row.securable ?? '');\n const privileges = (row.privilege ?? row.privileges ?? '')\n .split(',')\n .map((value) => value.trim().toUpperCase())\n .filter(Boolean);\n if (privileges.length === 0 || privileges.some((value) => !ALLOWED_PRIVILEGES.has(value))) {\n throw new Error(`Unsupported or empty privileges '${row.privilege ?? row.privileges ?? ''}'`);\n }\n return { securableType, securable, privileges };\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fabricorg/databricks-bdd",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Gherkin (cucumber-js) step library for testing Databricks artifacts — one .feature file runs on DuckDB locally and on a live workspace.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"module": "./dist/index.js",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"require": {
|
|
18
|
+
"types": "./dist/index.d.cts",
|
|
19
|
+
"default": "./dist/index.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"./steps": {
|
|
23
|
+
"import": {
|
|
24
|
+
"types": "./dist/steps.d.ts",
|
|
25
|
+
"default": "./dist/steps.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"./evidence-formatter": {
|
|
29
|
+
"import": {
|
|
30
|
+
"types": "./dist/evidence-formatter.d.ts",
|
|
31
|
+
"default": "./dist/evidence-formatter.js"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
],
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@cucumber/cucumber": "^13.0.0",
|
|
40
|
+
"@fabric-harness/databricks": "^1.2.3",
|
|
41
|
+
"@fabricorg/databricks-testkit": "0.1.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@duckdb/node-api": ">=1.4.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependenciesMeta": {
|
|
47
|
+
"@duckdb/node-api": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@duckdb/node-api": "1.5.4-r.1",
|
|
53
|
+
"@types/node": "^22.15.3",
|
|
54
|
+
"tsup": "^8.3.5",
|
|
55
|
+
"tsx": "^4.19.2",
|
|
56
|
+
"typescript": "^5.8.3",
|
|
57
|
+
"vitest": "^2.1.8"
|
|
58
|
+
},
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "tsup",
|
|
61
|
+
"type-check": "tsc --noEmit",
|
|
62
|
+
"test": "vitest run",
|
|
63
|
+
"test:features": "NODE_OPTIONS=\"--import tsx\" cucumber-js",
|
|
64
|
+
"steps:catalog": "node scripts/steps-catalog.mjs",
|
|
65
|
+
"clean": "rm -rf dist reports"
|
|
66
|
+
}
|
|
67
|
+
}
|