@dbx-tools/cli 0.9.131 → 0.9.136

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.
@@ -31,13 +31,14 @@ function sendJson(response, status, body, setCookie) {
31
31
  /**
32
32
  * Hand every Better Auth and compatibility route to the shared gate runtime.
33
33
  */
34
- async function handleAuthRoute(request, response, path, gate, brandName) {
34
+ async function handleAuthRoute(request, response, path, gate, brandName, passkeyNamePrefix) {
35
35
  if (!tunnelGate.isAuthPath(path))
36
36
  return false;
37
37
  if (tunnelGate.wantsHostedLogin(request)) {
38
38
  response.writeHead(200, { "content-type": "text/html; charset=utf-8" });
39
39
  response.end(tunnelLoginPage.loginPageHtml({
40
40
  brandName,
41
+ passkeyNamePrefix,
41
42
  returnTo: tunnelGate.loginReturnTo(request),
42
43
  }));
43
44
  return true;
@@ -75,14 +76,18 @@ export async function startProxy(options) {
75
76
  void (async () => {
76
77
  const path = (request.url ?? "/").split("?")[0] ?? "/";
77
78
  const brandName = options.brandName ?? "this app";
78
- if (gate && (await handleAuthRoute(request, response, path, gate, brandName)))
79
+ const passkeyNamePrefix = options.passkeyNamePrefix;
80
+ if (gate &&
81
+ (await handleAuthRoute(request, response, path, gate, brandName, passkeyNamePrefix))) {
79
82
  return;
83
+ }
80
84
  if ((await decide(request)) === "deny") {
81
85
  // A denied browser navigation gets the hosted login page; anything else
82
86
  // (an XHR, a /ws upgrade probe, a non-HTML fetch) gets the 401 JSON.
83
87
  if (gate && tunnelGate.wantsLoginPage(request)) {
84
88
  const html = tunnelLoginPage.loginPageHtml({
85
89
  brandName,
90
+ passkeyNamePrefix,
86
91
  returnTo: tunnelGate.requestReturnTo(request),
87
92
  });
88
93
  response.writeHead(401, { "content-type": "text/html; charset=utf-8" });
@@ -140,4 +145,4 @@ export async function startProxy(options) {
140
145
  });
141
146
  })));
142
147
  }
143
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdHVubmVsL3Byb3h5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sRUFBRSxZQUFZLEVBQTZDLE1BQU0sV0FBVyxDQUFDO0FBRXBGLE9BQU8sRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekQsT0FBTyxFQUNMLElBQUksSUFBSSxVQUFVLEVBQ2xCLE9BQU8sSUFBSSxhQUFhLEVBQ3hCLFNBQVMsSUFBSSxlQUFlLEdBRTdCLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxXQUFXLE1BQU0sY0FBYyxDQUFDO0FBRXZDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUEyQjFDLFNBQVMsUUFBUSxDQUNmLFFBQXdCLEVBQ3hCLE1BQWMsRUFDZCxJQUFhLEVBQ2IsU0FBa0I7SUFFbEIsUUFBUSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUU7UUFDekIsY0FBYyxFQUFFLGtCQUFrQjtRQUNsQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0tBQ2xELENBQUMsQ0FBQztJQUNILFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3JDLENBQUM7QUFFRDs7R0FFRztBQUNILEtBQUssVUFBVSxlQUFlLENBQzVCLE9BQXdCLEVBQ3hCLFFBQXdCLEVBQ3hCLElBQVksRUFDWixJQUFpQixFQUNqQixTQUFpQjtJQUVqQixJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMvQyxJQUFJLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FB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QztJQUNMLENBQUMsQ0FBQyxDQUNMLENBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoZSByZXZlcnNlIHByb3h5IHRoYXQgbWFrZXMgdGhlIHdyYXBwZXIgcGF0aCBwb3NzaWJsZS5cbiAqXG4gKiBUaGUgd3JhcHBlciBjbGFpbXMgdGhlIFBVQkxJQyBwb3J0IGFuZCB0aGUgd3JhcHBlZCBhcHAgcnVucyBhcyBhIGNoaWxkIHByb2Nlc3NcbiAqIG9uIGEgcHJpdmF0ZSBsb29wYmFjayBwb3J0LCBzbyAtIHVubGlrZSB0aGUgaW4tcHJvY2VzcyBwbHVnaW4gLSB0aGVyZSBpcyBub1xuICogbWlkZGxld2FyZSBjaGFpbiB0byBpbnNlcnQgdGhlIGdhdGUgaW50by4gVGhpcyBwcm94eSBpcyB0aGF0IGluc2VydGlvbiBwb2ludDogaXRcbiAqIGFuc3dlcnMgdGhlIGxvZ2luIHJvdXRlcyBpdHNlbGYsIGFwcGxpZXMgdGhlIGdhdGUgdG8gZXZlcnl0aGluZyBlbHNlLCBhbmRcbiAqIGZvcndhcmRzIHdoYXQgc3Vydml2ZXMgdG8gdGhlIGNoaWxkLlxuICpcbiAqIFRoZSBnYXRpbmcgREVDSVNJT04gaXMgbm90IHJlaW1wbGVtZW50ZWQgaGVyZS4gYEBkYngtdG9vbHMvdHVubmVsYCdzXG4gKiBgZ2F0ZS5nYXRlUmVxdWVzdGAgbWFrZXMgaXQgLSB0aGUgc2FtZSBmdW5jdGlvbiB0aGUgRXhwcmVzcyBtaWRkbGV3YXJlIGNhbGxzIC1cbiAqIGFuZCB0aGlzIG1vZHVsZSBvbmx5IGRpZmZlcnMgaW4gaG93IHRoZSBvdXRjb21lIGlzIHdyaXR0ZW46IGEgcHJveGllZCByZXF1ZXN0XG4gKiBpbnN0ZWFkIG9mIGBuZXh0KClgLCBhIGB3cml0ZUhlYWRgIGluc3RlYWQgb2YgYHJlcy5qc29uYC4gVGhhdCBpcyBkZWxpYmVyYXRlOlxuICogdHdvIGluZGVwZW5kZW50IGltcGxlbWVudGF0aW9ucyBvZiBcIndoaWNoIHJlcXVlc3RzIGFyZSBnYXRlZCBhbmQgd2hpY2ggaGVhZGVyc1xuICogYXJlIHN0cmlwcGVkXCIgaXMgdGhlIG9uZSB3YXkgdGhpcyBwYWNrYWdlIGNvdWxkIGJlY29tZSBhIHNlY3VyaXR5IGJ1Zy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlU2VydmVyLCB0eXBlIEluY29taW5nTWVzc2FnZSwgdHlwZSBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJub2RlOmh0dHBcIjtcbmltcG9ydCB0eXBlIHsgU29ja2V0IH0gZnJvbSBcIm5vZGU6bmV0XCI7XG5pbXBvcnQgeyBlcnJvclV0aWxzLCBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHtcbiAgZ2F0ZSBhcyB0dW5uZWxHYXRlLFxuICBoZWFkZXJzIGFzIHR1bm5lbEhlYWRlcnMsXG4gIGxvZ2luUGFnZSBhcyB0dW5uZWxMb2dpblBhZ2UsXG4gIHR5cGUgQXV0aEdhdGVBcGksXG59IGZyb20gXCJAZGJ4LXRvb2xzL3R1bm5lbFwiO1xuaW1wb3J0IFByb3h5TW9kdWxlIGZyb20gXCJodHRwLXByb3h5LTNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDpwcm94eVwiKTtcblxudHlwZSBVcGdyYWRlU29ja2V0ID0gU29ja2V0ICYgeyBkZXN0cm95U29vbj86ICgpID0+IHZvaWQgfTtcblxuLyoqIExpc3RlbmVyLCB1cHN0cmVhbSBhcHBsaWNhdGlvbiwgYW5kIG9wdGlvbmFsIGF1dGhlbnRpY2F0aW9uIHNldHRpbmdzIGZvciB0aGUgd3JhcHBlciBwcm94eS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJveHlPcHRpb25zIHtcbiAgLyoqIFRoZSBwb3J0IHRoaXMgcHJveHkgbGlzdGVucyBvbiAtIHRoZSBwb3J0IHBvcnRyIGFuZCB0aGUgcGxhdGZvcm0gcm91dGUgdG8uICovXG4gIHB1YmxpY1BvcnQ6IG51bWJlcjtcbiAgLyoqIFRoZSBwcml2YXRlIGxvb3BiYWNrIHBvcnQgdGhlIHdyYXBwZWQgYXBwIGxpc3RlbnMgb24uICovXG4gIGFwcFBvcnQ6IG51bWJlcjtcbiAgLyoqIFRoZSBnYXRlIGhhbmRsZXJzLiBPbWl0dGVkIChhbiBgLS1pbnNlY3VyZWAgcnVuKSBmb3J3YXJkcyBldmVyeXRoaW5nLiAqL1xuICBnYXRlPzogQXV0aEdhdGVBcGk7XG4gIC8qKiBFeHRyYSBgeC1gIGhlYWRlcnMgdHVubmVsIHRyYWZmaWMgbWF5IGZvcndhcmQuICovXG4gIGZvcndhcmRIZWFkZXJzPzogcmVhZG9ubHkgc3RyaW5nW107XG4gIC8qKiBQYXRoIHByZWZpeGVzIHRvIGdhdGUgYmV5b25kIGAvYXBpL2AgKGUuZy4gYC93c2AgZm9yIGEgV2ViU29ja2V0IGFwcCkuICovXG4gIGdhdGVQYXRocz86IHJlYWRvbmx5IHN0cmluZ1tdO1xuICAvKiogQnJhbmQgbmFtZSBmb3IgdGhlIGhvc3RlZCBsb2dpbiBwYWdlIHNob3duIG9uIGEgZGVuaWVkIGJyb3dzZXIgbmF2aWdhdGlvbi4gKi9cbiAgYnJhbmROYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogQWRkcmVzc2VzIHRvIGxpc3RlbiBvbi4gRGVmYXVsdHMgdG8gYSBzaW5nbGUgYDAuMC4wLjBgIChldmVyeSBpbnRlcmZhY2UpLFxuICAgKiB0aGUgcG9ydHIvcGxhdGZvcm0gY2FzZS4gUGFzcyBzcGVjaWZpYyBpbnRlcmZhY2UgSVBzIHRvIGV4cG9zZSB0aGUgZ2F0ZSBvblxuICAgKiBvbmx5IHRob3NlIC0gZS5nLiBhbiBvdmVybGF5L0xBTiBhZGRyZXNzIHdoaWxlIGxvb3BiYWNrIHJlYWNoZXMgdGhlIHVwc3RyZWFtXG4gICAqIGRpcmVjdGx5IGFuZCB1bmdhdGVkLlxuICAgKi9cbiAgYmluZEhvc3RzPzogcmVhZG9ubHkgc3RyaW5nW107XG59XG5cbmZ1bmN0aW9uIHNlbmRKc29uKFxuICByZXNwb25zZTogU2VydmVyUmVzcG9uc2UsXG4gIHN0YXR1czogbnVtYmVyLFxuICBib2R5OiB1bmtub3duLFxuICBzZXRDb29raWU/OiBzdHJpbmcsXG4pOiB2b2lkIHtcbiAgcmVzcG9uc2Uud3JpdGVIZWFkKHN0YXR1cywge1xuICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgIC4uLihzZXRDb29raWUgPyB7IFwic2V0LWNvb2tpZVwiOiBzZXRDb29raWUgfSA6IHt9KSxcbiAgfSk7XG4gIHJlc3BvbnNlLmVuZChKU09OLnN0cmluZ2lmeShib2R5KSk7XG59XG5cbi8qKlxuICogSGFuZCBldmVyeSBCZXR0ZXIgQXV0aCBhbmQgY29tcGF0aWJpbGl0eSByb3V0ZSB0byB0aGUgc2hhcmVkIGdhdGUgcnVudGltZS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gaGFuZGxlQXV0aFJvdXRlKFxuICByZXF1ZXN0OiBJbmNvbWluZ01lc3NhZ2UsXG4gIHJlc3BvbnNlOiBTZXJ2ZXJSZXNwb25zZSxcbiAgcGF0aDogc3RyaW5nLFxuICBnYXRlOiBBdXRoR2F0ZUFwaSxcbiAgYnJhbmROYW1lOiBzdHJpbmcsXG4pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgaWYgKCF0dW5uZWxHYXRlLmlzQXV0aFBhdGgocGF0aCkpIHJldHVybiBmYWxzZTtcbiAgaWYgKHR1bm5lbEdhdGUud2FudHNIb3N0ZWRMb2dpbihyZXF1ZXN0KSkge1xuICAgIHJlc3BvbnNlLndyaXRlSGVhZCgyMDAsIHsgXCJjb250ZW50LXR5cGVcIjogXCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLThcIiB9KTtcbiAgICByZXNwb25zZS5lbmQoXG4gICAgICB0dW5uZWxMb2dpblBhZ2UubG9naW5QYWdlSHRtbCh7XG4gICAgICAgIGJyYW5kTmFtZSxcbiAgICAgICAgcmV0dXJuVG86IHR1bm5lbEdhdGUubG9naW5SZXR1cm5UbyhyZXF1ZXN0KSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ2F0ZS5oYW5kbGVyKHR1bm5lbEdhdGUud2ViUmVxdWVzdChyZXF1ZXN0KSk7XG4gIGF3YWl0IHR1bm5lbEdhdGUuc2VuZFdlYlJlc3BvbnNlKHJlc3BvbnNlLCByZXN1bHQpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBTdGFydCB0aGUgcHJveHkgYW5kIHJlc29sdmUgb25jZSBpdCBpcyBsaXN0ZW5pbmcuXG4gKlxuICogYHB1YmxpY0RvbWFpbmAgaXMgaW50ZW50aW9uYWxseSBOT1QgcGFzc2VkIHRvIGBnYXRlUmVxdWVzdGA6IG9uIHRoaXMgcGF0aCBldmVyeVxuICogcmVxdWVzdCBhcnJpdmVkIG9uIHRoZSBwdWJsaWMgcG9ydCwgc28gaXQgSVMgdHVubmVsIHRyYWZmaWMgYnkgY29uc3RydWN0aW9uIC1cbiAqIHdoZXJlYXMgdGhlIGluLXByb2Nlc3MgZ2F0ZSBzaGFyZXMgYSBwb3J0IHdpdGggdGhlIHBsYXRmb3JtIGZyb250IGRvb3IgYW5kIGhhc1xuICogdG8gdGVsbCB0aGVtIGFwYXJ0IGJ5IGBIb3N0YC4gUGFzc2luZyB0aGUgcmVxdWVzdCdzIG93biBob3N0IGtlZXBzIHRoZSBzaGFyZWRcbiAqIGRlY2lzaW9uIGZ1bmN0aW9uJ3MgY29udHJhY3Qgc2F0aXNmaWVkIHdpdGhvdXQgd2Vha2VuaW5nIGl0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRQcm94eShvcHRpb25zOiBQcm94eU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJveHkgPSBQcm94eU1vZHVsZS5jcmVhdGVQcm94eVNlcnZlcih7XG4gICAgdGFyZ2V0OiBgaHR0cDovLzEyNy4wLjAuMToke29wdGlvbnMuYXBwUG9ydH1gLFxuICAgIHdzOiB0cnVlLFxuICAgIHhmd2Q6IHRydWUsXG4gIH0pO1xuICBjb25zdCBoZWFkZXJQb2xpY3kgPSB0dW5uZWxIZWFkZXJzLnRvSGVhZGVyUG9saWN5KG9wdGlvbnMuZm9yd2FyZEhlYWRlcnMpO1xuICBjb25zdCBnYXRlID0gb3B0aW9ucy5nYXRlO1xuXG4gIGNvbnN0IGRlY2lkZSA9IChyZXF1ZXN0OiBJbmNvbWluZ01lc3NhZ2UpOiBQcm9taXNlPHR1bm5lbEdhdGUuR2F0ZUFjdGlvbj4gPT5cbiAgICBnYXRlXG4gICAgICA/IHR1bm5lbEdhdGUuZ2F0ZVJlcXVlc3QocmVxdWVzdCwge1xuICAgICAgICAgIGdhdGUsXG4gICAgICAgICAgcHVibGljRG9tYWluOiAocmVxdWVzdC5oZWFkZXJzLmhvc3QgPz8gXCJcIikuc3BsaXQoXCI6XCIpWzBdIHx8IFwibG9jYWxob3N0XCIsXG4gICAgICAgICAgaGVhZGVyUG9saWN5LFxuICAgICAgICAgIGdhdGVQYXRoczogb3B0aW9ucy5nYXRlUGF0aHMsXG4gICAgICAgIH0pXG4gICAgICA6IFByb21pc2UucmVzb2x2ZTx0dW5uZWxHYXRlLkdhdGVBY3Rpb24+KFwicGFzc1wiKTtcblxuICBjb25zdCBvblJlcXVlc3QgPSAocmVxdWVzdDogSW5jb21pbmdNZXNzYWdlLCByZXNwb25zZTogU2VydmVyUmVzcG9uc2UpOiB2b2lkID0+IHtcbiAgICB2b2lkIChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXRoID0gKHJlcXVlc3QudXJsID8/IFwiL1wiKS5zcGxpdChcIj9cIilbMF0gPz8gXCIvXCI7XG4gICAgICBjb25zdCBicmFuZE5hbWUgPSBvcHRpb25zLmJyYW5kTmFtZSA/PyBcInRoaXMgYXBwXCI7XG4gICAgICBpZiAoZ2F0ZSAmJiAoYXdhaXQgaGFuZGxlQXV0aFJvdXRlKHJlcXVlc3QsIHJlc3BvbnNlLCBwYXRoLCBnYXRlLCBicmFuZE5hbWUpKSkgcmV0dXJuO1xuICAgICAgaWYgKChhd2FpdCBkZWNpZGUocmVxdWVzdCkpID09PSBcImRlbnlcIikge1xuICAgICAgICAvLyBBIGRlbmllZCBicm93c2VyIG5hdmlnYXRpb24gZ2V0cyB0aGUgaG9zdGVkIGxvZ2luIHBhZ2U7IGFueXRoaW5nIGVsc2VcbiAgICAgICAgLy8gKGFuIFhIUiwgYSAvd3MgdXBncmFkZSBwcm9iZSwgYSBub24tSFRNTCBmZXRjaCkgZ2V0cyB0aGUgNDAxIEpTT04uXG4gICAgICAgIGlmIChnYXRlICYmIHR1bm5lbEdhdGUud2FudHNMb2dpblBhZ2UocmVxdWVzdCkpIHtcbiAgICAgICAgICBjb25zdCBodG1sID0gdHVubmVsTG9naW5QYWdlLmxvZ2luUGFnZUh0bWwoe1xuICAgICAgICAgICAgYnJhbmROYW1lLFxuICAgICAgICAgICAgcmV0dXJuVG86IHR1bm5lbEdhdGUucmVxdWVzdFJldHVyblRvKHJlcXVlc3QpLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCg0MDEsIHsgXCJjb250ZW50LXR5cGVcIjogXCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLThcIiB9KTtcbiAgICAgICAgICByZXNwb25zZS5lbmQoaHRtbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VuZEpzb24ocmVzcG9uc2UsIDQwMSwgdHVubmVsR2F0ZS51bmF1dGhvcml6ZWRCb2R5KHJlcXVlc3QpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBwcm94eS53ZWIocmVxdWVzdCwgcmVzcG9uc2UpO1xuICAgIH0pKCkuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICBsb2dnZXIuZXJyb3IoXCJwcm94eSByZXF1ZXN0IGZhaWxlZFwiLCB7IGVycm9yOiBlcnJvclV0aWxzLnRvRXJyb3IoZXJyb3IpIH0pO1xuICAgICAgaWYgKCFyZXNwb25zZS5oZWFkZXJzU2VudCkgc2VuZEpzb24ocmVzcG9uc2UsIDUwMiwgeyBlcnJvcjogXCJiYWQgZ2F0ZXdheVwiIH0pO1xuICAgICAgZWxzZSByZXNwb25zZS5lbmQoKTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBBIHdlYnNvY2tldCB1cGdyYWRlIGNhbm5vdCBiZSBhbnN3ZXJlZCB3aXRoIGEgNDAxIGJvZHksIHNvIGEgZGVuaWVkIG9uZSBpc1xuICAvLyBkZXN0cm95ZWQgLSB0aGUgY2xpZW50IHNlZXMgdGhlIGhhbmRzaGFrZSBmYWlsLCB3aGljaCBpcyB3aGF0IGEgYnJvd3NlcidzXG4gIC8vIFdlYlNvY2tldCBlcnJvciBoYW5kbGVyIGV4cGVjdHMuXG4gIGNvbnN0IG9uVXBncmFkZSA9IChyZXF1ZXN0OiBJbmNvbWluZ01lc3NhZ2UsIHNvY2tldDogU29ja2V0LCBoZWFkOiBCdWZmZXIpOiB2b2lkID0+IHtcbiAgICBjb25zdCB1cGdyYWRlU29ja2V0ID0gc29ja2V0IGFzIFVwZ3JhZGVTb2NrZXQ7XG4gICAgdXBncmFkZVNvY2tldC5kZXN0cm95U29vbiA/Pz0gKCkgPT4gdXBncmFkZVNvY2tldC5lbmQoKTtcbiAgICBjb25zdCBwYXRoID0gKHJlcXVlc3QudXJsID8/IFwiL1wiKS5zcGxpdChcIj9cIiwgMSlbMF0gPz8gXCIvXCI7XG4gICAgaWYgKHR1bm5lbEdhdGUuaXNBdXRoUGF0aChwYXRoKSkge1xuICAgICAgdXBncmFkZVNvY2tldC5kZXN0cm95KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZvaWQgZGVjaWRlKHJlcXVlc3QpXG4gICAgICAudGhlbigoYWN0aW9uKSA9PiB7XG4gICAgICAgIGlmIChhY3Rpb24gPT09IFwiZGVueVwiKSB1cGdyYWRlU29ja2V0LmRlc3Ryb3koKTtcbiAgICAgICAgZWxzZSBwcm94eS53cyhyZXF1ZXN0LCB1cGdyYWRlU29ja2V0LCBoZWFkKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4gdXBncmFkZVNvY2tldC5kZXN0cm95KCkpO1xuICB9O1xuXG4gIC8vIE9uZSBuZXQuU2VydmVyIGJpbmRzIG9uZSBhZGRyZXNzLCBzbyBsaXN0ZW4gZWFjaCBob3N0IG9uIGl0cyBvd24gc2VydmVyIHRoYXRcbiAgLy8gc2hhcmVzIHRoZSBzYW1lIGhhbmRsZXJzLiBCaW5kaW5nIHNwZWNpZmljIGludGVyZmFjZSBJUHMgKHJhdGhlciB0aGFuIHRoZVxuICAvLyBkZWZhdWx0IDAuMC4wLjApIGlzIHdoYXQgbGV0cyB0aGUgZ2F0ZSBmcm9udCBhbiBvdmVybGF5L0xBTiBhZGRyZXNzIHdoaWxlXG4gIC8vIGxvb3BiYWNrIHJlYWNoZXMgdGhlIHVwc3RyZWFtIHVuZ2F0ZWQuXG4gIGNvbnN0IGhvc3RzID0gb3B0aW9ucy5iaW5kSG9zdHM/Lmxlbmd0aCA/IG9wdGlvbnMuYmluZEhvc3RzIDogW1wiMC4wLjAuMFwiXTtcbiAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgaG9zdHMubWFwKFxuICAgICAgKGhvc3QpID0+XG4gICAgICAgIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc2VydmVyID0gY3JlYXRlU2VydmVyKG9uUmVxdWVzdCk7XG4gICAgICAgICAgc2VydmVyLm9uKFwidXBncmFkZVwiLCBvblVwZ3JhZGUpO1xuICAgICAgICAgIHNlcnZlci5saXN0ZW4ob3B0aW9ucy5wdWJsaWNQb3J0LCBob3N0LCAoKSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhcInByb3h5IGxpc3RlbmluZ1wiLCB7XG4gICAgICAgICAgICAgIGhvc3QsXG4gICAgICAgICAgICAgIHB1YmxpY1BvcnQ6IG9wdGlvbnMucHVibGljUG9ydCxcbiAgICAgICAgICAgICAgYXBwUG9ydDogb3B0aW9ucy5hcHBQb3J0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICksXG4gICk7XG59XG4iXX0=
148
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdHVubmVsL3Byb3h5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sRUFBRSxZQUFZLEVBQTZDLE1BQU0sV0FBVyxDQUFDO0FBRXBGLE9BQU8sRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekQsT0FBTyxFQUNMLElBQUksSUFBSSxVQUFVLEVBQ2xCLE9BQU8sSUFBSSxhQUFhLEVBQ3hCLFNBQVMsSUFBSSxlQUFlLEdBRTdCLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxXQUFXLE1BQU0sY0FBYyxDQUFDO0FBRXZDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUE2QjFDLFNBQVMsUUFBUSxDQUNmLFFBQXdCLEVBQ3hCLE1BQWMsRUFDZCxJQUFhLEVBQ2IsU0FBa0I7SUFFbEIsUUFBUSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUU7UUFDekIsY0FBYyxFQUFFLGtCQUFrQjtRQUNsQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0tBQ2xELENBQUMsQ0FBQztJQUNILFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3JDLENBQUM7QUFFRDs7R0FFRztBQUNILEtBQUssVUFBVSxlQUFlLENBQzVCLE9BQXdCLEVBQ3hCLFFBQXdCLEVBQ3hCLElBQVksRUFDWixJQUFpQixFQUNqQixTQUFpQixFQUNqQixpQkFBMEI7SUFFMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDL0MsSUFBSSxVQUFVLENB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O2dCQUNKLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtnQkFDOUIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO2FBQ3pCLENBQUMsQ0FBQztZQUNILE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FDTCxDQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgcmV2ZXJzZSBwcm94eSB0aGF0IG1ha2VzIHRoZSB3cmFwcGVyIHBhdGggcG9zc2libGUuXG4gKlxuICogVGhlIHdyYXBwZXIgY2xhaW1zIHRoZSBQVUJMSUMgcG9ydCBhbmQgdGhlIHdyYXBwZWQgYXBwIHJ1bnMgYXMgYSBjaGlsZCBwcm9jZXNzXG4gKiBvbiBhIHByaXZhdGUgbG9vcGJhY2sgcG9ydCwgc28gLSB1bmxpa2UgdGhlIGluLXByb2Nlc3MgcGx1Z2luIC0gdGhlcmUgaXMgbm9cbiAqIG1pZGRsZXdhcmUgY2hhaW4gdG8gaW5zZXJ0IHRoZSBnYXRlIGludG8uIFRoaXMgcHJveHkgaXMgdGhhdCBpbnNlcnRpb24gcG9pbnQ6IGl0XG4gKiBhbnN3ZXJzIHRoZSBsb2dpbiByb3V0ZXMgaXRzZWxmLCBhcHBsaWVzIHRoZSBnYXRlIHRvIGV2ZXJ5dGhpbmcgZWxzZSwgYW5kXG4gKiBmb3J3YXJkcyB3aGF0IHN1cnZpdmVzIHRvIHRoZSBjaGlsZC5cbiAqXG4gKiBUaGUgZ2F0aW5nIERFQ0lTSU9OIGlzIG5vdCByZWltcGxlbWVudGVkIGhlcmUuIGBAZGJ4LXRvb2xzL3R1bm5lbGAnc1xuICogYGdhdGUuZ2F0ZVJlcXVlc3RgIG1ha2VzIGl0IC0gdGhlIHNhbWUgZnVuY3Rpb24gdGhlIEV4cHJlc3MgbWlkZGxld2FyZSBjYWxscyAtXG4gKiBhbmQgdGhpcyBtb2R1bGUgb25seSBkaWZmZXJzIGluIGhvdyB0aGUgb3V0Y29tZSBpcyB3cml0dGVuOiBhIHByb3hpZWQgcmVxdWVzdFxuICogaW5zdGVhZCBvZiBgbmV4dCgpYCwgYSBgd3JpdGVIZWFkYCBpbnN0ZWFkIG9mIGByZXMuanNvbmAuIFRoYXQgaXMgZGVsaWJlcmF0ZTpcbiAqIHR3byBpbmRlcGVuZGVudCBpbXBsZW1lbnRhdGlvbnMgb2YgXCJ3aGljaCByZXF1ZXN0cyBhcmUgZ2F0ZWQgYW5kIHdoaWNoIGhlYWRlcnNcbiAqIGFyZSBzdHJpcHBlZFwiIGlzIHRoZSBvbmUgd2F5IHRoaXMgcGFja2FnZSBjb3VsZCBiZWNvbWUgYSBzZWN1cml0eSBidWcuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZVNlcnZlciwgdHlwZSBJbmNvbWluZ01lc3NhZ2UsIHR5cGUgU2VydmVyUmVzcG9uc2UgfSBmcm9tIFwibm9kZTpodHRwXCI7XG5pbXBvcnQgdHlwZSB7IFNvY2tldCB9IGZyb20gXCJub2RlOm5ldFwiO1xuaW1wb3J0IHsgZXJyb3JVdGlscywgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7XG4gIGdhdGUgYXMgdHVubmVsR2F0ZSxcbiAgaGVhZGVycyBhcyB0dW5uZWxIZWFkZXJzLFxuICBsb2dpblBhZ2UgYXMgdHVubmVsTG9naW5QYWdlLFxuICB0eXBlIEF1dGhHYXRlQXBpLFxufSBmcm9tIFwiQGRieC10b29scy90dW5uZWxcIjtcbmltcG9ydCBQcm94eU1vZHVsZSBmcm9tIFwiaHR0cC1wcm94eS0zXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWw6cHJveHlcIik7XG5cbnR5cGUgVXBncmFkZVNvY2tldCA9IFNvY2tldCAmIHsgZGVzdHJveVNvb24/OiAoKSA9PiB2b2lkIH07XG5cbi8qKiBMaXN0ZW5lciwgdXBzdHJlYW0gYXBwbGljYXRpb24sIGFuZCBvcHRpb25hbCBhdXRoZW50aWNhdGlvbiBzZXR0aW5ncyBmb3IgdGhlIHdyYXBwZXIgcHJveHkuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb3h5T3B0aW9ucyB7XG4gIC8qKiBUaGUgcG9ydCB0aGlzIHByb3h5IGxpc3RlbnMgb24gLSB0aGUgcG9ydCBwb3J0ciBhbmQgdGhlIHBsYXRmb3JtIHJvdXRlIHRvLiAqL1xuICBwdWJsaWNQb3J0OiBudW1iZXI7XG4gIC8qKiBUaGUgcHJpdmF0ZSBsb29wYmFjayBwb3J0IHRoZSB3cmFwcGVkIGFwcCBsaXN0ZW5zIG9uLiAqL1xuICBhcHBQb3J0OiBudW1iZXI7XG4gIC8qKiBUaGUgZ2F0ZSBoYW5kbGVycy4gT21pdHRlZCAoYW4gYC0taW5zZWN1cmVgIHJ1bikgZm9yd2FyZHMgZXZlcnl0aGluZy4gKi9cbiAgZ2F0ZT86IEF1dGhHYXRlQXBpO1xuICAvKiogRXh0cmEgYHgtYCBoZWFkZXJzIHR1bm5lbCB0cmFmZmljIG1heSBmb3J3YXJkLiAqL1xuICBmb3J3YXJkSGVhZGVycz86IHJlYWRvbmx5IHN0cmluZ1tdO1xuICAvKiogUGF0aCBwcmVmaXhlcyB0byBnYXRlIGJleW9uZCBgL2FwaS9gIChlLmcuIGAvd3NgIGZvciBhIFdlYlNvY2tldCBhcHApLiAqL1xuICBnYXRlUGF0aHM/OiByZWFkb25seSBzdHJpbmdbXTtcbiAgLyoqIEJyYW5kIG5hbWUgZm9yIHRoZSBob3N0ZWQgbG9naW4gcGFnZSBzaG93biBvbiBhIGRlbmllZCBicm93c2VyIG5hdmlnYXRpb24uICovXG4gIGJyYW5kTmFtZT86IHN0cmluZztcbiAgLyoqIFByZWZpeCBhZGRlZCBiZWZvcmUgdGhlIGh1bWFuaXplZCB0dW5uZWwgc3ViZG9tYWluIGluIG5ldyBwYXNza2V5IG5hbWVzLiAqL1xuICBwYXNza2V5TmFtZVByZWZpeD86IHN0cmluZztcbiAgLyoqXG4gICAqIEFkZHJlc3NlcyB0byBsaXN0ZW4gb24uIERlZmF1bHRzIHRvIGEgc2luZ2xlIGAwLjAuMC4wYCAoZXZlcnkgaW50ZXJmYWNlKSxcbiAgICogdGhlIHBvcnRyL3BsYXRmb3JtIGNhc2UuIFBhc3Mgc3BlY2lmaWMgaW50ZXJmYWNlIElQcyB0byBleHBvc2UgdGhlIGdhdGUgb25cbiAgICogb25seSB0aG9zZSAtIGUuZy4gYW4gb3ZlcmxheS9MQU4gYWRkcmVzcyB3aGlsZSBsb29wYmFjayByZWFjaGVzIHRoZSB1cHN0cmVhbVxuICAgKiBkaXJlY3RseSBhbmQgdW5nYXRlZC5cbiAgICovXG4gIGJpbmRIb3N0cz86IHJlYWRvbmx5IHN0cmluZ1tdO1xufVxuXG5mdW5jdGlvbiBzZW5kSnNvbihcbiAgcmVzcG9uc2U6IFNlcnZlclJlc3BvbnNlLFxuICBzdGF0dXM6IG51bWJlcixcbiAgYm9keTogdW5rbm93bixcbiAgc2V0Q29va2llPzogc3RyaW5nLFxuKTogdm9pZCB7XG4gIHJlc3BvbnNlLndyaXRlSGVhZChzdGF0dXMsIHtcbiAgICBcImNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAuLi4oc2V0Q29va2llID8geyBcInNldC1jb29raWVcIjogc2V0Q29va2llIH0gOiB7fSksXG4gIH0pO1xuICByZXNwb25zZS5lbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xufVxuXG4vKipcbiAqIEhhbmQgZXZlcnkgQmV0dGVyIEF1dGggYW5kIGNvbXBhdGliaWxpdHkgcm91dGUgdG8gdGhlIHNoYXJlZCBnYXRlIHJ1bnRpbWUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGhhbmRsZUF1dGhSb3V0ZShcbiAgcmVxdWVzdDogSW5jb21pbmdNZXNzYWdlLFxuICByZXNwb25zZTogU2VydmVyUmVzcG9uc2UsXG4gIHBhdGg6IHN0cmluZyxcbiAgZ2F0ZTogQXV0aEdhdGVBcGksXG4gIGJyYW5kTmFtZTogc3RyaW5nLFxuICBwYXNza2V5TmFtZVByZWZpeD86IHN0cmluZyxcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBpZiAoIXR1bm5lbEdhdGUuaXNBdXRoUGF0aChwYXRoKSkgcmV0dXJuIGZhbHNlO1xuICBpZiAodHVubmVsR2F0ZS53YW50c0hvc3RlZExvZ2luKHJlcXVlc3QpKSB7XG4gICAgcmVzcG9uc2Uud3JpdGVIZWFkKDIwMCwgeyBcImNvbnRlbnQtdHlwZVwiOiBcInRleHQvaHRtbDsgY2hhcnNldD11dGYtOFwiIH0pO1xuICAgIHJlc3BvbnNlLmVuZChcbiAgICAgIHR1bm5lbExvZ2luUGFnZS5sb2dpblBhZ2VIdG1sKHtcbiAgICAgICAgYnJhbmROYW1lLFxuICAgICAgICBwYXNza2V5TmFtZVByZWZpeCxcbiAgICAgICAgcmV0dXJuVG86IHR1bm5lbEdhdGUubG9naW5SZXR1cm5UbyhyZXF1ZXN0KSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ2F0ZS5oYW5kbGVyKHR1bm5lbEdhdGUud2ViUmVxdWVzdChyZXF1ZXN0KSk7XG4gIGF3YWl0IHR1bm5lbEdhdGUuc2VuZFdlYlJlc3BvbnNlKHJlc3BvbnNlLCByZXN1bHQpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBTdGFydCB0aGUgcHJveHkgYW5kIHJlc29sdmUgb25jZSBpdCBpcyBsaXN0ZW5pbmcuXG4gKlxuICogYHB1YmxpY0RvbWFpbmAgaXMgaW50ZW50aW9uYWxseSBOT1QgcGFzc2VkIHRvIGBnYXRlUmVxdWVzdGA6IG9uIHRoaXMgcGF0aCBldmVyeVxuICogcmVxdWVzdCBhcnJpdmVkIG9uIHRoZSBwdWJsaWMgcG9ydCwgc28gaXQgSVMgdHVubmVsIHRyYWZmaWMgYnkgY29uc3RydWN0aW9uIC1cbiAqIHdoZXJlYXMgdGhlIGluLXByb2Nlc3MgZ2F0ZSBzaGFyZXMgYSBwb3J0IHdpdGggdGhlIHBsYXRmb3JtIGZyb250IGRvb3IgYW5kIGhhc1xuICogdG8gdGVsbCB0aGVtIGFwYXJ0IGJ5IGBIb3N0YC4gUGFzc2luZyB0aGUgcmVxdWVzdCdzIG93biBob3N0IGtlZXBzIHRoZSBzaGFyZWRcbiAqIGRlY2lzaW9uIGZ1bmN0aW9uJ3MgY29udHJhY3Qgc2F0aXNmaWVkIHdpdGhvdXQgd2Vha2VuaW5nIGl0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRQcm94eShvcHRpb25zOiBQcm94eU9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJveHkgPSBQcm94eU1vZHVsZS5jcmVhdGVQcm94eVNlcnZlcih7XG4gICAgdGFyZ2V0OiBgaHR0cDovLzEyNy4wLjAuMToke29wdGlvbnMuYXBwUG9ydH1gLFxuICAgIHdzOiB0cnVlLFxuICAgIHhmd2Q6IHRydWUsXG4gIH0pO1xuICBjb25zdCBoZWFkZXJQb2xpY3kgPSB0dW5uZWxIZWFkZXJzLnRvSGVhZGVyUG9saWN5KG9wdGlvbnMuZm9yd2FyZEhlYWRlcnMpO1xuICBjb25zdCBnYXRlID0gb3B0aW9ucy5nYXRlO1xuXG4gIGNvbnN0IGRlY2lkZSA9IChyZXF1ZXN0OiBJbmNvbWluZ01lc3NhZ2UpOiBQcm9taXNlPHR1bm5lbEdhdGUuR2F0ZUFjdGlvbj4gPT5cbiAgICBnYXRlXG4gICAgICA/IHR1bm5lbEdhdGUuZ2F0ZVJlcXVlc3QocmVxdWVzdCwge1xuICAgICAgICAgIGdhdGUsXG4gICAgICAgICAgcHVibGljRG9tYWluOiAocmVxdWVzdC5oZWFkZXJzLmhvc3QgPz8gXCJcIikuc3BsaXQoXCI6XCIpWzBdIHx8IFwibG9jYWxob3N0XCIsXG4gICAgICAgICAgaGVhZGVyUG9saWN5LFxuICAgICAgICAgIGdhdGVQYXRoczogb3B0aW9ucy5nYXRlUGF0aHMsXG4gICAgICAgIH0pXG4gICAgICA6IFByb21pc2UucmVzb2x2ZTx0dW5uZWxHYXRlLkdhdGVBY3Rpb24+KFwicGFzc1wiKTtcblxuICBjb25zdCBvblJlcXVlc3QgPSAocmVxdWVzdDogSW5jb21pbmdNZXNzYWdlLCByZXNwb25zZTogU2VydmVyUmVzcG9uc2UpOiB2b2lkID0+IHtcbiAgICB2b2lkIChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXRoID0gKHJlcXVlc3QudXJsID8/IFwiL1wiKS5zcGxpdChcIj9cIilbMF0gPz8gXCIvXCI7XG4gICAgICBjb25zdCBicmFuZE5hbWUgPSBvcHRpb25zLmJyYW5kTmFtZSA/PyBcInRoaXMgYXBwXCI7XG4gICAgICBjb25zdCBwYXNza2V5TmFtZVByZWZpeCA9IG9wdGlvbnMucGFzc2tleU5hbWVQcmVmaXg7XG4gICAgICBpZiAoXG4gICAgICAgIGdhdGUgJiZcbiAgICAgICAgKGF3YWl0IGhhbmRsZUF1dGhSb3V0ZShyZXF1ZXN0LCByZXNwb25zZSwgcGF0aCwgZ2F0ZSwgYnJhbmROYW1lLCBwYXNza2V5TmFtZVByZWZpeCkpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKChhd2FpdCBkZWNpZGUocmVxdWVzdCkpID09PSBcImRlbnlcIikge1xuICAgICAgICAvLyBBIGRlbmllZCBicm93c2VyIG5hdmlnYXRpb24gZ2V0cyB0aGUgaG9zdGVkIGxvZ2luIHBhZ2U7IGFueXRoaW5nIGVsc2VcbiAgICAgICAgLy8gKGFuIFhIUiwgYSAvd3MgdXBncmFkZSBwcm9iZSwgYSBub24tSFRNTCBmZXRjaCkgZ2V0cyB0aGUgNDAxIEpTT04uXG4gICAgICAgIGlmIChnYXRlICYmIHR1bm5lbEdhdGUud2FudHNMb2dpblBhZ2UocmVxdWVzdCkpIHtcbiAgICAgICAgICBjb25zdCBodG1sID0gdHVubmVsTG9naW5QYWdlLmxvZ2luUGFnZUh0bWwoe1xuICAgICAgICAgICAgYnJhbmROYW1lLFxuICAgICAgICAgICAgcGFzc2tleU5hbWVQcmVmaXgsXG4gICAgICAgICAgICByZXR1cm5UbzogdHVubmVsR2F0ZS5yZXF1ZXN0UmV0dXJuVG8ocmVxdWVzdCksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmVzcG9uc2Uud3JpdGVIZWFkKDQwMSwgeyBcImNvbnRlbnQtdHlwZVwiOiBcInRleHQvaHRtbDsgY2hhcnNldD11dGYtOFwiIH0pO1xuICAgICAgICAgIHJlc3BvbnNlLmVuZChodG1sKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZW5kSnNvbihyZXNwb25zZSwgNDAxLCB0dW5uZWxHYXRlLnVuYXV0aG9yaXplZEJvZHkocmVxdWVzdCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHByb3h5LndlYihyZXF1ZXN0LCByZXNwb25zZSk7XG4gICAgfSkoKS5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgIGxvZ2dlci5lcnJvcihcInByb3h5IHJlcXVlc3QgZmFpbGVkXCIsIHsgZXJyb3I6IGVycm9yVXRpbHMudG9FcnJvcihlcnJvcikgfSk7XG4gICAgICBpZiAoIXJlc3BvbnNlLmhlYWRlcnNTZW50KSBzZW5kSnNvbihyZXNwb25zZSwgNTAyLCB7IGVycm9yOiBcImJhZCBnYXRld2F5XCIgfSk7XG4gICAgICBlbHNlIHJlc3BvbnNlLmVuZCgpO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIEEgd2Vic29ja2V0IHVwZ3JhZGUgY2Fubm90IGJlIGFuc3dlcmVkIHdpdGggYSA0MDEgYm9keSwgc28gYSBkZW5pZWQgb25lIGlzXG4gIC8vIGRlc3Ryb3llZCAtIHRoZSBjbGllbnQgc2VlcyB0aGUgaGFuZHNoYWtlIGZhaWwsIHdoaWNoIGlzIHdoYXQgYSBicm93c2VyJ3NcbiAgLy8gV2ViU29ja2V0IGVycm9yIGhhbmRsZXIgZXhwZWN0cy5cbiAgY29uc3Qgb25VcGdyYWRlID0gKHJlcXVlc3Q6IEluY29taW5nTWVzc2FnZSwgc29ja2V0OiBTb2NrZXQsIGhlYWQ6IEJ1ZmZlcik6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHVwZ3JhZGVTb2NrZXQgPSBzb2NrZXQgYXMgVXBncmFkZVNvY2tldDtcbiAgICB1cGdyYWRlU29ja2V0LmRlc3Ryb3lTb29uID8/PSAoKSA9PiB1cGdyYWRlU29ja2V0LmVuZCgpO1xuICAgIGNvbnN0IHBhdGggPSAocmVxdWVzdC51cmwgPz8gXCIvXCIpLnNwbGl0KFwiP1wiLCAxKVswXSA/PyBcIi9cIjtcbiAgICBpZiAodHVubmVsR2F0ZS5pc0F1dGhQYXRoKHBhdGgpKSB7XG4gICAgICB1cGdyYWRlU29ja2V0LmRlc3Ryb3koKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdm9pZCBkZWNpZGUocmVxdWVzdClcbiAgICAgIC50aGVuKChhY3Rpb24pID0+IHtcbiAgICAgICAgaWYgKGFjdGlvbiA9PT0gXCJkZW55XCIpIHVwZ3JhZGVTb2NrZXQuZGVzdHJveSgpO1xuICAgICAgICBlbHNlIHByb3h5LndzKHJlcXVlc3QsIHVwZ3JhZGVTb2NrZXQsIGhlYWQpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoKSA9PiB1cGdyYWRlU29ja2V0LmRlc3Ryb3koKSk7XG4gIH07XG5cbiAgLy8gT25lIG5ldC5TZXJ2ZXIgYmluZHMgb25lIGFkZHJlc3MsIHNvIGxpc3RlbiBlYWNoIGhvc3Qgb24gaXRzIG93biBzZXJ2ZXIgdGhhdFxuICAvLyBzaGFyZXMgdGhlIHNhbWUgaGFuZGxlcnMuIEJpbmRpbmcgc3BlY2lmaWMgaW50ZXJmYWNlIElQcyAocmF0aGVyIHRoYW4gdGhlXG4gIC8vIGRlZmF1bHQgMC4wLjAuMCkgaXMgd2hhdCBsZXRzIHRoZSBnYXRlIGZyb250IGFuIG92ZXJsYXkvTEFOIGFkZHJlc3Mgd2hpbGVcbiAgLy8gbG9vcGJhY2sgcmVhY2hlcyB0aGUgdXBzdHJlYW0gdW5nYXRlZC5cbiAgY29uc3QgaG9zdHMgPSBvcHRpb25zLmJpbmRIb3N0cz8ubGVuZ3RoID8gb3B0aW9ucy5iaW5kSG9zdHMgOiBbXCIwLjAuMC4wXCJdO1xuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBob3N0cy5tYXAoXG4gICAgICAoaG9zdCkgPT5cbiAgICAgICAgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICBjb25zdCBzZXJ2ZXIgPSBjcmVhdGVTZXJ2ZXIob25SZXF1ZXN0KTtcbiAgICAgICAgICBzZXJ2ZXIub24oXCJ1cGdyYWRlXCIsIG9uVXBncmFkZSk7XG4gICAgICAgICAgc2VydmVyLmxpc3RlbihvcHRpb25zLnB1YmxpY1BvcnQsIGhvc3QsICgpID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKFwicHJveHkgbGlzdGVuaW5nXCIsIHtcbiAgICAgICAgICAgICAgaG9zdCxcbiAgICAgICAgICAgICAgcHVibGljUG9ydDogb3B0aW9ucy5wdWJsaWNQb3J0LFxuICAgICAgICAgICAgICBhcHBQb3J0OiBvcHRpb25zLmFwcFBvcnQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgKSxcbiAgKTtcbn1cbiJdfQ==
@@ -1 +1 @@
1
- {"root":["../src/bootstrap.ts","../src/bun.ts","../src/cli.ts","../src/root.ts","../src/appkit/cli.ts","../src/appkit/env-export.ts","../src/appkit/index.ts","../src/auth/cli.ts","../src/auth/index.ts","../src/auth/options.ts","../src/genie-code/cli.ts","../src/genie-code/config.ts","../src/genie-code/index.ts","../src/genie-code/install.ts","../src/genie-code/options.ts","../src/genie-code/runner.ts","../src/genie-code/runtime.ts","../src/graphiti/cli.ts","../src/graphiti/index.ts","../src/graphiti/options.ts","../src/lakebase-proxy/cancellation.ts","../src/lakebase-proxy/cli.ts","../src/lakebase-proxy/index.ts","../src/lakebase-proxy/options.ts","../src/lakebase-proxy/protocol.ts","../src/lakebase-proxy/proxy.ts","../src/model-gateway/cli.ts","../src/model-gateway/index.ts","../src/model-gateway/server.ts","../src/tunnel/app.ts","../src/tunnel/cli.ts","../src/tunnel/index.ts","../src/tunnel/options.ts","../src/tunnel/proxy.ts","../index.ts","../bin/dbx-genie.ts","../bin/dbx-graphiti.ts","../bin/dbx-lakebase-proxy.ts","../bin/dbx-model-gateway.ts","../bin/dbx-tools.ts"],"version":"5.9.3"}
1
+ {"root":["../src/bootstrap.ts","../src/bun.ts","../src/cli.ts","../src/root.ts","../src/appkit/cli.ts","../src/appkit/env-export.ts","../src/appkit/index.ts","../src/auth/cli.ts","../src/auth/index.ts","../src/auth/options.ts","../src/brand/cli.ts","../src/brand/export.ts","../src/brand/index.ts","../src/brand/options.ts","../src/brand/run.ts","../src/genie-code/cli.ts","../src/genie-code/config.ts","../src/genie-code/index.ts","../src/genie-code/install.ts","../src/genie-code/options.ts","../src/genie-code/runner.ts","../src/genie-code/runtime.ts","../src/graphiti/cli.ts","../src/graphiti/index.ts","../src/graphiti/options.ts","../src/lakebase-proxy/cancellation.ts","../src/lakebase-proxy/cli.ts","../src/lakebase-proxy/index.ts","../src/lakebase-proxy/options.ts","../src/lakebase-proxy/protocol.ts","../src/lakebase-proxy/proxy.ts","../src/model-gateway/cli.ts","../src/model-gateway/index.ts","../src/model-gateway/server.ts","../src/tunnel/app.ts","../src/tunnel/cli.ts","../src/tunnel/index.ts","../src/tunnel/options.ts","../src/tunnel/proxy.ts","../index.ts","../bin/dbx-genie.ts","../bin/dbx-graphiti.ts","../bin/dbx-lakebase-proxy.ts","../bin/dbx-model-gateway.ts","../bin/dbx-tools.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -34,30 +34,34 @@
34
34
  "dependencies": {
35
35
  "@clack/prompts": "^1.7.0",
36
36
  "@databricks/appkit": "0.81.0",
37
- "@dbx-tools/appkit": "^0.9.131",
38
- "@dbx-tools/appkit-memory": "^0.9.131",
39
- "@dbx-tools/appkit-model-gateway": "^0.9.131",
40
- "@dbx-tools/auth": "^0.9.131",
41
- "@dbx-tools/auth-gate": "^0.9.131",
42
- "@dbx-tools/cli-args": "^0.9.131",
43
- "@dbx-tools/cli-service": "^0.9.131",
44
- "@dbx-tools/core": "^0.9.131",
45
- "@dbx-tools/databricks": "^0.9.131",
46
- "@dbx-tools/email": "^0.9.131",
47
- "@dbx-tools/lakebase": "^0.9.131",
48
- "@dbx-tools/postgres": "^0.9.131",
49
- "@dbx-tools/shared-auth": "^0.9.131",
50
- "@dbx-tools/shared-core": "^0.9.131",
51
- "@dbx-tools/shared-email": "^0.9.131",
52
- "@dbx-tools/shared-genie-code": "^0.9.131",
53
- "@dbx-tools/shared-model-gateway": "^0.9.131",
54
- "@dbx-tools/tunnel": "^0.9.131",
37
+ "@dbx-tools/appkit": "^0.9.136",
38
+ "@dbx-tools/appkit-generator": "^0.9.136",
39
+ "@dbx-tools/appkit-memory": "^0.9.136",
40
+ "@dbx-tools/appkit-model-gateway": "^0.9.136",
41
+ "@dbx-tools/appkit-web-search": "^0.9.136",
42
+ "@dbx-tools/auth": "^0.9.136",
43
+ "@dbx-tools/auth-gate": "^0.9.136",
44
+ "@dbx-tools/cli-args": "^0.9.136",
45
+ "@dbx-tools/cli-service": "^0.9.136",
46
+ "@dbx-tools/core": "^0.9.136",
47
+ "@dbx-tools/databricks": "^0.9.136",
48
+ "@dbx-tools/email": "^0.9.136",
49
+ "@dbx-tools/lakebase": "^0.9.136",
50
+ "@dbx-tools/postgres": "^0.9.136",
51
+ "@dbx-tools/shared-auth": "^0.9.136",
52
+ "@dbx-tools/shared-core": "^0.9.136",
53
+ "@dbx-tools/shared-email": "^0.9.136",
54
+ "@dbx-tools/shared-generator": "^0.9.136",
55
+ "@dbx-tools/shared-genie-code": "^0.9.136",
56
+ "@dbx-tools/shared-model-gateway": "^0.9.136",
57
+ "@dbx-tools/tunnel": "^0.9.136",
55
58
  "commander": "^15.0.0",
56
59
  "concurrently": "^10.0.3",
57
60
  "get-port": "^7.1.0",
58
61
  "http-proxy-3": "^1.23.1",
59
62
  "pg": "^8.22.0",
60
63
  "smol-toml": "1.8.0",
64
+ "yaml": "^2.9.0",
61
65
  "zod": "4.3.6"
62
66
  },
63
67
  "main": "./lib/index.js",
@@ -115,6 +119,22 @@
115
119
  "types": "./lib/src/auth/options.d.ts",
116
120
  "default": "./lib/src/auth/options.js"
117
121
  },
122
+ "./brand": {
123
+ "types": "./lib/src/brand/cli.d.ts",
124
+ "default": "./lib/src/brand/cli.js"
125
+ },
126
+ "./brand/export": {
127
+ "types": "./lib/src/brand/export.d.ts",
128
+ "default": "./lib/src/brand/export.js"
129
+ },
130
+ "./brand/options": {
131
+ "types": "./lib/src/brand/options.d.ts",
132
+ "default": "./lib/src/brand/options.js"
133
+ },
134
+ "./brand/run": {
135
+ "types": "./lib/src/brand/run.d.ts",
136
+ "default": "./lib/src/brand/run.js"
137
+ },
118
138
  "./graphiti": {
119
139
  "types": "./lib/src/graphiti/cli.d.ts",
120
140
  "default": "./lib/src/graphiti/cli.js"
@@ -158,7 +178,7 @@
158
178
  "./package.json": "./package.json"
159
179
  }
160
180
  },
161
- "version": "0.9.131",
181
+ "version": "0.9.136",
162
182
  "types": "./lib/index.d.ts",
163
183
  "dbxToolsConfig": {
164
184
  "tags": [
@@ -207,6 +227,22 @@
207
227
  "types": "./lib/src/auth/options.d.ts",
208
228
  "default": "./lib/src/auth/options.js"
209
229
  },
230
+ "./brand": {
231
+ "types": "./lib/src/brand/cli.d.ts",
232
+ "default": "./lib/src/brand/cli.js"
233
+ },
234
+ "./brand/export": {
235
+ "types": "./lib/src/brand/export.d.ts",
236
+ "default": "./lib/src/brand/export.js"
237
+ },
238
+ "./brand/options": {
239
+ "types": "./lib/src/brand/options.d.ts",
240
+ "default": "./lib/src/brand/options.js"
241
+ },
242
+ "./brand/run": {
243
+ "types": "./lib/src/brand/run.d.ts",
244
+ "default": "./lib/src/brand/run.js"
245
+ },
210
246
  "./graphiti": {
211
247
  "types": "./lib/src/graphiti/cli.d.ts",
212
248
  "default": "./lib/src/graphiti/cli.js"
@@ -0,0 +1,52 @@
1
+ /**
2
+ * `dbx brand` researched brand-package export.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { addArgs, parseArgs } from "@dbx-tools/cli-args";
8
+ import { Command } from "commander";
9
+
10
+ import { BrandExportOptionsSchema } from "./options.ts";
11
+ import { exportBrandFromPrompt } from "./run.ts";
12
+
13
+ /** Replaceable command boundaries used by tests and embedders. */
14
+ export interface BrandCliDependencies {
15
+ readonly exportBrandFromPrompt?: typeof exportBrandFromPrompt;
16
+ readonly writeProgress?: (value: string) => void;
17
+ readonly writeResult?: (value: unknown) => void;
18
+ }
19
+
20
+ /** Build the lazily loaded `dbx brand` command. */
21
+ export function buildProgram(name = "dbx brand", dependencies: BrandCliDependencies = {}): Command {
22
+ const runExport = dependencies.exportBrandFromPrompt ?? exportBrandFromPrompt;
23
+ const writeProgress =
24
+ dependencies.writeProgress ?? ((value: string) => process.stderr.write(`${value}\n`));
25
+ const writeResult =
26
+ dependencies.writeResult ??
27
+ ((value: unknown) => process.stdout.write(`${JSON.stringify(value, null, 2)}\n`));
28
+ const program = addArgs(
29
+ new Command()
30
+ .name(name)
31
+ .description(
32
+ "Research a brand brief and export brand.yaml with web and mobile visual references",
33
+ ),
34
+ BrandExportOptionsSchema,
35
+ );
36
+ program
37
+ .argument("<prompt>", "brand, company, product, or design brief to research")
38
+ .action(async (prompt: string) => {
39
+ const options = parseArgs(program, BrandExportOptionsSchema);
40
+ const result = await runExport(prompt, options, {
41
+ onProgress(event) {
42
+ writeProgress(`[${event.stage}] ${event.message}`);
43
+ },
44
+ });
45
+ writeResult({
46
+ brand: result.brandYamlPath,
47
+ manifest: result.manifestPath,
48
+ references: result.referenceCount,
49
+ });
50
+ });
51
+ return program;
52
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Brand package filesystem export.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { access, mkdir, rename, rm, writeFile } from "node:fs/promises";
8
+ import path from "node:path";
9
+ import type { BrandResearch } from "@dbx-tools/appkit-generator";
10
+ import type { BrandPackage } from "@dbx-tools/shared-generator";
11
+ import { BrandPackageSchema } from "@dbx-tools/shared-generator";
12
+ import { stringify } from "yaml";
13
+
14
+ /** Inputs required to write a generated brand package. */
15
+ export interface WriteBrandPackageOptions {
16
+ readonly outputDirectory: string;
17
+ readonly prompt: string;
18
+ readonly brandPackage: BrandPackage;
19
+ readonly research: BrandResearch;
20
+ readonly force?: boolean;
21
+ }
22
+
23
+ /** Files written for a generated brand package. */
24
+ export interface WrittenBrandPackage {
25
+ readonly outputDirectory: string;
26
+ readonly brandYamlPath: string;
27
+ readonly manifestPath: string;
28
+ readonly referenceCount: number;
29
+ }
30
+
31
+ function imageExtension(contentType?: string): string {
32
+ if (!contentType) return ".img";
33
+ const normalized = contentType.split(";", 1)[0].trim().toLowerCase();
34
+ switch (normalized) {
35
+ case "image/avif":
36
+ return ".avif";
37
+ case "image/gif":
38
+ return ".gif";
39
+ case "image/jpeg":
40
+ return ".jpg";
41
+ case "image/png":
42
+ return ".png";
43
+ case "image/svg+xml":
44
+ return ".svg";
45
+ case "image/webp":
46
+ return ".webp";
47
+ default:
48
+ return ".img";
49
+ }
50
+ }
51
+
52
+ function fileSlug(value: string): string {
53
+ return (
54
+ value
55
+ .normalize("NFKD")
56
+ .replace(/[\u0300-\u036f]/g, "")
57
+ .toLowerCase()
58
+ .replace(/[^a-z0-9]+/g, "-")
59
+ .replace(/^-+|-+$/g, "")
60
+ .slice(0, 60) || "reference"
61
+ );
62
+ }
63
+
64
+ async function writeAtomic(filePath: string, content: string | Uint8Array): Promise<void> {
65
+ await mkdir(path.dirname(filePath), { recursive: true });
66
+ const temporaryPath = `${filePath}.${process.pid}.${crypto.randomUUID()}.tmp`;
67
+ await writeFile(temporaryPath, content);
68
+ await rename(temporaryPath, filePath);
69
+ }
70
+
71
+ async function fileExists(filePath: string): Promise<boolean> {
72
+ try {
73
+ await access(filePath);
74
+ return true;
75
+ } catch {
76
+ return false;
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Write a normal `brand.yaml` plus research provenance and downloaded visual
82
+ * references.
83
+ */
84
+ export async function writeBrandPackage(
85
+ options: WriteBrandPackageOptions,
86
+ ): Promise<WrittenBrandPackage> {
87
+ const outputDirectory = path.resolve(options.outputDirectory);
88
+ const brandYamlPath = path.join(outputDirectory, "brand.yaml");
89
+ const packageExists = await fileExists(brandYamlPath);
90
+ if (packageExists && !options.force) {
91
+ throw new Error(`Brand package already exists at ${brandYamlPath}; pass --force to replace it`);
92
+ }
93
+ if (options.force) {
94
+ await rm(path.join(outputDirectory, "references"), { recursive: true, force: true });
95
+ }
96
+
97
+ const visualReferences = structuredClone(options.brandPackage.visualReferences);
98
+ let referenceCount = 0;
99
+ for (
100
+ let referenceIndex = 0;
101
+ referenceIndex < options.research.visualReferences.length;
102
+ referenceIndex += 1
103
+ ) {
104
+ const researchReference = options.research.visualReferences[referenceIndex];
105
+ const exportedReference = visualReferences[referenceIndex];
106
+ if (!exportedReference) continue;
107
+ for (let imageIndex = 0; imageIndex < researchReference.images.length; imageIndex += 1) {
108
+ const researchImage = researchReference.images[imageIndex];
109
+ const exportedImage = exportedReference.images[imageIndex];
110
+ if (!exportedImage || !researchImage.data) continue;
111
+ const fileName = `${fileSlug(researchReference.appName)}-${imageIndex + 1}${imageExtension(researchImage.contentType)}`;
112
+ const relativePath = path.posix.join("references", researchReference.platform, fileName);
113
+ await writeAtomic(path.join(outputDirectory, relativePath), researchImage.data);
114
+ exportedImage.localPath = `./${relativePath}`;
115
+ referenceCount += 1;
116
+ }
117
+ }
118
+
119
+ const brandPackage = BrandPackageSchema.parse({
120
+ ...options.brandPackage,
121
+ visualReferences,
122
+ });
123
+ const manifestPath = path.join(outputDirectory, "brand-package.json");
124
+ await writeAtomic(brandYamlPath, stringify(brandPackage.brand, { indent: 2 }));
125
+ await writeAtomic(
126
+ manifestPath,
127
+ `${JSON.stringify(
128
+ {
129
+ prompt: options.prompt,
130
+ generatedAt: new Date().toISOString(),
131
+ ...brandPackage,
132
+ },
133
+ null,
134
+ 2,
135
+ )}\n`,
136
+ );
137
+
138
+ return {
139
+ outputDirectory,
140
+ brandYamlPath,
141
+ manifestPath,
142
+ referenceCount,
143
+ };
144
+ }
@@ -0,0 +1,13 @@
1
+ // GENERATED by projen watch - DO NOT EDIT.
2
+ // Regenerated from the exporting modules in ./src.
3
+ // Hand edits are overwritten on the next watch; this file is read-only.
4
+
5
+ export * as cli from "./cli.ts";
6
+ export * as exportModule from "./export.ts";
7
+ export * as options from "./options.ts";
8
+ export * as run from "./run.ts";
9
+ export type { BrandCliDependencies } from "./cli.ts";
10
+ export type { WriteBrandPackageOptions, WrittenBrandPackage } from "./export.ts";
11
+ export { BrandExportOptionsSchema } from "./options.ts";
12
+ export type { BrandExportOptions } from "./options.ts";
13
+ export type { BrandExportCallbacks } from "./run.ts";
@@ -0,0 +1,48 @@
1
+ /**
2
+ * `dbx brand` option contracts.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { DatabricksAuthOptionsSchema } from "@dbx-tools/auth/config";
8
+ import { z } from "zod";
9
+
10
+ /** Options for exporting one researched brand package. */
11
+ export const BrandExportOptionsSchema = z
12
+ .object({
13
+ profile: DatabricksAuthOptionsSchema.shape.profile,
14
+ name: z.string().trim().min(1).optional().describe("Known canonical brand name."),
15
+ website: z.string().url().optional().describe("Known official HTTPS website."),
16
+ output: z
17
+ .string()
18
+ .trim()
19
+ .min(1)
20
+ .default("branding")
21
+ .describe("Output directory for brand.yaml, provenance, and visual references."),
22
+ model: z
23
+ .string()
24
+ .trim()
25
+ .min(1)
26
+ .optional()
27
+ .describe("Optional Databricks model preference for brand synthesis."),
28
+ maxSources: z.coerce
29
+ .number()
30
+ .int()
31
+ .min(1)
32
+ .max(8)
33
+ .default(4)
34
+ .describe("Maximum general web sources to read."),
35
+ sourceMaxLength: z.coerce
36
+ .number()
37
+ .int()
38
+ .min(1_000)
39
+ .max(20_000)
40
+ .default(8_000)
41
+ .describe("Maximum characters retained from each source page."),
42
+ force: z.boolean().default(false).describe("Replace files in an existing output directory."),
43
+ })
44
+ .strict()
45
+ .describe("Options for exporting a researched brand package.");
46
+
47
+ /** Resolved brand export options. */
48
+ export type BrandExportOptions = z.output<typeof BrandExportOptionsSchema>;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Standalone researched brand generation for the consolidated CLI.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import type { BrandResearch } from "@dbx-tools/appkit-generator";
8
+ import { generateBrandPackage } from "@dbx-tools/appkit-generator/generate";
9
+ import {
10
+ runWebAssetPageFetch,
11
+ runWebFetch,
12
+ runWebImageFetch,
13
+ } from "@dbx-tools/appkit-web-search/fetch";
14
+ import { createWebSearchRuntime } from "@dbx-tools/appkit-web-search/runtime";
15
+ import { runWebSearch } from "@dbx-tools/appkit-web-search/search";
16
+ import { createWorkspaceClient } from "@dbx-tools/databricks/workspace-client";
17
+ import type { BrandGenerationProgressEvent } from "@dbx-tools/shared-generator";
18
+
19
+ import { writeBrandPackage, type WrittenBrandPackage } from "./export.ts";
20
+ import type { BrandExportOptions } from "./options.ts";
21
+
22
+ /** Optional observers for one CLI brand generation run. */
23
+ export interface BrandExportCallbacks {
24
+ readonly onProgress?: (event: BrandGenerationProgressEvent) => void | Promise<void>;
25
+ }
26
+
27
+ /**
28
+ * Research a freeform brand brief, synthesize a portable context, and export
29
+ * the package to disk.
30
+ */
31
+ export async function exportBrandFromPrompt(
32
+ prompt: string,
33
+ options: BrandExportOptions,
34
+ callbacks: BrandExportCallbacks = {},
35
+ ): Promise<WrittenBrandPackage> {
36
+ const workspaceClient = await createWorkspaceClient({
37
+ ...(options.profile ? { profile: options.profile } : {}),
38
+ });
39
+ const host = (await workspaceClient.config.getHost()).toString();
40
+ const runtime = createWebSearchRuntime({
41
+ ...(options.model ? { model: options.model } : {}),
42
+ });
43
+ let research: BrandResearch | undefined;
44
+ const brandPackage = await generateBrandPackage(
45
+ {
46
+ prompt,
47
+ ...(options.name ? { name: options.name } : {}),
48
+ ...(options.website ? { website: options.website } : {}),
49
+ },
50
+ {
51
+ client: {
52
+ search: (request, signal) =>
53
+ runWebSearch(
54
+ request,
55
+ runtime,
56
+ {
57
+ client: workspaceClient,
58
+ host,
59
+ ...(options.profile ? { cacheIdentity: `profile:${options.profile}` } : {}),
60
+ },
61
+ signal,
62
+ ),
63
+ fetch: (request, signal) => runWebFetch(request, runtime, signal),
64
+ fetchAssetPage: (request, signal) => runWebAssetPageFetch(request, runtime, signal),
65
+ fetchImage: (request, signal) => runWebImageFetch(request, runtime, signal),
66
+ },
67
+ workspaceClient,
68
+ ...(options.model ? { model: options.model } : {}),
69
+ maxSources: options.maxSources,
70
+ sourceMaxLength: options.sourceMaxLength,
71
+ ...(callbacks.onProgress ? { onProgress: callbacks.onProgress } : {}),
72
+ onResearch(value) {
73
+ research = value;
74
+ },
75
+ },
76
+ );
77
+ if (!research) throw new Error("Brand generation completed without research provenance");
78
+ return writeBrandPackage({
79
+ outputDirectory: options.output,
80
+ prompt,
81
+ brandPackage,
82
+ research,
83
+ force: options.force,
84
+ });
85
+ }
package/src/cli.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * `dev` bootstraps or repairs a workspace and forwards to projen.
5
5
  * `appkit` provides AppKit environment helpers.
6
6
  * `auth` manages Databricks OAuth and access tokens.
7
+ * `brand` researches and exports portable brand packages.
7
8
  * `tunnel` runs a public portr tunnel with passwordless access gating.
8
9
  *
9
10
  * Feature commands load their sibling packages only when selected and forward
@@ -88,7 +89,7 @@ export function buildProgram(name: string = PROGRAM_NAMES[0]): Command {
88
89
  const program = new Command()
89
90
  .name(name)
90
91
  .description(
91
- "Databricks developer tools: workspace lifecycle, AppKit env, auth, tunnels, and local proxies",
92
+ "Databricks developer tools: workspace lifecycle, AppKit env, auth, brand generation, tunnels, and local proxies",
92
93
  )
93
94
  .enablePositionalOptions()
94
95
  .showHelpAfterError()
@@ -97,7 +98,7 @@ export function buildProgram(name: string = PROGRAM_NAMES[0]): Command {
97
98
  program
98
99
  .command("dev")
99
100
  .description("Bootstrap or repair a dbx-tools workspace, then forward to projen")
100
- .argument("[projenArgs...]", "projen task and arguments (e.g. sync --watch)")
101
+ .argument("[projenArgs...]", "Projen task and arguments, for example sync --watch")
101
102
  .allowUnknownOption()
102
103
  .allowExcessArguments()
103
104
  .helpOption(false)
@@ -119,6 +120,13 @@ export function buildProgram(name: string = PROGRAM_NAMES[0]): Command {
119
120
  async () => (await import("./auth/cli.ts")).buildProgram,
120
121
  );
121
122
 
123
+ addForwardedCommand(
124
+ program,
125
+ "brand",
126
+ "Research and export a portable brand package",
127
+ async () => (await import("./brand/cli.ts")).buildProgram,
128
+ );
129
+
122
130
  addForwardedCommand(
123
131
  program,
124
132
  "tunnel",
@@ -163,6 +171,7 @@ export async function buildDocumentationProgram(name: string = PROGRAM_NAMES[0])
163
171
  const children = [
164
172
  (await import("./appkit/cli.ts")).buildProgram("appkit"),
165
173
  (await import("./auth/cli.ts")).buildProgram("auth"),
174
+ (await import("./brand/cli.ts")).buildProgram("brand"),
166
175
  (await import("./tunnel/cli.ts")).buildProgram("tunnel"),
167
176
  (await import("./lakebase-proxy/cli.ts")).buildProgram("lakebase-proxy"),
168
177
  (await import("./model-gateway/cli.ts")).buildProgram("model-gateway"),
@@ -34,7 +34,7 @@ export function buildProgram(
34
34
  .description("Run Genie Code through an authenticated local Databricks model gateway")
35
35
  .argument(
36
36
  "[genieArgs...]",
37
- "arguments and unknown flags forwarded to Genie Code; wrapper options may be separated with --",
37
+ "Arguments and unknown flags forwarded to Genie Code. Separate wrapper options with --",
38
38
  )
39
39
  .allowUnknownOption()
40
40
  .passThroughOptions()
package/src/tunnel/cli.ts CHANGED
@@ -132,6 +132,7 @@ async function run(raw: TunnelOptions, command: readonly string[]): Promise<void
132
132
  forwardHeaders: resolved.gate.forwardHeaders,
133
133
  gatePaths: resolved.gate.gatePaths,
134
134
  brandName: resolved.gate.brandName,
135
+ passkeyNamePrefix: resolved.gate.passkeyNamePrefix,
135
136
  bindHosts: resolved.bindHosts,
136
137
  });
137
138