sonamu 0.8.5 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"dev-vitest-manager.d.ts","sourceRoot":"","sources":["../../src/testing/dev-vitest-manager.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAQF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;IAEjB,KAAK,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B/C,GAAG,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAe3E,SAAS,IAAI,aAAa;IAQpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAYjB,YAAY;YA2BZ,UAAU;IAkCxB,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,iBAAiB;CAe1B"}
1
+ {"version":3,"file":"dev-vitest-manager.d.ts","sourceRoot":"","sources":["../../src/testing/dev-vitest-manager.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAQF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;IAEjB,KAAK,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B/C,GAAG,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAe3E,SAAS,IAAI,aAAa;IAQpB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAoBjB,YAAY;YA2BZ,UAAU;IAkCxB,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,iBAAiB;CAe1B"}
@@ -59,6 +59,13 @@ export class DevVitestManager {
59
59
  return;
60
60
  }
61
61
  this.closed = true;
62
+ // 큐에 남은 작업들을 reject하여 호출자가 영구 대기하지 않도록 정리
63
+ while(this.queue.length > 0){
64
+ const entry = this.queue.shift();
65
+ if (entry) {
66
+ entry.reject(new Error("DevVitestManager is being shut down"));
67
+ }
68
+ }
62
69
  if (this.vitest) {
63
70
  await this.vitest.close();
64
71
  this.vitest = null;
@@ -180,4 +187,4 @@ export class DevVitestManager {
180
187
  }
181
188
  }
182
189
 
183
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0aW5nL2Rldi12aXRlc3QtbWFuYWdlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFVzZXJDb25maWcgYXMgVml0ZVVzZXJDb25maWcgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHR5cGUge1xuICBDbGlPcHRpb25zLFxuICBUZXN0Q2FzZSxcbiAgVGVzdE1vZHVsZSxcbiAgVGVzdFJ1blJlc3VsdCxcbiAgVGVzdFNwZWNpZmljYXRpb24sXG4gIFZpdGVzdCxcbn0gZnJvbSBcInZpdGVzdC9ub2RlXCI7XG5cbmV4cG9ydCB0eXBlIFJ1blJlc3VsdCA9IHtcbiAgb2s6IGJvb2xlYW47XG4gIHN1bW1hcnk6IHtcbiAgICB0b3RhbDogbnVtYmVyO1xuICAgIHBhc3NlZDogbnVtYmVyO1xuICAgIGZhaWxlZDogbnVtYmVyO1xuICAgIHNraXBwZWQ6IG51bWJlcjtcbiAgICBkdXJhdGlvbk1zOiBudW1iZXI7XG4gIH07XG4gIGZhaWxlZDogRmFpbGVkVGVzdFtdO1xufTtcblxuZXhwb3J0IHR5cGUgRmFpbGVkVGVzdCA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICBmaWxlOiBzdHJpbmc7XG4gIGVycm9yOiBzdHJpbmc7XG59O1xuXG5leHBvcnQgdHlwZSBNYW5hZ2VyU3RhdHVzID0ge1xuICByZWFkeTogYm9vbGVhbjtcbiAgcnVubmluZzogYm9vbGVhbjtcbiAgbGFzdFJ1bkF0OiBzdHJpbmcgfCBudWxsO1xufTtcblxudHlwZSBRdWV1ZUVudHJ5ID0ge1xuICB0YXNrOiAoKSA9PiBQcm9taXNlPFJ1blJlc3VsdD47XG4gIHJlc29sdmU6IChyZXN1bHQ6IFJ1blJlc3VsdCkgPT4gdm9pZDtcbiAgcmVqZWN0OiAoZXJyb3I6IHVua25vd24pID0+IHZvaWQ7XG59O1xuXG5leHBvcnQgY2xhc3MgRGV2Vml0ZXN0TWFuYWdlciB7XG4gIHByaXZhdGUgdml0ZXN0OiBWaXRlc3QgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBydW5uaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgbGFzdFJ1bkF0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBxdWV1ZTogUXVldWVFbnRyeVtdID0gW107XG4gIHByaXZhdGUgcHJvY2Vzc2luZyA9IGZhbHNlO1xuICBwcml2YXRlIGNsb3NlZCA9IGZhbHNlO1xuXG4gIGFzeW5jIHN0YXJ0KHZpdGVzdENvbmZpZ1BhdGg/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyDsnbTrr7gg7Iuc7J6R65CcIOqyveyasCDspJHrs7Ug7LSI6riw7ZmU66W8IOuwqeyngFxuICAgIGlmICh0aGlzLnZpdGVzdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgY3JlYXRlVml0ZXN0IH0gPSBhd2FpdCBpbXBvcnQoXCJ2aXRlc3Qvbm9kZVwiKTtcblxuICAgIGNvbnN0IHZpdGVPdmVycmlkZXM6IFZpdGVVc2VyQ29uZmlnID0ge1xuICAgICAgc2VydmVyOiB7IHdhdGNoOiBudWxsIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IGNsaU9wdGlvbnM6IENsaU9wdGlvbnMgPSB7XG4gICAgICB3YXRjaDogdHJ1ZSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgICBmb3JjZVJlcnVuVHJpZ2dlcnM6IFtdLFxuICAgICAgY29uZmlnOiB2aXRlc3RDb25maWdQYXRoLFxuICAgICAgZW52OiB7XG4gICAgICAgIE5PREVfRU5WOiBcInRlc3RcIixcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIHRoaXMudml0ZXN0ID0gYXdhaXQgY3JlYXRlVml0ZXN0KFwidGVzdFwiLCBjbGlPcHRpb25zLCB2aXRlT3ZlcnJpZGVzKTtcbiAgICBhd2FpdCB0aGlzLnZpdGVzdC5pbml0KCk7XG5cbiAgICB0aGlzLnZpdGVzdC5vbkZpbHRlcldhdGNoZWRTcGVjaWZpY2F0aW9uKChfc3BlYykgPT4gZmFsc2UpO1xuICAgIHRoaXMuY2xvc2VkID0gZmFsc2U7XG4gIH1cblxuICBhc3luYyBydW4ob3B0czogeyBmaWxlcz86IHN0cmluZ1tdOyBwYXR0ZXJuPzogc3RyaW5nIH0pOiBQcm9taXNlPFJ1blJlc3VsdD4ge1xuICAgIGlmICh0aGlzLmNsb3NlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGV2Vml0ZXN0TWFuYWdlciBpcyBhbHJlYWR5IHNodXQgZG93blwiKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnZpdGVzdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGV2Vml0ZXN0TWFuYWdlciBpcyBub3Qgc3RhcnRlZFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2U8UnVuUmVzdWx0PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0YXNrID0gKCkgPT4gdGhpcy5leGVjdXRlUnVuKG9wdHMpO1xuICAgICAgdGhpcy5xdWV1ZS5wdXNoKHsgdGFzaywgcmVzb2x2ZSwgcmVqZWN0IH0pO1xuICAgICAgdGhpcy5wcm9jZXNzUXVldWUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFN0YXR1cygpOiBNYW5hZ2VyU3RhdHVzIHtcbiAgICByZXR1cm4ge1xuICAgICAgcmVhZHk6IHRoaXMudml0ZXN0ICE9PSBudWxsICYmICF0aGlzLmNsb3NlZCxcbiAgICAgIHJ1bm5pbmc6IHRoaXMucnVubmluZyxcbiAgICAgIGxhc3RSdW5BdDogdGhpcy5sYXN0UnVuQXQsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIHNodXRkb3duKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmNsb3NlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNsb3NlZCA9IHRydWU7XG5cbiAgICBpZiAodGhpcy52aXRlc3QpIHtcbiAgICAgIGF3YWl0IHRoaXMudml0ZXN0LmNsb3NlKCk7XG4gICAgICB0aGlzLnZpdGVzdCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzUXVldWUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMucHJvY2Vzc2luZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnByb2Nlc3NpbmcgPSB0cnVlO1xuXG4gICAgdHJ5IHtcbiAgICAgIHdoaWxlICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgZW50cnkgPSB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgIGlmICghZW50cnkpIGJyZWFrO1xuICAgICAgICBpZiAodGhpcy5jbG9zZWQpIHtcbiAgICAgICAgICBlbnRyeS5yZWplY3QobmV3IEVycm9yKFwiRGV2Vml0ZXN0TWFuYWdlciBpcyBhbHJlYWR5IHNodXQgZG93blwiKSk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVudHJ5LnRhc2soKTtcbiAgICAgICAgICBlbnRyeS5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGVudHJ5LnJlamVjdChlcnIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMucHJvY2Vzc2luZyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZXhlY3V0ZVJ1bihvcHRzOiB7IGZpbGVzPzogc3RyaW5nW107IHBhdHRlcm4/OiBzdHJpbmcgfSk6IFByb21pc2U8UnVuUmVzdWx0PiB7XG4gICAgY29uc3Qgdml0ZXN0ID0gdGhpcy52aXRlc3Q7XG4gICAgaWYgKCF2aXRlc3QpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkRldlZpdGVzdE1hbmFnZXIgaXMgbm90IHN0YXJ0ZWRcIik7XG4gICAgfVxuXG4gICAgdGhpcy5ydW5uaW5nID0gdHJ1ZTtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgaWYgKG9wdHMucGF0dGVybikge1xuICAgICAgdml0ZXN0LnNldEdsb2JhbFRlc3ROYW1lUGF0dGVybihvcHRzLnBhdHRlcm4pO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBzcGVjczogVGVzdFNwZWNpZmljYXRpb25bXSA9IG9wdHMuZmlsZXNcbiAgICAgICAgPyBhd2FpdCB2aXRlc3QuZ2xvYlRlc3RTcGVjaWZpY2F0aW9ucyhvcHRzLmZpbGVzKVxuICAgICAgICA6IGF3YWl0IHZpdGVzdC5nbG9iVGVzdFNwZWNpZmljYXRpb25zKCk7XG5cbiAgICAgIGNvbnN0IGFsbFRlc3RzUnVuID0gIW9wdHMuZmlsZXMgfHwgb3B0cy5maWxlcy5sZW5ndGggPT09IDA7XG4gICAgICBjb25zdCBydW5SZXN1bHQ6IFRlc3RSdW5SZXN1bHQgPSBhd2FpdCB2aXRlc3QucnVuVGVzdFNwZWNpZmljYXRpb25zKHNwZWNzLCBhbGxUZXN0c1J1bik7XG5cbiAgICAgIGNvbnN0IGR1cmF0aW9uTXMgPSBEYXRlLm5vdygpIC0gc3RhcnRUaW1lO1xuICAgICAgdGhpcy5sYXN0UnVuQXQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG5cbiAgICAgIGNvbnN0IHNwZWNNb2R1bGVJZHMgPSBuZXcgU2V0KHNwZWNzLm1hcCgocykgPT4gcy5tb2R1bGVJZCkpO1xuICAgICAgcmV0dXJuIHRoaXMuY29sbGVjdFJlc3VsdHMocnVuUmVzdWx0LCBkdXJhdGlvbk1zLCBzcGVjTW9kdWxlSWRzKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKG9wdHMucGF0dGVybikge1xuICAgICAgICB2aXRlc3QucmVzZXRHbG9iYWxUZXN0TmFtZVBhdHRlcm4oKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucnVubmluZyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29sbGVjdFJlc3VsdHMoXG4gICAgcnVuUmVzdWx0OiBUZXN0UnVuUmVzdWx0LFxuICAgIGR1cmF0aW9uTXM6IG51bWJlcixcbiAgICBzcGVjTW9kdWxlSWRzOiBTZXQ8c3RyaW5nPixcbiAgKTogUnVuUmVzdWx0IHtcbiAgICBsZXQgdG90YWwgPSAwO1xuICAgIGxldCBwYXNzZWQgPSAwO1xuICAgIGxldCBmYWlsZWQgPSAwO1xuICAgIGxldCBza2lwcGVkID0gMDtcbiAgICBjb25zdCBmYWlsZWRUZXN0czogRmFpbGVkVGVzdFtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHRlc3RNb2R1bGUgb2YgcnVuUmVzdWx0LnRlc3RNb2R1bGVzKSB7XG4gICAgICBpZiAoIXNwZWNNb2R1bGVJZHMuaGFzKHRlc3RNb2R1bGUubW9kdWxlSWQpKSBjb250aW51ZTtcbiAgICAgIHRoaXMuY29sbGVjdEZyb21Nb2R1bGUodGVzdE1vZHVsZSwgZmFpbGVkVGVzdHMsIChjb3VudHMpID0+IHtcbiAgICAgICAgdG90YWwgKz0gY291bnRzLnRvdGFsO1xuICAgICAgICBwYXNzZWQgKz0gY291bnRzLnBhc3NlZDtcbiAgICAgICAgZmFpbGVkICs9IGNvdW50cy5mYWlsZWQ7XG4gICAgICAgIHNraXBwZWQgKz0gY291bnRzLnNraXBwZWQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgb2s6IGZhaWxlZCA9PT0gMCxcbiAgICAgIHN1bW1hcnk6IHsgdG90YWwsIHBhc3NlZCwgZmFpbGVkLCBza2lwcGVkLCBkdXJhdGlvbk1zIH0sXG4gICAgICBmYWlsZWQ6IGZhaWxlZFRlc3RzLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGNvbGxlY3RGcm9tTW9kdWxlKFxuICAgIHRlc3RNb2R1bGU6IFRlc3RNb2R1bGUsXG4gICAgZmFpbGVkVGVzdHM6IEZhaWxlZFRlc3RbXSxcbiAgICBhZGRDb3VudHM6IChjb3VudHM6IHsgdG90YWw6IG51bWJlcjsgcGFzc2VkOiBudW1iZXI7IGZhaWxlZDogbnVtYmVyOyBza2lwcGVkOiBudW1iZXIgfSkgPT4gdm9pZCxcbiAgKTogdm9pZCB7XG4gICAgbGV0IHRvdGFsID0gMDtcbiAgICBsZXQgcGFzc2VkID0gMDtcbiAgICBsZXQgZmFpbGVkID0gMDtcbiAgICBsZXQgc2tpcHBlZCA9IDA7XG5cbiAgICBmb3IgKGNvbnN0IHRlc3RDYXNlIG9mIHRlc3RNb2R1bGUuY2hpbGRyZW4uYWxsVGVzdHMoKSkge1xuICAgICAgdG90YWwrKztcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHRlc3RDYXNlLnJlc3VsdCgpO1xuXG4gICAgICBpZiAocmVzdWx0LnN0YXRlID09PSBcInBhc3NlZFwiKSB7XG4gICAgICAgIHBhc3NlZCsrO1xuICAgICAgfSBlbHNlIGlmIChyZXN1bHQuc3RhdGUgPT09IFwiZmFpbGVkXCIpIHtcbiAgICAgICAgZmFpbGVkKys7XG4gICAgICAgIGZhaWxlZFRlc3RzLnB1c2godGhpcy5leHRyYWN0RmFpbGVkVGVzdCh0ZXN0Q2FzZSwgdGVzdE1vZHVsZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gcGVuZGluZy9za2lwcGVkIOyDge2DnOuKlCBza2lwcGVk66GcIOynkeqzhFxuICAgICAgICBza2lwcGVkKys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYWRkQ291bnRzKHsgdG90YWwsIHBhc3NlZCwgZmFpbGVkLCBza2lwcGVkIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0RmFpbGVkVGVzdCh0ZXN0Q2FzZTogVGVzdENhc2UsIHRlc3RNb2R1bGU6IFRlc3RNb2R1bGUpOiBGYWlsZWRUZXN0IHtcbiAgICBjb25zdCByZXN1bHQgPSB0ZXN0Q2FzZS5yZXN1bHQoKTtcbiAgICBsZXQgZXJyb3JNZXNzYWdlID0gXCJVbmtub3duIGVycm9yXCI7XG5cbiAgICBpZiAocmVzdWx0LnN0YXRlID09PSBcImZhaWxlZFwiICYmIHJlc3VsdC5lcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgZmlyc3RFcnJvciA9IHJlc3VsdC5lcnJvcnNbMF07XG4gICAgICBlcnJvck1lc3NhZ2UgPSBmaXJzdEVycm9yLm1lc3NhZ2UgPz8gU3RyaW5nKGZpcnN0RXJyb3IpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiB0ZXN0Q2FzZS5mdWxsTmFtZSxcbiAgICAgIGZpbGU6IHRlc3RNb2R1bGUubW9kdWxlSWQsXG4gICAgICBlcnJvcjogZXJyb3JNZXNzYWdlLFxuICAgIH07XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJEZXZWaXRlc3RNYW5hZ2VyIiwidml0ZXN0IiwicnVubmluZyIsImxhc3RSdW5BdCIsInF1ZXVlIiwicHJvY2Vzc2luZyIsImNsb3NlZCIsInN0YXJ0Iiwidml0ZXN0Q29uZmlnUGF0aCIsImNyZWF0ZVZpdGVzdCIsInZpdGVPdmVycmlkZXMiLCJzZXJ2ZXIiLCJ3YXRjaCIsImNsaU9wdGlvbnMiLCJzdGFuZGFsb25lIiwiZm9yY2VSZXJ1blRyaWdnZXJzIiwiY29uZmlnIiwiZW52IiwiTk9ERV9FTlYiLCJpbml0Iiwib25GaWx0ZXJXYXRjaGVkU3BlY2lmaWNhdGlvbiIsIl9zcGVjIiwicnVuIiwib3B0cyIsIkVycm9yIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJ0YXNrIiwiZXhlY3V0ZVJ1biIsInB1c2giLCJwcm9jZXNzUXVldWUiLCJnZXRTdGF0dXMiLCJyZWFkeSIsInNodXRkb3duIiwiY2xvc2UiLCJsZW5ndGgiLCJlbnRyeSIsInNoaWZ0IiwicmVzdWx0IiwiZXJyIiwic3RhcnRUaW1lIiwiRGF0ZSIsIm5vdyIsInBhdHRlcm4iLCJzZXRHbG9iYWxUZXN0TmFtZVBhdHRlcm4iLCJzcGVjcyIsImZpbGVzIiwiZ2xvYlRlc3RTcGVjaWZpY2F0aW9ucyIsImFsbFRlc3RzUnVuIiwicnVuUmVzdWx0IiwicnVuVGVzdFNwZWNpZmljYXRpb25zIiwiZHVyYXRpb25NcyIsInRvSVNPU3RyaW5nIiwic3BlY01vZHVsZUlkcyIsIlNldCIsIm1hcCIsInMiLCJtb2R1bGVJZCIsImNvbGxlY3RSZXN1bHRzIiwicmVzZXRHbG9iYWxUZXN0TmFtZVBhdHRlcm4iLCJ0b3RhbCIsInBhc3NlZCIsImZhaWxlZCIsInNraXBwZWQiLCJmYWlsZWRUZXN0cyIsInRlc3RNb2R1bGUiLCJ0ZXN0TW9kdWxlcyIsImhhcyIsImNvbGxlY3RGcm9tTW9kdWxlIiwiY291bnRzIiwib2siLCJzdW1tYXJ5IiwiYWRkQ291bnRzIiwidGVzdENhc2UiLCJjaGlsZHJlbiIsImFsbFRlc3RzIiwic3RhdGUiLCJleHRyYWN0RmFpbGVkVGVzdCIsImVycm9yTWVzc2FnZSIsImVycm9ycyIsImZpcnN0RXJyb3IiLCJtZXNzYWdlIiwiU3RyaW5nIiwibmFtZSIsImZ1bGxOYW1lIiwiZmlsZSIsImVycm9yIl0sIm1hcHBpbmdzIjoiQUF3Q0EsT0FBTyxNQUFNQTtJQUNIQyxTQUF3QixLQUFLO0lBQzdCQyxVQUFVLE1BQU07SUFDaEJDLFlBQTJCLEtBQUs7SUFDaENDLFFBQXNCLEVBQUUsQ0FBQztJQUN6QkMsYUFBYSxNQUFNO0lBQ25CQyxTQUFTLE1BQU07SUFFdkIsTUFBTUMsTUFBTUMsZ0JBQXlCLEVBQWlCO1FBQ3BELHVCQUF1QjtRQUN2QixJQUFJLElBQUksQ0FBQ1AsTUFBTSxFQUFFO1lBQ2Y7UUFDRjtRQUVBLE1BQU0sRUFBRVEsWUFBWSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUM7UUFFdEMsTUFBTUMsZ0JBQWdDO1lBQ3BDQyxRQUFRO2dCQUFFQyxPQUFPO1lBQUs7UUFDeEI7UUFFQSxNQUFNQyxhQUF5QjtZQUM3QkQsT0FBTztZQUNQRSxZQUFZO1lBQ1pDLG9CQUFvQixFQUFFO1lBQ3RCQyxRQUFRUjtZQUNSUyxLQUFLO2dCQUNIQyxVQUFVO1lBQ1o7UUFDRjtRQUVBLElBQUksQ0FBQ2pCLE1BQU0sR0FBRyxNQUFNUSxhQUFhLFFBQVFJLFlBQVlIO1FBQ3JELE1BQU0sSUFBSSxDQUFDVCxNQUFNLENBQUNrQixJQUFJO1FBRXRCLElBQUksQ0FBQ2xCLE1BQU0sQ0FBQ21CLDRCQUE0QixDQUFDLENBQUNDLFFBQVU7UUFDcEQsSUFBSSxDQUFDZixNQUFNLEdBQUc7SUFDaEI7SUFFQSxNQUFNZ0IsSUFBSUMsSUFBNEMsRUFBc0I7UUFDMUUsSUFBSSxJQUFJLENBQUNqQixNQUFNLEVBQUU7WUFDZixNQUFNLElBQUlrQixNQUFNO1FBQ2xC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
190
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0aW5nL2Rldi12aXRlc3QtbWFuYWdlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFVzZXJDb25maWcgYXMgVml0ZVVzZXJDb25maWcgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHR5cGUge1xuICBDbGlPcHRpb25zLFxuICBUZXN0Q2FzZSxcbiAgVGVzdE1vZHVsZSxcbiAgVGVzdFJ1blJlc3VsdCxcbiAgVGVzdFNwZWNpZmljYXRpb24sXG4gIFZpdGVzdCxcbn0gZnJvbSBcInZpdGVzdC9ub2RlXCI7XG5cbmV4cG9ydCB0eXBlIFJ1blJlc3VsdCA9IHtcbiAgb2s6IGJvb2xlYW47XG4gIHN1bW1hcnk6IHtcbiAgICB0b3RhbDogbnVtYmVyO1xuICAgIHBhc3NlZDogbnVtYmVyO1xuICAgIGZhaWxlZDogbnVtYmVyO1xuICAgIHNraXBwZWQ6IG51bWJlcjtcbiAgICBkdXJhdGlvbk1zOiBudW1iZXI7XG4gIH07XG4gIGZhaWxlZDogRmFpbGVkVGVzdFtdO1xufTtcblxuZXhwb3J0IHR5cGUgRmFpbGVkVGVzdCA9IHtcbiAgbmFtZTogc3RyaW5nO1xuICBmaWxlOiBzdHJpbmc7XG4gIGVycm9yOiBzdHJpbmc7XG59O1xuXG5leHBvcnQgdHlwZSBNYW5hZ2VyU3RhdHVzID0ge1xuICByZWFkeTogYm9vbGVhbjtcbiAgcnVubmluZzogYm9vbGVhbjtcbiAgbGFzdFJ1bkF0OiBzdHJpbmcgfCBudWxsO1xufTtcblxudHlwZSBRdWV1ZUVudHJ5ID0ge1xuICB0YXNrOiAoKSA9PiBQcm9taXNlPFJ1blJlc3VsdD47XG4gIHJlc29sdmU6IChyZXN1bHQ6IFJ1blJlc3VsdCkgPT4gdm9pZDtcbiAgcmVqZWN0OiAoZXJyb3I6IHVua25vd24pID0+IHZvaWQ7XG59O1xuXG5leHBvcnQgY2xhc3MgRGV2Vml0ZXN0TWFuYWdlciB7XG4gIHByaXZhdGUgdml0ZXN0OiBWaXRlc3QgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBydW5uaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgbGFzdFJ1bkF0OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBxdWV1ZTogUXVldWVFbnRyeVtdID0gW107XG4gIHByaXZhdGUgcHJvY2Vzc2luZyA9IGZhbHNlO1xuICBwcml2YXRlIGNsb3NlZCA9IGZhbHNlO1xuXG4gIGFzeW5jIHN0YXJ0KHZpdGVzdENvbmZpZ1BhdGg/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyDsnbTrr7gg7Iuc7J6R65CcIOqyveyasCDspJHrs7Ug7LSI6riw7ZmU66W8IOuwqeyngFxuICAgIGlmICh0aGlzLnZpdGVzdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgY3JlYXRlVml0ZXN0IH0gPSBhd2FpdCBpbXBvcnQoXCJ2aXRlc3Qvbm9kZVwiKTtcblxuICAgIGNvbnN0IHZpdGVPdmVycmlkZXM6IFZpdGVVc2VyQ29uZmlnID0ge1xuICAgICAgc2VydmVyOiB7IHdhdGNoOiBudWxsIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IGNsaU9wdGlvbnM6IENsaU9wdGlvbnMgPSB7XG4gICAgICB3YXRjaDogdHJ1ZSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgICBmb3JjZVJlcnVuVHJpZ2dlcnM6IFtdLFxuICAgICAgY29uZmlnOiB2aXRlc3RDb25maWdQYXRoLFxuICAgICAgZW52OiB7XG4gICAgICAgIE5PREVfRU5WOiBcInRlc3RcIixcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIHRoaXMudml0ZXN0ID0gYXdhaXQgY3JlYXRlVml0ZXN0KFwidGVzdFwiLCBjbGlPcHRpb25zLCB2aXRlT3ZlcnJpZGVzKTtcbiAgICBhd2FpdCB0aGlzLnZpdGVzdC5pbml0KCk7XG5cbiAgICB0aGlzLnZpdGVzdC5vbkZpbHRlcldhdGNoZWRTcGVjaWZpY2F0aW9uKChfc3BlYykgPT4gZmFsc2UpO1xuICAgIHRoaXMuY2xvc2VkID0gZmFsc2U7XG4gIH1cblxuICBhc3luYyBydW4ob3B0czogeyBmaWxlcz86IHN0cmluZ1tdOyBwYXR0ZXJuPzogc3RyaW5nIH0pOiBQcm9taXNlPFJ1blJlc3VsdD4ge1xuICAgIGlmICh0aGlzLmNsb3NlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGV2Vml0ZXN0TWFuYWdlciBpcyBhbHJlYWR5IHNodXQgZG93blwiKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnZpdGVzdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRGV2Vml0ZXN0TWFuYWdlciBpcyBub3Qgc3RhcnRlZFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2U8UnVuUmVzdWx0PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCB0YXNrID0gKCkgPT4gdGhpcy5leGVjdXRlUnVuKG9wdHMpO1xuICAgICAgdGhpcy5xdWV1ZS5wdXNoKHsgdGFzaywgcmVzb2x2ZSwgcmVqZWN0IH0pO1xuICAgICAgdGhpcy5wcm9jZXNzUXVldWUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFN0YXR1cygpOiBNYW5hZ2VyU3RhdHVzIHtcbiAgICByZXR1cm4ge1xuICAgICAgcmVhZHk6IHRoaXMudml0ZXN0ICE9PSBudWxsICYmICF0aGlzLmNsb3NlZCxcbiAgICAgIHJ1bm5pbmc6IHRoaXMucnVubmluZyxcbiAgICAgIGxhc3RSdW5BdDogdGhpcy5sYXN0UnVuQXQsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIHNodXRkb3duKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmNsb3NlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNsb3NlZCA9IHRydWU7XG5cbiAgICAvLyDtgZDsl5Ag64Ko7J2AIOyekeyXheuTpOydhCByZWplY3TtlZjsl6wg7Zi47Lac7J6Q6rCAIOyYgeq1rCDrjIDquLDtlZjsp4Ag7JWK64+E66GdIOygleumrFxuICAgIHdoaWxlICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5xdWV1ZS5zaGlmdCgpO1xuICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgIGVudHJ5LnJlamVjdChuZXcgRXJyb3IoXCJEZXZWaXRlc3RNYW5hZ2VyIGlzIGJlaW5nIHNodXQgZG93blwiKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudml0ZXN0KSB7XG4gICAgICBhd2FpdCB0aGlzLnZpdGVzdC5jbG9zZSgpO1xuICAgICAgdGhpcy52aXRlc3QgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcHJvY2Vzc1F1ZXVlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnByb2Nlc3NpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5wcm9jZXNzaW5nID0gdHJ1ZTtcblxuICAgIHRyeSB7XG4gICAgICB3aGlsZSAodGhpcy5xdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5xdWV1ZS5zaGlmdCgpO1xuICAgICAgICBpZiAoIWVudHJ5KSBicmVhaztcbiAgICAgICAgaWYgKHRoaXMuY2xvc2VkKSB7XG4gICAgICAgICAgZW50cnkucmVqZWN0KG5ldyBFcnJvcihcIkRldlZpdGVzdE1hbmFnZXIgaXMgYWxyZWFkeSBzaHV0IGRvd25cIikpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlbnRyeS50YXNrKCk7XG4gICAgICAgICAgZW50cnkucmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBlbnRyeS5yZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnByb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVSdW4ob3B0czogeyBmaWxlcz86IHN0cmluZ1tdOyBwYXR0ZXJuPzogc3RyaW5nIH0pOiBQcm9taXNlPFJ1blJlc3VsdD4ge1xuICAgIGNvbnN0IHZpdGVzdCA9IHRoaXMudml0ZXN0O1xuICAgIGlmICghdml0ZXN0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZXZWaXRlc3RNYW5hZ2VyIGlzIG5vdCBzdGFydGVkXCIpO1xuICAgIH1cblxuICAgIHRoaXMucnVubmluZyA9IHRydWU7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgIGlmIChvcHRzLnBhdHRlcm4pIHtcbiAgICAgIHZpdGVzdC5zZXRHbG9iYWxUZXN0TmFtZVBhdHRlcm4ob3B0cy5wYXR0ZXJuKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3BlY3M6IFRlc3RTcGVjaWZpY2F0aW9uW10gPSBvcHRzLmZpbGVzXG4gICAgICAgID8gYXdhaXQgdml0ZXN0Lmdsb2JUZXN0U3BlY2lmaWNhdGlvbnMob3B0cy5maWxlcylcbiAgICAgICAgOiBhd2FpdCB2aXRlc3QuZ2xvYlRlc3RTcGVjaWZpY2F0aW9ucygpO1xuXG4gICAgICBjb25zdCBhbGxUZXN0c1J1biA9ICFvcHRzLmZpbGVzIHx8IG9wdHMuZmlsZXMubGVuZ3RoID09PSAwO1xuICAgICAgY29uc3QgcnVuUmVzdWx0OiBUZXN0UnVuUmVzdWx0ID0gYXdhaXQgdml0ZXN0LnJ1blRlc3RTcGVjaWZpY2F0aW9ucyhzcGVjcywgYWxsVGVzdHNSdW4pO1xuXG4gICAgICBjb25zdCBkdXJhdGlvbk1zID0gRGF0ZS5ub3coKSAtIHN0YXJ0VGltZTtcbiAgICAgIHRoaXMubGFzdFJ1bkF0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuXG4gICAgICBjb25zdCBzcGVjTW9kdWxlSWRzID0gbmV3IFNldChzcGVjcy5tYXAoKHMpID0+IHMubW9kdWxlSWQpKTtcbiAgICAgIHJldHVybiB0aGlzLmNvbGxlY3RSZXN1bHRzKHJ1blJlc3VsdCwgZHVyYXRpb25Ncywgc3BlY01vZHVsZUlkcyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmIChvcHRzLnBhdHRlcm4pIHtcbiAgICAgICAgdml0ZXN0LnJlc2V0R2xvYmFsVGVzdE5hbWVQYXR0ZXJuKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbGxlY3RSZXN1bHRzKFxuICAgIHJ1blJlc3VsdDogVGVzdFJ1blJlc3VsdCxcbiAgICBkdXJhdGlvbk1zOiBudW1iZXIsXG4gICAgc3BlY01vZHVsZUlkczogU2V0PHN0cmluZz4sXG4gICk6IFJ1blJlc3VsdCB7XG4gICAgbGV0IHRvdGFsID0gMDtcbiAgICBsZXQgcGFzc2VkID0gMDtcbiAgICBsZXQgZmFpbGVkID0gMDtcbiAgICBsZXQgc2tpcHBlZCA9IDA7XG4gICAgY29uc3QgZmFpbGVkVGVzdHM6IEZhaWxlZFRlc3RbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCB0ZXN0TW9kdWxlIG9mIHJ1blJlc3VsdC50ZXN0TW9kdWxlcykge1xuICAgICAgaWYgKCFzcGVjTW9kdWxlSWRzLmhhcyh0ZXN0TW9kdWxlLm1vZHVsZUlkKSkgY29udGludWU7XG4gICAgICB0aGlzLmNvbGxlY3RGcm9tTW9kdWxlKHRlc3RNb2R1bGUsIGZhaWxlZFRlc3RzLCAoY291bnRzKSA9PiB7XG4gICAgICAgIHRvdGFsICs9IGNvdW50cy50b3RhbDtcbiAgICAgICAgcGFzc2VkICs9IGNvdW50cy5wYXNzZWQ7XG4gICAgICAgIGZhaWxlZCArPSBjb3VudHMuZmFpbGVkO1xuICAgICAgICBza2lwcGVkICs9IGNvdW50cy5za2lwcGVkO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9rOiBmYWlsZWQgPT09IDAsXG4gICAgICBzdW1tYXJ5OiB7IHRvdGFsLCBwYXNzZWQsIGZhaWxlZCwgc2tpcHBlZCwgZHVyYXRpb25NcyB9LFxuICAgICAgZmFpbGVkOiBmYWlsZWRUZXN0cyxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjb2xsZWN0RnJvbU1vZHVsZShcbiAgICB0ZXN0TW9kdWxlOiBUZXN0TW9kdWxlLFxuICAgIGZhaWxlZFRlc3RzOiBGYWlsZWRUZXN0W10sXG4gICAgYWRkQ291bnRzOiAoY291bnRzOiB7IHRvdGFsOiBudW1iZXI7IHBhc3NlZDogbnVtYmVyOyBmYWlsZWQ6IG51bWJlcjsgc2tpcHBlZDogbnVtYmVyIH0pID0+IHZvaWQsXG4gICk6IHZvaWQge1xuICAgIGxldCB0b3RhbCA9IDA7XG4gICAgbGV0IHBhc3NlZCA9IDA7XG4gICAgbGV0IGZhaWxlZCA9IDA7XG4gICAgbGV0IHNraXBwZWQgPSAwO1xuXG4gICAgZm9yIChjb25zdCB0ZXN0Q2FzZSBvZiB0ZXN0TW9kdWxlLmNoaWxkcmVuLmFsbFRlc3RzKCkpIHtcbiAgICAgIHRvdGFsKys7XG4gICAgICBjb25zdCByZXN1bHQgPSB0ZXN0Q2FzZS5yZXN1bHQoKTtcblxuICAgICAgaWYgKHJlc3VsdC5zdGF0ZSA9PT0gXCJwYXNzZWRcIikge1xuICAgICAgICBwYXNzZWQrKztcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0LnN0YXRlID09PSBcImZhaWxlZFwiKSB7XG4gICAgICAgIGZhaWxlZCsrO1xuICAgICAgICBmYWlsZWRUZXN0cy5wdXNoKHRoaXMuZXh0cmFjdEZhaWxlZFRlc3QodGVzdENhc2UsIHRlc3RNb2R1bGUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHBlbmRpbmcvc2tpcHBlZCDsg4Htg5zripQgc2tpcHBlZOuhnCDsp5Hqs4RcbiAgICAgICAgc2tpcHBlZCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGFkZENvdW50cyh7IHRvdGFsLCBwYXNzZWQsIGZhaWxlZCwgc2tpcHBlZCB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZXh0cmFjdEZhaWxlZFRlc3QodGVzdENhc2U6IFRlc3RDYXNlLCB0ZXN0TW9kdWxlOiBUZXN0TW9kdWxlKTogRmFpbGVkVGVzdCB7XG4gICAgY29uc3QgcmVzdWx0ID0gdGVzdENhc2UucmVzdWx0KCk7XG4gICAgbGV0IGVycm9yTWVzc2FnZSA9IFwiVW5rbm93biBlcnJvclwiO1xuXG4gICAgaWYgKHJlc3VsdC5zdGF0ZSA9PT0gXCJmYWlsZWRcIiAmJiByZXN1bHQuZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGZpcnN0RXJyb3IgPSByZXN1bHQuZXJyb3JzWzBdO1xuICAgICAgZXJyb3JNZXNzYWdlID0gZmlyc3RFcnJvci5tZXNzYWdlID8/IFN0cmluZyhmaXJzdEVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogdGVzdENhc2UuZnVsbE5hbWUsXG4gICAgICBmaWxlOiB0ZXN0TW9kdWxlLm1vZHVsZUlkLFxuICAgICAgZXJyb3I6IGVycm9yTWVzc2FnZSxcbiAgICB9O1xuICB9XG59XG4iXSwibmFtZXMiOlsiRGV2Vml0ZXN0TWFuYWdlciIsInZpdGVzdCIsInJ1bm5pbmciLCJsYXN0UnVuQXQiLCJxdWV1ZSIsInByb2Nlc3NpbmciLCJjbG9zZWQiLCJzdGFydCIsInZpdGVzdENvbmZpZ1BhdGgiLCJjcmVhdGVWaXRlc3QiLCJ2aXRlT3ZlcnJpZGVzIiwic2VydmVyIiwid2F0Y2giLCJjbGlPcHRpb25zIiwic3RhbmRhbG9uZSIsImZvcmNlUmVydW5UcmlnZ2VycyIsImNvbmZpZyIsImVudiIsIk5PREVfRU5WIiwiaW5pdCIsIm9uRmlsdGVyV2F0Y2hlZFNwZWNpZmljYXRpb24iLCJfc3BlYyIsInJ1biIsIm9wdHMiLCJFcnJvciIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwidGFzayIsImV4ZWN1dGVSdW4iLCJwdXNoIiwicHJvY2Vzc1F1ZXVlIiwiZ2V0U3RhdHVzIiwicmVhZHkiLCJzaHV0ZG93biIsImxlbmd0aCIsImVudHJ5Iiwic2hpZnQiLCJjbG9zZSIsInJlc3VsdCIsImVyciIsInN0YXJ0VGltZSIsIkRhdGUiLCJub3ciLCJwYXR0ZXJuIiwic2V0R2xvYmFsVGVzdE5hbWVQYXR0ZXJuIiwic3BlY3MiLCJmaWxlcyIsImdsb2JUZXN0U3BlY2lmaWNhdGlvbnMiLCJhbGxUZXN0c1J1biIsInJ1blJlc3VsdCIsInJ1blRlc3RTcGVjaWZpY2F0aW9ucyIsImR1cmF0aW9uTXMiLCJ0b0lTT1N0cmluZyIsInNwZWNNb2R1bGVJZHMiLCJTZXQiLCJtYXAiLCJzIiwibW9kdWxlSWQiLCJjb2xsZWN0UmVzdWx0cyIsInJlc2V0R2xvYmFsVGVzdE5hbWVQYXR0ZXJuIiwidG90YWwiLCJwYXNzZWQiLCJmYWlsZWQiLCJza2lwcGVkIiwiZmFpbGVkVGVzdHMiLCJ0ZXN0TW9kdWxlIiwidGVzdE1vZHVsZXMiLCJoYXMiLCJjb2xsZWN0RnJvbU1vZHVsZSIsImNvdW50cyIsIm9rIiwic3VtbWFyeSIsImFkZENvdW50cyIsInRlc3RDYXNlIiwiY2hpbGRyZW4iLCJhbGxUZXN0cyIsInN0YXRlIiwiZXh0cmFjdEZhaWxlZFRlc3QiLCJlcnJvck1lc3NhZ2UiLCJlcnJvcnMiLCJmaXJzdEVycm9yIiwibWVzc2FnZSIsIlN0cmluZyIsIm5hbWUiLCJmdWxsTmFtZSIsImZpbGUiLCJlcnJvciJdLCJtYXBwaW5ncyI6IkFBd0NBLE9BQU8sTUFBTUE7SUFDSEMsU0FBd0IsS0FBSztJQUM3QkMsVUFBVSxNQUFNO0lBQ2hCQyxZQUEyQixLQUFLO0lBQ2hDQyxRQUFzQixFQUFFLENBQUM7SUFDekJDLGFBQWEsTUFBTTtJQUNuQkMsU0FBUyxNQUFNO0lBRXZCLE1BQU1DLE1BQU1DLGdCQUF5QixFQUFpQjtRQUNwRCx1QkFBdUI7UUFDdkIsSUFBSSxJQUFJLENBQUNQLE1BQU0sRUFBRTtZQUNmO1FBQ0Y7UUFFQSxNQUFNLEVBQUVRLFlBQVksRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDO1FBRXRDLE1BQU1DLGdCQUFnQztZQUNwQ0MsUUFBUTtnQkFBRUMsT0FBTztZQUFLO1FBQ3hCO1FBRUEsTUFBTUMsYUFBeUI7WUFDN0JELE9BQU87WUFDUEUsWUFBWTtZQUNaQyxvQkFBb0IsRUFBRTtZQUN0QkMsUUFBUVI7WUFDUlMsS0FB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonamu",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "Sonamu — TypeScript Fullstack API Framework",
5
5
  "keywords": [
6
6
  "typescript",
@@ -119,10 +119,10 @@
119
119
  "tsicli": "^1.0.5",
120
120
  "vite": "7.3.0",
121
121
  "vitest": "^4.0.10",
122
- "@sonamu-kit/hmr-hook": "^0.4.1",
123
122
  "@sonamu-kit/hmr-runner": "^0.1.1",
124
123
  "@sonamu-kit/tasks": "^0.2.0",
125
- "@sonamu-kit/ts-loader": "^2.1.3"
124
+ "@sonamu-kit/ts-loader": "^2.1.3",
125
+ "@sonamu-kit/hmr-hook": "^0.4.1"
126
126
  },
127
127
  "devDependencies": {
128
128
  "@biomejs/biome": "^2.3.13",
@@ -25,65 +25,21 @@ Sonamu 프레임워크로 프로젝트를 개발하기 위한 Claude Code skill
25
25
 
26
26
  ## 개발 흐름
27
27
 
28
- ### 1. 프로젝트 생성
29
- ```bash
30
- pnpm create sonamu [프로젝트명] --yes
31
- ```
28
+ **CRITICAL: 모든 개발은 반드시 `workflow.md`의 PHASE 0 → 7 순서를 따른다. 단계를 건너뛰거나 순서를 바꾸지 않는다.**
32
29
 
33
- ### 2. Sonamu 링크 설정 (선택)
34
- **Skills 원본 동기화가 필요한 경우만** `pnpm-workspace.yaml`에 추가:
35
- ```yaml
36
- overrides:
37
- sonamu: link:../../sonamu/modules/sonamu
38
30
  ```
39
- > 이유: Skills sync, 로컬 Sonamu 변경사항 즉시 반영
40
-
41
- ### 3. 의존성 설치 및 빌드
42
- 프로젝트 루트에서:
43
- ```bash
44
- pnpm install
45
- pnpm -r build
31
+ PHASE 0: 프로젝트 초기화 (프로젝트 생성 + auth generate)
32
+ PHASE 1: 엔티티 설계 (Auth 엔티티 확인 후 나머지 설계)
33
+ PHASE 2: 엔티티 생성
34
+ PHASE 3: 마이그레이션
35
+ PHASE 4: Cone 생성 (LLM 사용 여부 사용자에게 확인 후 진행)
36
+ PHASE 5: 스캐폴딩
37
+ PHASE 6: 테스트 작성 (완료 후 Fixture 생성 여부 확인, LLM 사용 여부도 확인)
38
+ PHASE 7: API 개발
39
+ PHASE 8: Frontend 개발
46
40
  ```
47
- > 빌드 실패 시 → 4번 도커 먼저 실행 후 5번 dev 서버 올리고 재시도
48
-
49
- ### 4. Docker 실행
50
- ```bash
51
- cd packages/api
52
- pnpm docker:up
53
- ```
54
-
55
- ### 5. 개발 서버 실행
56
- ```bash
57
- pnpm dev
58
- ```
59
- > 3번 빌드가 실패했다면, dev 서버가 올라온 후 프로젝트 루트에서 `pnpm -r build` 재시도
60
-
61
- ### 6. Auth 엔티티 생성 (별도 터미널)
62
- **dev 실행 중**에:
63
- ```bash
64
- pnpm sonamu auth generate
65
- ```
66
- > dev 모드에서 실행해야 types도 자동 생성됨
67
-
68
- ### 7. Subset 확인
69
- Sonamu UI Entity 메뉴에서 subset 체크
70
-
71
- ### 8. Migration
72
- ```bash
73
- pnpm sonamu migrate run
74
- ```
75
-
76
- ### 9. Scaffolding
77
- Sonamu UI에서 Model/View Scaffolding 실행
78
-
79
- ### 10. API 단위테스트
80
- ```bash
81
- pnpm test:watch
82
- ```
83
-
84
- ### 11. 프론트엔드 개발
85
41
 
86
- **상세 내용:** `project-init.md` 참조
42
+ **상세 내용:** `workflow.md` 참조
87
43
 
88
44
  ---
89
45
 
@@ -5,12 +5,79 @@ description: Sonamu 전체 개발 워크플로우. 엔티티 설계부터 Fronte
5
5
 
6
6
  # Sonamu 전체 개발 워크플로우
7
7
 
8
- 사용자가 시스템 구축을 요청하면 다음 7단계로 진행한다.
8
+ 사용자가 시스템 구축을 요청하면 다음 9단계로 진행한다.
9
+
10
+ **CRITICAL: 이 워크플로우는 반드시 순서대로 진행한다. 단계를 건너뛰거나 순서를 바꾸지 않는다.**
9
11
 
10
12
  **CRITICAL: 요구사항이 이미 제공된 경우에도 설계 및 비즈니스 로직은 반드시 사용자와 함께 확인한다.**
11
13
  요구사항 명세는 출발점일 뿐이다. Entity 구조, 관계, 필드, 상태 전이, 권한 규칙 등은 항상 사용자에게 질문하고 승인을 받아야 한다. 과거에 비슷한 요구사항을 받은 적이 있더라도 이번 프로젝트의 설계는 새로 확인한다.
12
14
 
13
- ## 사용자 요청 → 완성까지 7단계
15
+ ## 사용자 요청 → 완성까지 9단계
16
+
17
+ ### PHASE 0: 프로젝트 초기화
18
+
19
+ **목표:** 프로젝트 생성 및 better-auth 기반 엔티티 준비
20
+
21
+ **참조 스킬:** project-init.md, create-sonamu.md, auth.md
22
+
23
+ **절차:**
24
+
25
+ 1. **작업 경로 확인**
26
+ - 현재 디렉토리 또는 지정 디렉토리 확인
27
+ - `project-init.md` "0. 작업 경로 확인" 참조
28
+
29
+ 2. **프로젝트 생성**
30
+ ```bash
31
+ pnpm create sonamu [프로젝트명] --yes
32
+ ```
33
+ 기존 프로젝트면 경로 확인 후 진행.
34
+
35
+ 3. **요구사항 문서화** (요구사항 제공 시)
36
+ - `.claude/skills/project/requirements.md` 작성
37
+ - `project-init.md` "요구사항 문서화" 참조
38
+
39
+ 4. **의존성 설치 및 빌드**
40
+ ```bash
41
+ pnpm install
42
+ pnpm -r build
43
+ ```
44
+ > 빌드 실패 시 → 5번 Docker 먼저 실행 후 6번 dev 서버 올리고 재시도
45
+
46
+ 5. **Docker 실행**
47
+ ```bash
48
+ cd packages/api
49
+ pnpm docker:up
50
+ ```
51
+
52
+ 6. **개발 서버 실행**
53
+ ```bash
54
+ pnpm dev
55
+ ```
56
+
57
+ 7. **Auth 엔티티 생성** (별도 터미널, dev 실행 중)
58
+ ```bash
59
+ cd packages/api
60
+ pnpm sonamu auth generate
61
+ ```
62
+ 생성되는 엔티티: `User`, `Session`, `Account`, `Verification`
63
+ > dev 모드에서 실행해야 types 파일도 자동 생성됨
64
+
65
+ 8. **생성된 Auth 엔티티 확인**
66
+ - Sonamu UI (`http://localhost:34900/sonamu-ui`) → Entity 메뉴에서 4개 엔티티 확인
67
+ - **User 엔티티 필드 파악** (id 타입, 기본 제공 필드 목록)
68
+ - 이후 PHASE 1 엔티티 설계 시 User와의 관계를 고려해야 하므로 반드시 확인
69
+
70
+ **완료 기준:**
71
+
72
+ - [ ] 프로젝트 생성 완료
73
+ - [ ] Docker 실행 중
74
+ - [ ] dev 서버 실행 중
75
+ - [ ] `pnpm sonamu auth generate` 완료
76
+ - [ ] User, Session, Account, Verification 엔티티 확인 완료
77
+
78
+ **다음 단계:** PHASE 1 엔티티 설계
79
+
80
+ ---
14
81
 
15
82
  ### PHASE 1: 엔티티 설계
16
83
 
@@ -18,6 +85,9 @@ description: Sonamu 전체 개발 워크플로우. 엔티티 설계부터 Fronte
18
85
 
19
86
  **참조 스킬:** entity-basic.md, entity-relations.md
20
87
 
88
+ **CRITICAL: PHASE 0에서 생성된 Auth 엔티티(User, Session, Account, Verification)를 확인한 후 설계를 시작한다.**
89
+ User 엔티티는 이미 생성되어 있으므로 중복 생성하지 않는다. 다른 엔티티에서 User를 참조하는 관계는 이미 존재하는 User 엔티티 구조에 맞춰 설계한다.
90
+
21
91
  **절차:**
22
92
 
23
93
  1. **비즈니스 플로우 작성**
@@ -218,11 +288,71 @@ pnpm dev # 이 상태로 유지하면서 작업
218
288
  - [ ] Migration 오류 없이 완료
219
289
  - [ ] DB에 테이블 생성 확인 (psql 또는 DB UI)
220
290
 
221
- **다음 단계:** PHASE 4 스캐폴딩
291
+ **다음 단계:** PHASE 4 Cone 생성
292
+
293
+ ---
294
+
295
+ ### PHASE 4: Cone 생성
296
+
297
+ **목표:** Entity에 fixture 생성 가이드 메타데이터(cone) 부착
298
+
299
+ **참조 스킬:** fixture-cli.md (고급: cone 메타데이터 섹션)
300
+
301
+ **Cone이란?**
302
+ 각 Entity/Prop/Subset/Enum에 `cone` 메타데이터를 추가하여 fixture 생성 시 더 현실적인 테스트 데이터를 만들 수 있게 하는 기능이다. `note`, `fixtureGenerator`, `fixtureDefault`, `dataSource` 등의 속성으로 구성된다.
303
+
304
+ **절차:**
305
+
306
+ 1. **LLM 사용 여부 확인**
307
+
308
+ 사용자에게 묻는다:
309
+ > "Cone 메타데이터를 생성할게요. 요구사항 명세(`requirements.md`)를 참고하여 LLM이 각 필드에 맞는 설명과 faker 생성 로직을 자동으로 작성할 수 있습니다.
310
+ > LLM(Claude API)을 호출하여 생성하갬습니까?
311
+ > 1. 예 — AI가 요구사항 기반 상세 cone 생성 (ANTHROPIC_API_KEY 필요, 소량 과금)
312
+ > 2. 아니오 — faker 타입 매핑 기반 템플릿 cone 자동 생성 (API 키 불필요)"
313
+
314
+ **선택 1 — LLM 사용:**
315
+ ```bash
316
+ # 단일 Entity
317
+ pnpm sonamu cone gen [EntityId]
318
+
319
+ # 전체 Entity
320
+ pnpm sonamu cone gen --all
321
+
322
+ # 전체 재생성 (기존 덮어쓰기)
323
+ pnpm sonamu cone gen --all --regenerate
324
+
325
+ # 언어 지정 (기본: sonamu.config.ts의 i18n.defaultLocale)
326
+ pnpm sonamu cone gen --all --locale ko
327
+ ```
328
+ > ANTHROPIC_API_KEY가 없으면 에러 발생 → `sonamu.secret.ts` 또는 환경변수 설정 필요
329
+
330
+ **선택 2 — 템플릿 cone 사용:**
331
+ ```bash
332
+ # stub entity 시 이미 템플릿 cone이 생성되어 있음 (별도 작업 불필요)
333
+ # 필요 시 개별 Entity의 entity.json을 직접 편집
334
+ ```
335
+ > stub entity 실행 시 faker 타입 매핑 기반 기본 cone이 자동 생성된다.
336
+ > 나중에 `pnpm sonamu cone gen [EntityId]`로 AI 업그레이드 가능.
337
+
338
+ 2. **생성 결과 확인**
339
+ - 각 Entity의 `entity.json` → `cone` 필드 확인
340
+ - `note`: 필드 설명 및 fixture 생성 가이드
341
+ - `fixtureGenerator`: faker.js 표현식
342
+ - `dataSource`: BelongsToOne 관계 참조 전략
343
+ - 필요 시 직접 편집하여 커스터마이징
344
+
345
+ **완료 기준:**
346
+
347
+ - [ ] 모든 Entity의 `entity.json`에 cone 메타데이터 존재
348
+ - [ ] BelongsToOne 관계 필드에 `dataSource` 설정 확인
349
+ - [ ] LLM 사용 시 비용 확인 (콘솔 출력 참고)
350
+
351
+ **다음 단계:** PHASE 5 스캐폴딩
222
352
 
223
353
  ---
224
354
 
225
- ### PHASE 4: 스캐폴딩
355
+ ### PHASE 5: 스캐폴딩
226
356
 
227
357
  **목표:** Model, API, Frontend 코드 자동 생성
228
358
 
@@ -299,11 +429,11 @@ pnpm dev # 이 상태로 유지하면서 작업
299
429
  - [ ] Relation이 있는 경우 ko.ts 키 추가 완료
300
430
  - [ ] types.ts nullable 필드 처리 완료
301
431
 
302
- **다음 단계:** PHASE 5 테스트 작성
432
+ **다음 단계:** PHASE 6 테스트 작성
303
433
 
304
434
  ---
305
435
 
306
- ### PHASE 5: 테스트 작성
436
+ ### PHASE 6: 테스트 작성
307
437
 
308
438
  **목표:** 업무 프로세스 기반 모듈 테스트 작성
309
439
 
@@ -406,11 +536,47 @@ pnpm dev # 이 상태로 유지하면서 작업
406
536
  - [ ] 업무 시나리오 검증 완료
407
537
  - [ ] 모든 그룹 커밋 완료
408
538
 
409
- **다음 단계:** PHASE 6 API 개발
539
+ **[사용자 확인] Fixture 생성**
540
+
541
+ 테스트 작성 완료 후 사용자에게 묻는다:
542
+
543
+ > "Fixture 데이터를 생성할게요.
544
+ > 테스트 DB에 현실적인 샘플 데이터를 체우면 확장성 테스트나 프론트엔드 개발에 도움이 됩니다.
545
+ > Fixture를 생성하시갌습니까?
546
+ > 1. 예 — Fixture 생성 진행
547
+ > 2. 아니오 — PHASE 7 API 개발로 바로 진행"
548
+
549
+ **예 선택 시 — Fixture 생성 방식 확인:**
550
+
551
+ > "Fixture 데이터를 어떻게 생성할까요?
552
+ > 1. LLM 사용 — `cone.note` 기반으로 Claude API가 현실적인 데이터 생성 (ANTHROPIC_API_KEY 필요)
553
+ > 2. 템플릿 사용 — faker.js 기반 자동 생성 (API 키 불필요)"
554
+
555
+ **LLM 사용 시:**
556
+ ```bash
557
+ # 대화형 모드
558
+ pnpm sonamu fixture gen
559
+
560
+ # 또는 직접 지정
561
+ pnpm sonamu fixture gen --include User,Post,Comment --count 10 --use-llm
562
+
563
+ # 후 테스트 DB 동기화
564
+ pnpm sonamu fixture sync
565
+ ```
566
+
567
+ **템플릿 사용 시:**
568
+ ```bash
569
+ pnpm sonamu fixture gen --include User,Post,Comment --count 10
570
+ pnpm sonamu fixture sync
571
+ ```
572
+
573
+ > fixture gen 세부 옵션 및 생성 전략은 `fixture-cli.md` 참조
574
+
575
+ **다음 단계:** PHASE 7 API 개발
410
576
 
411
577
  ---
412
578
 
413
- ### PHASE 6: API 개발
579
+ ### PHASE 7: API 개발
414
580
 
415
581
  **목표:** 요구사항에 따른 비즈니스 로직 API 구현
416
582
 
@@ -464,11 +630,11 @@ pnpm dev # 이 상태로 유지하면서 작업
464
630
  - [ ] API 테스트 통과
465
631
  - [ ] Build 성공
466
632
 
467
- **다음 단계:** PHASE 7 Frontend 개발
633
+ **다음 단계:** PHASE 8 Frontend 개발
468
634
 
469
635
  ---
470
636
 
471
- ### PHASE 7: Frontend 개발
637
+ ### PHASE 8: Frontend 개발
472
638
 
473
639
  **목표:** 화면에서 실제 동작 확인
474
640
 
@@ -547,20 +713,29 @@ pnpm dev # 이 상태로 유지하면서 작업
547
713
 
548
714
  ## 빠른 참조 테이블
549
715
 
550
- | 단계 | 예상 시간 | 핵심 명령어 | 핵심 스킬 |
551
- | --------------- | ----------- | ------------------------ | -------------------- |
552
- | 1. 설계 | 5-10| (대화) | entity-basic.md |
553
- | 2. 생성 | 10-15 | `stub entity`, `sync` | entity-basic.md |
554
- | 3. 마이그레이션 | 5 | `migration:latest` | migration.md |
555
- | 4. 스캐폴딩 | 5-10 | `scaffold`, `build` | scaffolding.md |
556
- | 5. 테스트 | 30-60분 | `test`, `test:watch` | testing.md |
557
- | **6. API 개발** | **1-3시간** | **@api 데코레이터** | **api.md, model.md** |
558
- | **7. Frontend** | **2-5시간** | **Service, useTypeForm** | **frontend.md** |
716
+ | 단계 | 예상 시간 | 핵심 명령어 | 핵심 스킬 |
717
+ | -------------------- | ----------- | ----------------------------- | ----------------------------- |
718
+ | **0. 프로젝트 초기화** | **5-10분** | **`create sonamu`, `auth generate`** | **project-init.md, auth.md** |
719
+ | 1. 엔티티 설계 | 5-10분 | (대화) | entity-basic.md |
720
+ | 2. 엔티티 생성 | 10-15 | `stub entity`, `sync` | entity-basic.md |
721
+ | 3. 마이그레이션 | 5분 | `migration:latest` | migration.md |
722
+ | **4. Cone 생성** | **5-10분** | **`cone gen`** | **fixture-cli.md** |
723
+ | 5. 스캐폴딩 | 5-10분 | `scaffold`, `build` | scaffolding.md |
724
+ | 6. 테스트 | 30-60분 | `test`, `test:watch` | testing.md |
725
+ | **7. API 개발** | **1-3시간** | **@api 데코레이터** | **api.md, model.md** |
726
+ | **8. Frontend** | **2-5시간** | **Service, useTypeForm** | **frontend.md** |
559
727
 
560
728
  ---
561
729
 
562
730
  ## 각 단계의 완료 확인
563
731
 
732
+ ### PHASE 0 완료 시
733
+
734
+ ```
735
+ 프로젝트 초기화 완료 (Auth 엔티티 생성 포함)
736
+ → 다음: PHASE 1 엔티티 설계 (entity-basic.md)
737
+ ```
738
+
564
739
  ### PHASE 1 완료 시
565
740
 
566
741
  ```
@@ -579,32 +754,40 @@ pnpm dev # 이 상태로 유지하면서 작업
579
754
 
580
755
  ```
581
756
  마이그레이션 완료
582
- → 다음: PHASE 4 스캐폴딩 (scaffolding.md)
757
+ → 다음: PHASE 4 Cone 생성 (fixture-cli.md)
583
758
  ```
584
759
 
585
760
  ### PHASE 4 완료 시
586
761
 
587
762
  ```
588
- 스캐폴딩 완료
589
- → 다음: PHASE 5 테스트 작성 (testing.md)
763
+ Cone 생성 완료
764
+ → 다음: PHASE 5 스캐폴딩 (scaffolding.md)
590
765
  ```
591
766
 
592
767
  ### PHASE 5 완료 시
593
768
 
594
769
  ```
595
- 테스트 작성 완료
596
- → 다음: PHASE 6 API 개발 (api.md)
770
+ 스ce90폴딩 완료
771
+ → 다음: PHASE 6 테스트 작성 (testing.md)
597
772
  ```
598
773
 
599
774
  ### PHASE 6 완료 시
600
775
 
601
776
  ```
602
- API 개발 완료
603
- 다음: PHASE 7 Frontend 개발 (frontend.md)
777
+ 테스트 작성 완료
778
+ [사용자 확인] Fixture 생성 여부 확인 원스톱
779
+ → 다음: PHASE 7 API 개발 (api.md)
604
780
  ```
605
781
 
606
782
  ### PHASE 7 완료 시
607
783
 
784
+ ```
785
+ API 개발 완료
786
+ → 다음: PHASE 8 Frontend 개발 (frontend.md)
787
+ ```
788
+
789
+ ### PHASE 8 완료 시
790
+
608
791
  ```
609
792
  Frontend 개발 완료
610
793
  전체 워크플로우 완료
@@ -104,6 +104,14 @@ export class DevVitestManager {
104
104
  }
105
105
  this.closed = true;
106
106
 
107
+ // 큐에 남은 작업들을 reject하여 호출자가 영구 대기하지 않도록 정리
108
+ while (this.queue.length > 0) {
109
+ const entry = this.queue.shift();
110
+ if (entry) {
111
+ entry.reject(new Error("DevVitestManager is being shut down"));
112
+ }
113
+ }
114
+
107
115
  if (this.vitest) {
108
116
  await this.vitest.close();
109
117
  this.vitest = null;