@decohere/create 0.0.1-dev.43 → 0.0.1-dev.44

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.
Files changed (47) hide show
  1. package/commonjs/src/models/config-yaml.model.js +58 -4
  2. package/commonjs/src/models/env-file.model.js +14 -1
  3. package/commonjs/src/models/launch-json.model.js +49 -27
  4. package/commonjs/src/models/package-json.model.js +64 -7
  5. package/commonjs/src/models/project.model.js +4 -1
  6. package/commonjs/src/program.js +52 -21
  7. package/commonjs/src/runner.js +13 -2
  8. package/commonjs/src/webapi/api-name.js +95 -0
  9. package/commonjs/src/webapi/const.js +32 -4
  10. package/commonjs/src/webapi/create-api.js +62 -18
  11. package/commonjs/src/webapi/features/auth.feature.js +56 -51
  12. package/commonjs/src/webapi/features/biome-format.js +6 -4
  13. package/commonjs/src/webapi/features/database.feature.js +125 -98
  14. package/commonjs/src/webapi/features/finalize.feature.js +19 -7
  15. package/commonjs/src/webapi/models/api-package-json.model.js +7 -5
  16. package/commonjs/src/webapi/models/main-source-file.model.js +12 -3
  17. package/commonjs/src/webapi/models/production-dockerfile.model.js +76 -36
  18. package/es6/src/models/config-yaml.model.js +47 -1
  19. package/es6/src/models/env-file.model.js +14 -1
  20. package/es6/src/models/launch-json.model.js +49 -27
  21. package/es6/src/models/package-json.model.js +62 -5
  22. package/es6/src/models/project.model.js +4 -1
  23. package/es6/src/program.js +52 -21
  24. package/es6/src/runner.js +13 -2
  25. package/es6/src/webapi/api-name.js +59 -0
  26. package/es6/src/webapi/const.js +18 -5
  27. package/es6/src/webapi/create-api.js +64 -20
  28. package/es6/src/webapi/features/auth.feature.js +56 -51
  29. package/es6/src/webapi/features/biome-format.js +6 -4
  30. package/es6/src/webapi/features/database.feature.js +125 -98
  31. package/es6/src/webapi/features/finalize.feature.js +19 -7
  32. package/es6/src/webapi/models/api-package-json.model.js +8 -6
  33. package/es6/src/webapi/models/main-source-file.model.js +12 -3
  34. package/es6/src/webapi/models/production-dockerfile.model.js +71 -36
  35. package/package.json +2 -2
  36. package/types/src/models/config-yaml.model.d.ts +11 -0
  37. package/types/src/models/env-file.model.d.ts +1 -0
  38. package/types/src/models/launch-json.model.d.ts +2 -0
  39. package/types/src/models/package-json.model.d.ts +16 -6
  40. package/types/src/models/project.model.d.ts +3 -0
  41. package/types/src/webapi/api-name.d.ts +14 -0
  42. package/types/src/webapi/const.d.ts +15 -5
  43. package/types/src/webapi/create-api.d.ts +4 -0
  44. package/types/src/webapi/features/biome-format.d.ts +1 -1
  45. package/types/src/webapi/models/api-package-json.model.d.ts +4 -3
  46. package/types/src/webapi/models/main-source-file.model.d.ts +6 -0
  47. package/types/src/webapi/models/production-dockerfile.model.d.ts +13 -2
@@ -44,6 +44,7 @@ import { WELL_KNOWN_FILES } from "../../models/const.js";
44
44
  _entities = [];
45
45
  _repositories = [];
46
46
  _services = [];
47
+ _dataSourceName;
47
48
  _typeOrmSeed;
48
49
  constructor(appName){
49
50
  this.appName = appName;
@@ -77,6 +78,13 @@ import { WELL_KNOWN_FILES } from "../../models/const.js";
77
78
  this._services.push(service);
78
79
  return this;
79
80
  }
81
+ /**
82
+ * Datasource name passed to `withTypeOrm({ name })`. Must match
83
+ * `database.dataSources[].name` in config.yaml.
84
+ */ setDataSourceName(name) {
85
+ this._dataSourceName = name;
86
+ return this;
87
+ }
80
88
  /**
81
89
  * Inline seed callback body for `withTypeOrm({ seed })`.
82
90
  * Receives `dataSource` in scope. Example: `await dataSource.getRepository(User).save(...)`.
@@ -119,10 +127,11 @@ import { WELL_KNOWN_FILES } from "../../models/const.js";
119
127
  if (this._entities.length > 0) {
120
128
  const entities = this._entities.map((e)=>e.className).join(", ");
121
129
  const repos = this._repositories.map((r)=>r.className).join(", ");
130
+ const named = this._dataSourceName != null ? `name: "${this._dataSourceName}", ` : "";
122
131
  if (this._typeOrmSeed) {
123
- builderCalls.push(`\t.withTypeOrm({ entities: [${entities}], repositories: [${repos}], seed: async (dataSource) => { ${this._typeOrmSeed} } })`);
132
+ builderCalls.push(`\t.withTypeOrm({ ${named}entities: [${entities}], repositories: [${repos}], seed: async (dataSource) => { ${this._typeOrmSeed} } })`);
124
133
  } else {
125
- builderCalls.push(`\t.withTypeOrm({ entities: [${entities}], repositories: [${repos}] })`);
134
+ builderCalls.push(`\t.withTypeOrm({ ${named}entities: [${entities}], repositories: [${repos}] })`);
126
135
  }
127
136
  }
128
137
  builderCalls.push(`\t.withControllers(HelloController)`);
@@ -149,4 +158,4 @@ import { WELL_KNOWN_FILES } from "../../models/const.js";
149
158
  }
150
159
  }
151
160
 
152
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS9zcmMvd2ViYXBpL21vZGVscy9tYWluLXNvdXJjZS1maWxlLm1vZGVsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdFTExfS05PV05fRklMRVMgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL2NvbnN0LmpzXCI7XG5pbXBvcnQgdHlwZSB7IEtleWVkTW9kZWwsIFNvdXJjZUZpbGUgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL3NvdXJjZS1maWxlLmpzXCI7XG5cbmV4cG9ydCB0eXBlIFR5cGVPcm1JbXBvcnQgPSB7IGNsYXNzTmFtZTogc3RyaW5nOyBpbXBvcnRQYXRoOiBzdHJpbmcgfTtcbmV4cG9ydCB0eXBlIFNlcnZpY2VJbXBvcnQgPSBUeXBlT3JtSW1wb3J0ICYgeyBzY29wZT86IFwic2luZ2xldG9uXCIgfCBcInJlcXVlc3RcIiB9O1xuXG4vKiogVHJhY2tzIG5hbWVkIGltcG9ydHMgZnJvbSBhIHNpbmdsZSBtb2R1bGUgcGF0aCwgc3BsaXQgaW50byB2YWx1ZXMgYW5kIHR5cGVzLiAqL1xuY2xhc3MgSW1wb3J0R3JvdXAge1xuXHRwcml2YXRlIHJlYWRvbmx5IF92YWx1ZXM6IHN0cmluZ1tdID0gW107XG5cdHByaXZhdGUgcmVhZG9ubHkgX3R5cGVzOiBzdHJpbmdbXSA9IFtdO1xuXG5cdHB1YmxpYyBhZGQobmFtZTogc3RyaW5nLCB0eXBlT25seSA9IGZhbHNlKTogdGhpcyB7XG5cdFx0aWYgKHR5cGVPbmx5KSB7XG5cdFx0XHQvLyBWYWx1ZSBpbXBvcnQgYWxyZWFkeSBwcmVzZW50IOKAlCB2YWx1ZSB3aW5zLCBza2lwXG5cdFx0XHRpZiAoIXRoaXMuX3ZhbHVlcy5pbmNsdWRlcyhuYW1lKSAmJiAhdGhpcy5fdHlwZXMuaW5jbHVkZXMobmFtZSkpIHtcblx0XHRcdFx0dGhpcy5fdHlwZXMucHVzaChuYW1lKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gUHJvbW90ZTogcmVtb3ZlIGZyb20gdHlwZXMgaWYgaXQgd2FzIHByZXZpb3VzbHkgdHlwZS1vbmx5XG5cdFx0XHRjb25zdCB0eXBlSWR4ID0gdGhpcy5fdHlwZXMuaW5kZXhPZihuYW1lKTtcblx0XHRcdGlmICh0eXBlSWR4ICE9PSAtMSkgdGhpcy5fdHlwZXMuc3BsaWNlKHR5cGVJZHgsIDEpO1xuXHRcdFx0aWYgKCF0aGlzLl92YWx1ZXMuaW5jbHVkZXMobmFtZSkpIHRoaXMuX3ZhbHVlcy5wdXNoKG5hbWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHB1YmxpYyByZW5kZXIoZnJvbTogc3RyaW5nKTogc3RyaW5nIHtcblx0XHRjb25zdCB2YWx1ZXMgPSBbLi4udGhpcy5fdmFsdWVzXS5zb3J0KCk7XG5cdFx0Y29uc3QgdHlwZXMgPSBbLi4udGhpcy5fdHlwZXNdLnNvcnQoKS5tYXAoKG4pID0+IGB0eXBlICR7bn1gKTtcblx0XHRyZXR1cm4gYGltcG9ydCB7ICR7Wy4uLnZhbHVlcywgLi4udHlwZXNdLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwiJHtmcm9tfVwiO2A7XG5cdH1cbn1cblxuLyoqXG4gKiBNb2RlbCBmb3IgYHByb2plY3RzL2FwaS9zcmMvbWFpbi50c2AuXG4gKlxuICogU3RhcnRzIHdpdGggdGhlIG1pbmltYWwgSFRUUCArIFlBTUwgY29uZmlnIHNldHVwLiBGZWF0dXJlcyBtdXRhdGUgdGhlIG1vZGVsXG4gKiBieSBjYWxsaW5nIGFkZFNpZGVFZmZlY3RJbXBvcnQgLyBhZGRJbXBvcnQgLyBhZGRCdWlsZGVyQ2FsbCAvIGFkZEVudGl0eSAvXG4gKiBhZGRSZXBvc2l0b3J5LiBmaWxlcygpIHJlbmRlcnMgd2hhdGV2ZXIgaGFzIGJlZW4gYWNjdW11bGF0ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBNYWluU291cmNlRmlsZSBpbXBsZW1lbnRzIEtleWVkTW9kZWwge1xuXHRwdWJsaWMgcmVhZG9ubHkga2V5ID0gV0VMTF9LTk9XTl9GSUxFUy5NQUlOX1RTO1xuXG5cdHByaXZhdGUgcmVhZG9ubHkgX3NpZGVFZmZlY3RJbXBvcnRzOiBzdHJpbmdbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9leHRyYUltcG9ydHMgPSBuZXcgTWFwPHN0cmluZywgSW1wb3J0R3JvdXA+KCk7XG5cdHByaXZhdGUgcmVhZG9ubHkgX2J1aWxkZXJDYWxsczogc3RyaW5nW10gPSBbXTtcblx0cHJpdmF0ZSByZWFkb25seSBfZW50aXRpZXM6IFR5cGVPcm1JbXBvcnRbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9yZXBvc2l0b3JpZXM6IFR5cGVPcm1JbXBvcnRbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9zZXJ2aWNlczogU2VydmljZUltcG9ydFtdID0gW107XG5cdHByaXZhdGUgX3R5cGVPcm1TZWVkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgYXBwTmFtZTogc3RyaW5nKSB7fVxuXG5cdC8qKiBBZGRzIGEgYmFyZSBzaWRlLWVmZmVjdCBpbXBvcnQsIGUuZy4gYEBkZWNvaGVyZS9jb3J0ZXgvYXV0aGAuICovXG5cdHB1YmxpYyBhZGRTaWRlRWZmZWN0SW1wb3J0KHBhdGg6IHN0cmluZyk6IHRoaXMge1xuXHRcdGlmICghdGhpcy5fc2lkZUVmZmVjdEltcG9ydHMuaW5jbHVkZXMocGF0aCkpIHRoaXMuX3NpZGVFZmZlY3RJbXBvcnRzLnB1c2gocGF0aCk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKiogQWRkcyBhIG5hbWVkIGltcG9ydCwgZS5nLiBgaW1wb3J0IHsgRm9vIH0gZnJvbSBcImJhclwiYC4gKi9cblx0cHVibGljIGFkZEltcG9ydChuYW1lOiBzdHJpbmcsIGZyb206IHN0cmluZywgdHlwZU9ubHkgPSBmYWxzZSk6IHRoaXMge1xuXHRcdGNvbnN0IGdyb3VwID0gdGhpcy5fZXh0cmFJbXBvcnRzLmdldChmcm9tKSA/PyBuZXcgSW1wb3J0R3JvdXAoKTtcblx0XHRncm91cC5hZGQobmFtZSwgdHlwZU9ubHkpO1xuXHRcdHRoaXMuX2V4dHJhSW1wb3J0cy5zZXQoZnJvbSwgZ3JvdXApO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBidWlsZGVyIGNhbGwgaW5zZXJ0ZWQgYWZ0ZXIgYC53aXRoQ29uZmlndXJhdGlvbigpYCBhbmQgYmVmb3JlXG5cdCAqIGAud2l0aFNlcnZpY2VzKClgLiBQYXNzIHRoZSBjYWxsIHdpdGhvdXQgbGVhZGluZyBkb3QsIGUuZy4gYC53aXRoQXV0aCgpYC5cblx0ICovXG5cdHB1YmxpYyBhZGRCdWlsZGVyQ2FsbChjYWxsOiBzdHJpbmcpOiB0aGlzIHtcblx0XHR0aGlzLl9idWlsZGVyQ2FsbHMucHVzaChjYWxsKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKiBBZGRzIGEgVHlwZU9STSBlbnRpdHkg4oCUIGltcG9ydCBhbmQgZW50cnkgaW4gYHdpdGhUeXBlT3JtKHsgZW50aXRpZXMgfSlgLiAqL1xuXHRwdWJsaWMgYWRkRW50aXR5KGVudGl0eTogVHlwZU9ybUltcG9ydCk6IHRoaXMge1xuXHRcdHRoaXMuX2VudGl0aWVzLnB1c2goZW50aXR5KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKiBBZGRzIGEgVHlwZU9STSByZXBvc2l0b3J5IOKAlCBpbXBvcnQgYW5kIGVudHJ5IGluIGB3aXRoVHlwZU9ybSh7IHJlcG9zaXRvcmllcyB9KWAuICovXG5cdHB1YmxpYyBhZGRSZXBvc2l0b3J5KHJlcG86IFR5cGVPcm1JbXBvcnQpOiB0aGlzIHtcblx0XHR0aGlzLl9yZXBvc2l0b3JpZXMucHVzaChyZXBvKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKiBBZGRzIGEgc2VydmljZSByZWdpc3RlcmVkIGluIGAud2l0aFNlcnZpY2VzKClgLiAqL1xuXHRwdWJsaWMgYWRkU2VydmljZShzZXJ2aWNlOiBTZXJ2aWNlSW1wb3J0KTogdGhpcyB7XG5cdFx0dGhpcy5fc2VydmljZXMucHVzaChzZXJ2aWNlKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBJbmxpbmUgc2VlZCBjYWxsYmFjayBib2R5IGZvciBgd2l0aFR5cGVPcm0oeyBzZWVkIH0pYC5cblx0ICogUmVjZWl2ZXMgYGRhdGFTb3VyY2VgIGluIHNjb3BlLiBFeGFtcGxlOiBgYXdhaXQgZGF0YVNvdXJjZS5nZXRSZXBvc2l0b3J5KFVzZXIpLnNhdmUoLi4uKWAuXG5cdCAqL1xuXHRwdWJsaWMgc2V0VHlwZU9ybVNlZWQoc2VlZEJvZHk6IHN0cmluZyk6IHRoaXMge1xuXHRcdHRoaXMuX3R5cGVPcm1TZWVkID0gc2VlZEJvZHk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgZmlsZXMoKTogU291cmNlRmlsZVtdIHtcblx0XHRjb25zdCBpbXBvcnRzOiBzdHJpbmdbXSA9IFtcblx0XHRcdCdpbXBvcnQgXCJAZGVjb2hlcmUvc2NyaWJlLXBpbm9cIjsnLFxuXHRcdFx0J2ltcG9ydCBcIkBkZWNvaGVyZS9jb3J0ZXgvaHR0cFwiOycsXG5cdFx0XTtcblxuXHRcdGZvciAoY29uc3QgcGF0aCBvZiB0aGlzLl9zaWRlRWZmZWN0SW1wb3J0cykge1xuXHRcdFx0aW1wb3J0cy5wdXNoKGBpbXBvcnQgXCIke3BhdGh9XCI7YCk7XG5cdFx0fVxuXG5cdFx0aW1wb3J0cy5wdXNoKFxuXHRcdFx0J2ltcG9ydCBcIkBkZWNvaGVyZS9wcm90b2NvbFwiOycsXG5cdFx0XHQnaW1wb3J0IHsgWWFtbERhdGFTb3VyY2UgfSBmcm9tIFwiQGRlY29oZXJlL3Byb3RvY29sXCI7Jyxcblx0XHRcdCdpbXBvcnQgeyBCdWlsZGVyIH0gZnJvbSBcIkBkZWNvaGVyZS9jb3J0ZXhcIjsnLFxuXHRcdFx0J2ltcG9ydCB7IEZhc3RpZnlQcm92aWRlciB9IGZyb20gXCJAZGVjb2hlcmUvY29ydGV4L3Byb3ZpZGVyc1wiOycsXG5cdFx0XHQnaW1wb3J0IHsgc2NyaWJlIH0gZnJvbSBcIkBkZWNvaGVyZS9zY3JpYmVcIjsnLFxuXHRcdFx0J2ltcG9ydCB7IFNhbXBsZVNlcnZpY2UgfSBmcm9tIFwiLi9zZXJ2aWNlcy9zYW1wbGUuc2VydmljZS5qc1wiOycsXG5cdFx0KTtcblxuXHRcdGZvciAoY29uc3QgZSBvZiB0aGlzLl9lbnRpdGllcykge1xuXHRcdFx0aW1wb3J0cy5wdXNoKGBpbXBvcnQgeyAke2UuY2xhc3NOYW1lfSB9IGZyb20gXCIke2UuaW1wb3J0UGF0aH1cIjtgKTtcblx0XHR9XG5cblx0XHRmb3IgKGNvbnN0IHIgb2YgdGhpcy5fcmVwb3NpdG9yaWVzKSB7XG5cdFx0XHRpbXBvcnRzLnB1c2goYGltcG9ydCB7ICR7ci5jbGFzc05hbWV9IH0gZnJvbSBcIiR7ci5pbXBvcnRQYXRofVwiO2ApO1xuXHRcdH1cblxuXHRcdGZvciAoY29uc3QgcyBvZiB0aGlzLl9zZXJ2aWNlcykge1xuXHRcdFx0aW1wb3J0cy5wdXNoKGBpbXBvcnQgeyAke3MuY2xhc3NOYW1lfSB9IGZyb20gXCIke3MuaW1wb3J0UGF0aH1cIjtgKTtcblx0XHR9XG5cblx0XHRmb3IgKGNvbnN0IFtmcm9tLCBncm91cF0gb2YgdGhpcy5fZXh0cmFJbXBvcnRzKSB7XG5cdFx0XHRpbXBvcnRzLnB1c2goZ3JvdXAucmVuZGVyKGZyb20pKTtcblx0XHR9XG5cblx0XHRpbXBvcnRzLnB1c2goJ2ltcG9ydCB7IEhlbGxvQ29udHJvbGxlciB9IGZyb20gXCIuL2NvbnRyb2xsZXJzL2hlbGxvLmNvbnRyb2xsZXIuanNcIjsnKTtcblxuXHRcdGNvbnN0IHNlcnZpY2VSZWdzID0gW1xuXHRcdFx0XCJjYi5yZWdpc3RlclNpbmdsZXRvbihTYW1wbGVTZXJ2aWNlKTtcIixcblx0XHRcdC4uLnRoaXMuX3NlcnZpY2VzLm1hcCgocykgPT5cblx0XHRcdFx0cy5zY29wZSA9PT0gXCJyZXF1ZXN0XCJcblx0XHRcdFx0XHQ/IGBjYi5yZWdpc3RlclJlcXVlc3RTY29wZWQoJHtzLmNsYXNzTmFtZX0pO2Bcblx0XHRcdFx0XHQ6IGBjYi5yZWdpc3RlclNpbmdsZXRvbigke3MuY2xhc3NOYW1lfSk7YCxcblx0XHRcdCksXG5cdFx0XS5qb2luKFwiIFwiKTtcblxuXHRcdGNvbnN0IGJ1aWxkZXJDYWxsczogc3RyaW5nW10gPSBbXG5cdFx0XHRgXFx0LndpdGhIdHRwUHJvdmlkZXIoRmFzdGlmeVByb3ZpZGVyKWAsXG5cdFx0XHRgXFx0LndpdGhDb25maWd1cmF0aW9uKFlhbWxEYXRhU291cmNlKWAsXG5cdFx0XHQuLi50aGlzLl9idWlsZGVyQ2FsbHMubWFwKChjKSA9PiBgXFx0JHtjfWApLFxuXHRcdFx0YFxcdC53aXRoU2VydmljZXMoKGNiKSA9PiB7ICR7c2VydmljZVJlZ3N9IH0pYCxcblx0XHRdO1xuXG5cdFx0aWYgKHRoaXMuX2VudGl0aWVzLmxlbmd0aCA+IDApIHtcblx0XHRcdGNvbnN0IGVudGl0aWVzID0gdGhpcy5fZW50aXRpZXMubWFwKChlKSA9PiBlLmNsYXNzTmFtZSkuam9pbihcIiwgXCIpO1xuXHRcdFx0Y29uc3QgcmVwb3MgPSB0aGlzLl9yZXBvc2l0b3JpZXMubWFwKChyKSA9PiByLmNsYXNzTmFtZSkuam9pbihcIiwgXCIpO1xuXHRcdFx0aWYgKHRoaXMuX3R5cGVPcm1TZWVkKSB7XG5cdFx0XHRcdGJ1aWxkZXJDYWxscy5wdXNoKFxuXHRcdFx0XHRcdGBcXHQud2l0aFR5cGVPcm0oeyBlbnRpdGllczogWyR7ZW50aXRpZXN9XSwgcmVwb3NpdG9yaWVzOiBbJHtyZXBvc31dLCBzZWVkOiBhc3luYyAoZGF0YVNvdXJjZSkgPT4geyAke3RoaXMuX3R5cGVPcm1TZWVkfSB9IH0pYCxcblx0XHRcdFx0KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGJ1aWxkZXJDYWxscy5wdXNoKFxuXHRcdFx0XHRcdGBcXHQud2l0aFR5cGVPcm0oeyBlbnRpdGllczogWyR7ZW50aXRpZXN9XSwgcmVwb3NpdG9yaWVzOiBbJHtyZXBvc31dIH0pYCxcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRidWlsZGVyQ2FsbHMucHVzaChgXFx0LndpdGhDb250cm9sbGVycyhIZWxsb0NvbnRyb2xsZXIpYCk7XG5cblx0XHRjb25zdCBjb250ZW50ID0gW1xuXHRcdFx0Li4uaW1wb3J0cyxcblx0XHRcdFwiXCIsXG5cdFx0XHRcInNjcmliZS5leHRlbmQud2l0aFBpbm9QcmV0dHkoKTtcIixcblx0XHRcdFwiXCIsXG5cdFx0XHRgY29uc3QgYXBwID0gYXdhaXQgQnVpbGRlci5jcmVhdGUoeyBhcHBsaWNhdGlvbk5hbWU6IFwiJHt0aGlzLmFwcE5hbWV9XCIgfSlgLFxuXHRcdFx0Li4uYnVpbGRlckNhbGxzLFxuXHRcdFx0YFxcdC5idWlsZCgpO2AsXG5cdFx0XHRcIlwiLFxuXHRcdFx0XCJhd2FpdCBhcHAuc3RhcnQoeyBwb3J0OiBOdW1iZXIocHJvY2Vzcy5lbnYuUE9SVCkgfHwgMzAwMCB9KTtcIixcblx0XHRcdFwiXCIsXG5cdFx0XHRcImV4cG9ydCBkZWZhdWx0IGFwcDtcIixcblx0XHRcdFwiXCIsXG5cdFx0XS5qb2luKFwiXFxuXCIpO1xuXG5cdFx0cmV0dXJuIFtcblx0XHRcdHtcblx0XHRcdFx0ZmlsZVBhdGg6IFwic3JjL21haW4udHNcIixcblx0XHRcdFx0Y29udGVudCxcblx0XHRcdH0sXG5cdFx0XTtcblx0fVxufVxuIl0sIm5hbWVzIjpbIldFTExfS05PV05fRklMRVMiLCJJbXBvcnRHcm91cCIsIl92YWx1ZXMiLCJfdHlwZXMiLCJhZGQiLCJuYW1lIiwidHlwZU9ubHkiLCJpbmNsdWRlcyIsInB1c2giLCJ0eXBlSWR4IiwiaW5kZXhPZiIsInNwbGljZSIsInJlbmRlciIsImZyb20iLCJ2YWx1ZXMiLCJzb3J0IiwidHlwZXMiLCJtYXAiLCJuIiwiam9pbiIsIk1haW5Tb3VyY2VGaWxlIiwia2V5IiwiTUFJTl9UUyIsIl9zaWRlRWZmZWN0SW1wb3J0cyIsIl9leHRyYUltcG9ydHMiLCJNYXAiLCJfYnVpbGRlckNhbGxzIiwiX2VudGl0aWVzIiwiX3JlcG9zaXRvcmllcyIsIl9zZXJ2aWNlcyIsIl90eXBlT3JtU2VlZCIsImFwcE5hbWUiLCJhZGRTaWRlRWZmZWN0SW1wb3J0IiwicGF0aCIsImFkZEltcG9ydCIsImdyb3VwIiwiZ2V0Iiwic2V0IiwiYWRkQnVpbGRlckNhbGwiLCJjYWxsIiwiYWRkRW50aXR5IiwiZW50aXR5IiwiYWRkUmVwb3NpdG9yeSIsInJlcG8iLCJhZGRTZXJ2aWNlIiwic2VydmljZSIsInNldFR5cGVPcm1TZWVkIiwic2VlZEJvZHkiLCJmaWxlcyIsImltcG9ydHMiLCJlIiwiY2xhc3NOYW1lIiwiaW1wb3J0UGF0aCIsInIiLCJzIiwic2VydmljZVJlZ3MiLCJzY29wZSIsImJ1aWxkZXJDYWxscyIsImMiLCJsZW5ndGgiLCJlbnRpdGllcyIsInJlcG9zIiwiY29udGVudCIsImZpbGVQYXRoIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxnQkFBZ0IsUUFBUSx3QkFBd0I7QUFNekQsaUZBQWlGLEdBQ2pGLE1BQU1DO0lBQ1lDLFVBQW9CLEVBQUUsQ0FBQztJQUN2QkMsU0FBbUIsRUFBRSxDQUFDO0lBRWhDQyxJQUFJQyxJQUFZLEVBQUVDLFdBQVcsS0FBSyxFQUFRO1FBQ2hELElBQUlBLFVBQVU7WUFDYixrREFBa0Q7WUFDbEQsSUFBSSxDQUFDLElBQUksQ0FBQ0osT0FBTyxDQUFDSyxRQUFRLENBQUNGLFNBQVMsQ0FBQyxJQUFJLENBQUNGLE1BQU0sQ0FBQ0ksUUFBUSxDQUFDRixPQUFPO2dCQUNoRSxJQUFJLENBQUNGLE1BQU0sQ0FBQ0ssSUFBSSxDQUFDSDtZQUNsQjtRQUNELE9BQU87WUFDTiw0REFBNEQ7WUFDNUQsTUFBTUksVUFBVSxJQUFJLENBQUNOLE1BQU0sQ0FBQ08sT0FBTyxDQUFDTDtZQUNwQyxJQUFJSSxZQUFZLENBQUMsR0FBRyxJQUFJLENBQUNOLE1BQU0sQ0FBQ1EsTUFBTSxDQUFDRixTQUFTO1lBQ2hELElBQUksQ0FBQyxJQUFJLENBQUNQLE9BQU8sQ0FBQ0ssUUFBUSxDQUFDRixPQUFPLElBQUksQ0FBQ0gsT0FBTyxDQUFDTSxJQUFJLENBQUNIO1FBQ3JEO1FBQ0EsT0FBTyxJQUFJO0lB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
161
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS9zcmMvd2ViYXBpL21vZGVscy9tYWluLXNvdXJjZS1maWxlLm1vZGVsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdFTExfS05PV05fRklMRVMgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL2NvbnN0LmpzXCI7XG5pbXBvcnQgdHlwZSB7IEtleWVkTW9kZWwsIFNvdXJjZUZpbGUgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL3NvdXJjZS1maWxlLmpzXCI7XG5cbmV4cG9ydCB0eXBlIFR5cGVPcm1JbXBvcnQgPSB7IGNsYXNzTmFtZTogc3RyaW5nOyBpbXBvcnRQYXRoOiBzdHJpbmcgfTtcbmV4cG9ydCB0eXBlIFNlcnZpY2VJbXBvcnQgPSBUeXBlT3JtSW1wb3J0ICYgeyBzY29wZT86IFwic2luZ2xldG9uXCIgfCBcInJlcXVlc3RcIiB9O1xuXG4vKiogVHJhY2tzIG5hbWVkIGltcG9ydHMgZnJvbSBhIHNpbmdsZSBtb2R1bGUgcGF0aCwgc3BsaXQgaW50byB2YWx1ZXMgYW5kIHR5cGVzLiAqL1xuY2xhc3MgSW1wb3J0R3JvdXAge1xuXHRwcml2YXRlIHJlYWRvbmx5IF92YWx1ZXM6IHN0cmluZ1tdID0gW107XG5cdHByaXZhdGUgcmVhZG9ubHkgX3R5cGVzOiBzdHJpbmdbXSA9IFtdO1xuXG5cdHB1YmxpYyBhZGQobmFtZTogc3RyaW5nLCB0eXBlT25seSA9IGZhbHNlKTogdGhpcyB7XG5cdFx0aWYgKHR5cGVPbmx5KSB7XG5cdFx0XHQvLyBWYWx1ZSBpbXBvcnQgYWxyZWFkeSBwcmVzZW50IOKAlCB2YWx1ZSB3aW5zLCBza2lwXG5cdFx0XHRpZiAoIXRoaXMuX3ZhbHVlcy5pbmNsdWRlcyhuYW1lKSAmJiAhdGhpcy5fdHlwZXMuaW5jbHVkZXMobmFtZSkpIHtcblx0XHRcdFx0dGhpcy5fdHlwZXMucHVzaChuYW1lKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gUHJvbW90ZTogcmVtb3ZlIGZyb20gdHlwZXMgaWYgaXQgd2FzIHByZXZpb3VzbHkgdHlwZS1vbmx5XG5cdFx0XHRjb25zdCB0eXBlSWR4ID0gdGhpcy5fdHlwZXMuaW5kZXhPZihuYW1lKTtcblx0XHRcdGlmICh0eXBlSWR4ICE9PSAtMSkgdGhpcy5fdHlwZXMuc3BsaWNlKHR5cGVJZHgsIDEpO1xuXHRcdFx0aWYgKCF0aGlzLl92YWx1ZXMuaW5jbHVkZXMobmFtZSkpIHRoaXMuX3ZhbHVlcy5wdXNoKG5hbWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHB1YmxpYyByZW5kZXIoZnJvbTogc3RyaW5nKTogc3RyaW5nIHtcblx0XHRjb25zdCB2YWx1ZXMgPSBbLi4udGhpcy5fdmFsdWVzXS5zb3J0KCk7XG5cdFx0Y29uc3QgdHlwZXMgPSBbLi4udGhpcy5fdHlwZXNdLnNvcnQoKS5tYXAoKG4pID0+IGB0eXBlICR7bn1gKTtcblx0XHRyZXR1cm4gYGltcG9ydCB7ICR7Wy4uLnZhbHVlcywgLi4udHlwZXNdLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwiJHtmcm9tfVwiO2A7XG5cdH1cbn1cblxuLyoqXG4gKiBNb2RlbCBmb3IgYHByb2plY3RzL2FwaS9zcmMvbWFpbi50c2AuXG4gKlxuICogU3RhcnRzIHdpdGggdGhlIG1pbmltYWwgSFRUUCArIFlBTUwgY29uZmlnIHNldHVwLiBGZWF0dXJlcyBtdXRhdGUgdGhlIG1vZGVsXG4gKiBieSBjYWxsaW5nIGFkZFNpZGVFZmZlY3RJbXBvcnQgLyBhZGRJbXBvcnQgLyBhZGRCdWlsZGVyQ2FsbCAvIGFkZEVudGl0eSAvXG4gKiBhZGRSZXBvc2l0b3J5LiBmaWxlcygpIHJlbmRlcnMgd2hhdGV2ZXIgaGFzIGJlZW4gYWNjdW11bGF0ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBNYWluU291cmNlRmlsZSBpbXBsZW1lbnRzIEtleWVkTW9kZWwge1xuXHRwdWJsaWMgcmVhZG9ubHkga2V5ID0gV0VMTF9LTk9XTl9GSUxFUy5NQUlOX1RTO1xuXG5cdHByaXZhdGUgcmVhZG9ubHkgX3NpZGVFZmZlY3RJbXBvcnRzOiBzdHJpbmdbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9leHRyYUltcG9ydHMgPSBuZXcgTWFwPHN0cmluZywgSW1wb3J0R3JvdXA+KCk7XG5cdHByaXZhdGUgcmVhZG9ubHkgX2J1aWxkZXJDYWxsczogc3RyaW5nW10gPSBbXTtcblx0cHJpdmF0ZSByZWFkb25seSBfZW50aXRpZXM6IFR5cGVPcm1JbXBvcnRbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9yZXBvc2l0b3JpZXM6IFR5cGVPcm1JbXBvcnRbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9zZXJ2aWNlczogU2VydmljZUltcG9ydFtdID0gW107XG5cdHByaXZhdGUgX2RhdGFTb3VyY2VOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cdHByaXZhdGUgX3R5cGVPcm1TZWVkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgYXBwTmFtZTogc3RyaW5nKSB7fVxuXG5cdC8qKiBBZGRzIGEgYmFyZSBzaWRlLWVmZmVjdCBpbXBvcnQsIGUuZy4gYEBkZWNvaGVyZS9jb3J0ZXgvYXV0aGAuICovXG5cdHB1YmxpYyBhZGRTaWRlRWZmZWN0SW1wb3J0KHBhdGg6IHN0cmluZyk6IHRoaXMge1xuXHRcdGlmICghdGhpcy5fc2lkZUVmZmVjdEltcG9ydHMuaW5jbHVkZXMocGF0aCkpIHRoaXMuX3NpZGVFZmZlY3RJbXBvcnRzLnB1c2gocGF0aCk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKiogQWRkcyBhIG5hbWVkIGltcG9ydCwgZS5nLiBgaW1wb3J0IHsgRm9vIH0gZnJvbSBcImJhclwiYC4gKi9cblx0cHVibGljIGFkZEltcG9ydChuYW1lOiBzdHJpbmcsIGZyb206IHN0cmluZywgdHlwZU9ubHkgPSBmYWxzZSk6IHRoaXMge1xuXHRcdGNvbnN0IGdyb3VwID0gdGhpcy5fZXh0cmFJbXBvcnRzLmdldChmcm9tKSA/PyBuZXcgSW1wb3J0R3JvdXAoKTtcblx0XHRncm91cC5hZGQobmFtZSwgdHlwZU9ubHkpO1xuXHRcdHRoaXMuX2V4dHJhSW1wb3J0cy5zZXQoZnJvbSwgZ3JvdXApO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBidWlsZGVyIGNhbGwgaW5zZXJ0ZWQgYWZ0ZXIgYC53aXRoQ29uZmlndXJhdGlvbigpYCBhbmQgYmVmb3JlXG5cdCAqIGAud2l0aFNlcnZpY2VzKClgLiBQYXNzIHRoZSBjYWxsIHdpdGhvdXQgbGVhZGluZyBkb3QsIGUuZy4gYC53aXRoQXV0aCgpYC5cblx0ICovXG5cdHB1YmxpYyBhZGRCdWlsZGVyQ2FsbChjYWxsOiBzdHJpbmcpOiB0aGlzIHtcblx0XHR0aGlzLl9idWlsZGVyQ2FsbHMucHVzaChjYWxsKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKiBBZGRzIGEgVHlwZU9STSBlbnRpdHkg4oCUIGltcG9ydCBhbmQgZW50cnkgaW4gYHdpdGhUeXBlT3JtKHsgZW50aXRpZXMgfSlgLiAqL1xuXHRwdWJsaWMgYWRkRW50aXR5KGVudGl0eTogVHlwZU9ybUltcG9ydCk6IHRoaXMge1xuXHRcdHRoaXMuX2VudGl0aWVzLnB1c2goZW50aXR5KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKiBBZGRzIGEgVHlwZU9STSByZXBvc2l0b3J5IOKAlCBpbXBvcnQgYW5kIGVudHJ5IGluIGB3aXRoVHlwZU9ybSh7IHJlcG9zaXRvcmllcyB9KWAuICovXG5cdHB1YmxpYyBhZGRSZXBvc2l0b3J5KHJlcG86IFR5cGVPcm1JbXBvcnQpOiB0aGlzIHtcblx0XHR0aGlzLl9yZXBvc2l0b3JpZXMucHVzaChyZXBvKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKiBBZGRzIGEgc2VydmljZSByZWdpc3RlcmVkIGluIGAud2l0aFNlcnZpY2VzKClgLiAqL1xuXHRwdWJsaWMgYWRkU2VydmljZShzZXJ2aWNlOiBTZXJ2aWNlSW1wb3J0KTogdGhpcyB7XG5cdFx0dGhpcy5fc2VydmljZXMucHVzaChzZXJ2aWNlKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBEYXRhc291cmNlIG5hbWUgcGFzc2VkIHRvIGB3aXRoVHlwZU9ybSh7IG5hbWUgfSlgLiBNdXN0IG1hdGNoXG5cdCAqIGBkYXRhYmFzZS5kYXRhU291cmNlc1tdLm5hbWVgIGluIGNvbmZpZy55YW1sLlxuXHQgKi9cblx0cHVibGljIHNldERhdGFTb3VyY2VOYW1lKG5hbWU6IHN0cmluZyk6IHRoaXMge1xuXHRcdHRoaXMuX2RhdGFTb3VyY2VOYW1lID0gbmFtZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKlxuXHQgKiBJbmxpbmUgc2VlZCBjYWxsYmFjayBib2R5IGZvciBgd2l0aFR5cGVPcm0oeyBzZWVkIH0pYC5cblx0ICogUmVjZWl2ZXMgYGRhdGFTb3VyY2VgIGluIHNjb3BlLiBFeGFtcGxlOiBgYXdhaXQgZGF0YVNvdXJjZS5nZXRSZXBvc2l0b3J5KFVzZXIpLnNhdmUoLi4uKWAuXG5cdCAqL1xuXHRwdWJsaWMgc2V0VHlwZU9ybVNlZWQoc2VlZEJvZHk6IHN0cmluZyk6IHRoaXMge1xuXHRcdHRoaXMuX3R5cGVPcm1TZWVkID0gc2VlZEJvZHk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgZmlsZXMoKTogU291cmNlRmlsZVtdIHtcblx0XHRjb25zdCBpbXBvcnRzOiBzdHJpbmdbXSA9IFtcblx0XHRcdCdpbXBvcnQgXCJAZGVjb2hlcmUvc2NyaWJlLXBpbm9cIjsnLFxuXHRcdFx0J2ltcG9ydCBcIkBkZWNvaGVyZS9jb3J0ZXgvaHR0cFwiOycsXG5cdFx0XTtcblxuXHRcdGZvciAoY29uc3QgcGF0aCBvZiB0aGlzLl9zaWRlRWZmZWN0SW1wb3J0cykge1xuXHRcdFx0aW1wb3J0cy5wdXNoKGBpbXBvcnQgXCIke3BhdGh9XCI7YCk7XG5cdFx0fVxuXG5cdFx0aW1wb3J0cy5wdXNoKFxuXHRcdFx0J2ltcG9ydCBcIkBkZWNvaGVyZS9wcm90b2NvbFwiOycsXG5cdFx0XHQnaW1wb3J0IHsgWWFtbERhdGFTb3VyY2UgfSBmcm9tIFwiQGRlY29oZXJlL3Byb3RvY29sXCI7Jyxcblx0XHRcdCdpbXBvcnQgeyBCdWlsZGVyIH0gZnJvbSBcIkBkZWNvaGVyZS9jb3J0ZXhcIjsnLFxuXHRcdFx0J2ltcG9ydCB7IEZhc3RpZnlQcm92aWRlciB9IGZyb20gXCJAZGVjb2hlcmUvY29ydGV4L3Byb3ZpZGVyc1wiOycsXG5cdFx0XHQnaW1wb3J0IHsgc2NyaWJlIH0gZnJvbSBcIkBkZWNvaGVyZS9zY3JpYmVcIjsnLFxuXHRcdFx0J2ltcG9ydCB7IFNhbXBsZVNlcnZpY2UgfSBmcm9tIFwiLi9zZXJ2aWNlcy9zYW1wbGUuc2VydmljZS5qc1wiOycsXG5cdFx0KTtcblxuXHRcdGZvciAoY29uc3QgZSBvZiB0aGlzLl9lbnRpdGllcykge1xuXHRcdFx0aW1wb3J0cy5wdXNoKGBpbXBvcnQgeyAke2UuY2xhc3NOYW1lfSB9IGZyb20gXCIke2UuaW1wb3J0UGF0aH1cIjtgKTtcblx0XHR9XG5cblx0XHRmb3IgKGNvbnN0IHIgb2YgdGhpcy5fcmVwb3NpdG9yaWVzKSB7XG5cdFx0XHRpbXBvcnRzLnB1c2goYGltcG9ydCB7ICR7ci5jbGFzc05hbWV9IH0gZnJvbSBcIiR7ci5pbXBvcnRQYXRofVwiO2ApO1xuXHRcdH1cblxuXHRcdGZvciAoY29uc3QgcyBvZiB0aGlzLl9zZXJ2aWNlcykge1xuXHRcdFx0aW1wb3J0cy5wdXNoKGBpbXBvcnQgeyAke3MuY2xhc3NOYW1lfSB9IGZyb20gXCIke3MuaW1wb3J0UGF0aH1cIjtgKTtcblx0XHR9XG5cblx0XHRmb3IgKGNvbnN0IFtmcm9tLCBncm91cF0gb2YgdGhpcy5fZXh0cmFJbXBvcnRzKSB7XG5cdFx0XHRpbXBvcnRzLnB1c2goZ3JvdXAucmVuZGVyKGZyb20pKTtcblx0XHR9XG5cblx0XHRpbXBvcnRzLnB1c2goJ2ltcG9ydCB7IEhlbGxvQ29udHJvbGxlciB9IGZyb20gXCIuL2NvbnRyb2xsZXJzL2hlbGxvLmNvbnRyb2xsZXIuanNcIjsnKTtcblxuXHRcdGNvbnN0IHNlcnZpY2VSZWdzID0gW1xuXHRcdFx0XCJjYi5yZWdpc3RlclNpbmdsZXRvbihTYW1wbGVTZXJ2aWNlKTtcIixcblx0XHRcdC4uLnRoaXMuX3NlcnZpY2VzLm1hcCgocykgPT5cblx0XHRcdFx0cy5zY29wZSA9PT0gXCJyZXF1ZXN0XCJcblx0XHRcdFx0XHQ/IGBjYi5yZWdpc3RlclJlcXVlc3RTY29wZWQoJHtzLmNsYXNzTmFtZX0pO2Bcblx0XHRcdFx0XHQ6IGBjYi5yZWdpc3RlclNpbmdsZXRvbigke3MuY2xhc3NOYW1lfSk7YCxcblx0XHRcdCksXG5cdFx0XS5qb2luKFwiIFwiKTtcblxuXHRcdGNvbnN0IGJ1aWxkZXJDYWxsczogc3RyaW5nW10gPSBbXG5cdFx0XHRgXFx0LndpdGhIdHRwUHJvdmlkZXIoRmFzdGlmeVByb3ZpZGVyKWAsXG5cdFx0XHRgXFx0LndpdGhDb25maWd1cmF0aW9uKFlhbWxEYXRhU291cmNlKWAsXG5cdFx0XHQuLi50aGlzLl9idWlsZGVyQ2FsbHMubWFwKChjKSA9PiBgXFx0JHtjfWApLFxuXHRcdFx0YFxcdC53aXRoU2VydmljZXMoKGNiKSA9PiB7ICR7c2VydmljZVJlZ3N9IH0pYCxcblx0XHRdO1xuXG5cdFx0aWYgKHRoaXMuX2VudGl0aWVzLmxlbmd0aCA+IDApIHtcblx0XHRcdGNvbnN0IGVudGl0aWVzID0gdGhpcy5fZW50aXRpZXMubWFwKChlKSA9PiBlLmNsYXNzTmFtZSkuam9pbihcIiwgXCIpO1xuXHRcdFx0Y29uc3QgcmVwb3MgPSB0aGlzLl9yZXBvc2l0b3JpZXMubWFwKChyKSA9PiByLmNsYXNzTmFtZSkuam9pbihcIiwgXCIpO1xuXHRcdFx0Y29uc3QgbmFtZWQgPSB0aGlzLl9kYXRhU291cmNlTmFtZSAhPSBudWxsID8gYG5hbWU6IFwiJHt0aGlzLl9kYXRhU291cmNlTmFtZX1cIiwgYCA6IFwiXCI7XG5cdFx0XHRpZiAodGhpcy5fdHlwZU9ybVNlZWQpIHtcblx0XHRcdFx0YnVpbGRlckNhbGxzLnB1c2goXG5cdFx0XHRcdFx0YFxcdC53aXRoVHlwZU9ybSh7ICR7bmFtZWR9ZW50aXRpZXM6IFske2VudGl0aWVzfV0sIHJlcG9zaXRvcmllczogWyR7cmVwb3N9XSwgc2VlZDogYXN5bmMgKGRhdGFTb3VyY2UpID0+IHsgJHt0aGlzLl90eXBlT3JtU2VlZH0gfSB9KWAsXG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRidWlsZGVyQ2FsbHMucHVzaChcblx0XHRcdFx0XHRgXFx0LndpdGhUeXBlT3JtKHsgJHtuYW1lZH1lbnRpdGllczogWyR7ZW50aXRpZXN9XSwgcmVwb3NpdG9yaWVzOiBbJHtyZXBvc31dIH0pYCxcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRidWlsZGVyQ2FsbHMucHVzaChgXFx0LndpdGhDb250cm9sbGVycyhIZWxsb0NvbnRyb2xsZXIpYCk7XG5cblx0XHRjb25zdCBjb250ZW50ID0gW1xuXHRcdFx0Li4uaW1wb3J0cyxcblx0XHRcdFwiXCIsXG5cdFx0XHRcInNjcmliZS5leHRlbmQud2l0aFBpbm9QcmV0dHkoKTtcIixcblx0XHRcdFwiXCIsXG5cdFx0XHRgY29uc3QgYXBwID0gYXdhaXQgQnVpbGRlci5jcmVhdGUoeyBhcHBsaWNhdGlvbk5hbWU6IFwiJHt0aGlzLmFwcE5hbWV9XCIgfSlgLFxuXHRcdFx0Li4uYnVpbGRlckNhbGxzLFxuXHRcdFx0YFxcdC5idWlsZCgpO2AsXG5cdFx0XHRcIlwiLFxuXHRcdFx0XCJhd2FpdCBhcHAuc3RhcnQoeyBwb3J0OiBOdW1iZXIocHJvY2Vzcy5lbnYuUE9SVCkgfHwgMzAwMCB9KTtcIixcblx0XHRcdFwiXCIsXG5cdFx0XHRcImV4cG9ydCBkZWZhdWx0IGFwcDtcIixcblx0XHRcdFwiXCIsXG5cdFx0XS5qb2luKFwiXFxuXCIpO1xuXG5cdFx0cmV0dXJuIFtcblx0XHRcdHtcblx0XHRcdFx0ZmlsZVBhdGg6IFwic3JjL21haW4udHNcIixcblx0XHRcdFx0Y29udGVudCxcblx0XHRcdH0sXG5cdFx0XTtcblx0fVxufVxuIl0sIm5hbWVzIjpbIldFTExfS05PV05fRklMRVMiLCJJbXBvcnRHcm91cCIsIl92YWx1ZXMiLCJfdHlwZXMiLCJhZGQiLCJuYW1lIiwidHlwZU9ubHkiLCJpbmNsdWRlcyIsInB1c2giLCJ0eXBlSWR4IiwiaW5kZXhPZiIsInNwbGljZSIsInJlbmRlciIsImZyb20iLCJ2YWx1ZXMiLCJzb3J0IiwidHlwZXMiLCJtYXAiLCJuIiwiam9pbiIsIk1haW5Tb3VyY2VGaWxlIiwia2V5IiwiTUFJTl9UUyIsIl9zaWRlRWZmZWN0SW1wb3J0cyIsIl9leHRyYUltcG9ydHMiLCJNYXAiLCJfYnVpbGRlckNhbGxzIiwiX2VudGl0aWVzIiwiX3JlcG9zaXRvcmllcyIsIl9zZXJ2aWNlcyIsIl9kYXRhU291cmNlTmFtZSIsIl90eXBlT3JtU2VlZCIsImFwcE5hbWUiLCJhZGRTaWRlRWZmZWN0SW1wb3J0IiwicGF0aCIsImFkZEltcG9ydCIsImdyb3VwIiwiZ2V0Iiwic2V0IiwiYWRkQnVpbGRlckNhbGwiLCJjYWxsIiwiYWRkRW50aXR5IiwiZW50aXR5IiwiYWRkUmVwb3NpdG9yeSIsInJlcG8iLCJhZGRTZXJ2aWNlIiwic2VydmljZSIsInNldERhdGFTb3VyY2VOYW1lIiwic2V0VHlwZU9ybVNlZWQiLCJzZWVkQm9keSIsImZpbGVzIiwiaW1wb3J0cyIsImUiLCJjbGFzc05hbWUiLCJpbXBvcnRQYXRoIiwiciIsInMiLCJzZXJ2aWNlUmVncyIsInNjb3BlIiwiYnVpbGRlckNhbGxzIiwiYyIsImxlbmd0aCIsImVudGl0aWVzIiwicmVwb3MiLCJuYW1lZCIsImNvbnRlbnQiLCJmaWxlUGF0aCJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsZ0JBQWdCLFFBQVEsd0JBQXdCO0FBTXpELGlGQUFpRixHQUNqRixNQUFNQztJQUNZQyxVQUFvQixFQUFFLENBQUM7SUFDdkJDLFNBQW1CLEVBQUUsQ0FBQztJQUVoQ0Ms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
@@ -1,14 +1,57 @@
1
1
  import { WELL_KNOWN_FILES } from "../../models/const.js";
2
- import { WEBAPI_PROJECT_DIR, WEBAPI_RELEASE_ENTRY } from "../const.js";
2
+ import { DEFAULT_WEBAPI_NAME, webapiProjectDir, webapiReleaseEntry } from "../const.js";
3
3
  /**
4
- * Repo-root production Dockerfile for PaaS (Railway/Fly) and local `docker build`.
5
- * Runs conventional `pnpm run build` / `pnpm start` so Nixpacks and Docker share scripts.
4
+ * Production Dockerfiles for PaaS (Railway/Fly) and local `docker build`.
5
+ *
6
+ * Context is always the **repo root** (`docker build -f Dockerfile.billing .`).
7
+ * Root `Dockerfile` is the first API (`pnpm start`). Extra or custom-named APIs
8
+ * also get `Dockerfile.<name>` so each service can be deployed on its own.
6
9
  */ export class WebapiProductionDockerfile {
10
+ apiNames;
11
+ options;
7
12
  key = WELL_KNOWN_FILES.PRODUCTION_DOCKERFILE;
13
+ constructor(apiNames = [
14
+ DEFAULT_WEBAPI_NAME
15
+ ], options = {}){
16
+ this.apiNames = apiNames;
17
+ this.options = options;
18
+ }
8
19
  files() {
9
- const content = `# syntax=docker/dockerfile:1
20
+ const names = this.apiNames.length > 0 ? this.apiNames : [
21
+ DEFAULT_WEBAPI_NAME
22
+ ];
23
+ const first = names[0] ?? DEFAULT_WEBAPI_NAME;
24
+ const files = [];
25
+ if (!this.options.namedOnly) {
26
+ files.push({
27
+ filePath: ".dockerignore",
28
+ content: dockerignoreContent()
29
+ });
30
+ files.push({
31
+ filePath: "Dockerfile",
32
+ content: renderProductionDockerfile(first, "start")
33
+ });
34
+ }
35
+ const emitNamed = this.options.namedOnly || names.length > 1 || first !== DEFAULT_WEBAPI_NAME;
36
+ if (emitNamed) {
37
+ for (const name of names){
38
+ files.push({
39
+ filePath: `Dockerfile.${name}`,
40
+ content: renderProductionDockerfile(name, `start:${name}`)
41
+ });
42
+ }
43
+ }
44
+ return files;
45
+ }
46
+ }
47
+ export function renderProductionDockerfile(apiName, startScript) {
48
+ const projectDir = webapiProjectDir(apiName);
49
+ const startCmd = startScript === "start" ? 'CMD ["pnpm", "start"]' : `CMD ["pnpm", "run", "${startScript}"]`;
50
+ const startEntry = webapiReleaseEntry(apiName);
51
+ return `# syntax=docker/dockerfile:1
10
52
  # Self-contained production image: install + forge build happen inside docker build.
11
53
  # Hosts (Railway/Fly/etc.) clone git and run \`docker build\` — they do not receive CI dist/.
54
+ # Build from the repo root: docker build -f Dockerfile${startScript === "start" ? "" : `.${apiName}`} .
12
55
  #
13
56
  # Private @decohere/* packages: pass a BuildKit secret named npm_token (npm auth token), e.g.
14
57
  # docker build --secret id=npm_token,env=NODE_AUTH_TOKEN .
@@ -22,7 +65,7 @@ COPY package.json ./
22
65
  COPY pnpm-lock.yaml* ./
23
66
  COPY tsconfig.json biome.json ./
24
67
  COPY config ./config
25
- COPY ${WEBAPI_PROJECT_DIR} ./${WEBAPI_PROJECT_DIR}
68
+ COPY ${projectDir} ./${projectDir}
26
69
 
27
70
  ARG NODE_AUTH_TOKEN=
28
71
  RUN --mount=type=secret,id=npm_token,required=false \\
@@ -53,39 +96,31 @@ COPY --from=build /app/pnpm-lock.yaml* ./
53
96
  COPY --from=build /app/config ./config
54
97
  COPY --from=build /app/dist ./dist
55
98
  COPY --from=build /app/node_modules ./node_modules
56
- COPY --from=build /app/${WEBAPI_PROJECT_DIR}/package.json ./${WEBAPI_PROJECT_DIR}/package.json
99
+ COPY --from=build /app/${projectDir}/package.json ./${projectDir}/package.json
57
100
 
58
101
  EXPOSE 3000
59
- CMD ["pnpm", "start"]
60
- # Entry resolved by package.json "start" → node ${WEBAPI_RELEASE_ENTRY}
102
+ ${startCmd}
103
+ # Entry resolved by package.json "${startScript}" → node ${startEntry}
61
104
  `;
62
- return [
63
- {
64
- filePath: "Dockerfile",
65
- content
66
- },
67
- {
68
- filePath: ".dockerignore",
69
- content: [
70
- "node_modules",
71
- "dist",
72
- ".git",
73
- ".devcontainer",
74
- ".vscode",
75
- ".github",
76
- "postman",
77
- ".postman",
78
- ".env",
79
- ".env.*",
80
- "!.env.example",
81
- "coverage",
82
- "**/*.spec.ts",
83
- "**/*.test.ts",
84
- ""
85
- ].join("\n")
86
- }
87
- ];
88
- }
105
+ }
106
+ function dockerignoreContent() {
107
+ return [
108
+ "node_modules",
109
+ "dist",
110
+ ".git",
111
+ ".devcontainer",
112
+ ".vscode",
113
+ ".github",
114
+ "postman",
115
+ ".postman",
116
+ ".env",
117
+ ".env.*",
118
+ "!.env.example",
119
+ "coverage",
120
+ "**/*.spec.ts",
121
+ "**/*.test.ts",
122
+ ""
123
+ ].join("\n");
89
124
  }
90
125
 
91
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS9zcmMvd2ViYXBpL21vZGVscy9wcm9kdWN0aW9uLWRvY2tlcmZpbGUubW9kZWwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgV0VMTF9LTk9XTl9GSUxFUyB9IGZyb20gXCIuLi8uLi9tb2RlbHMvY29uc3QuanNcIjtcbmltcG9ydCB0eXBlIHsgS2V5ZWRNb2RlbCwgU291cmNlRmlsZSB9IGZyb20gXCIuLi8uLi9tb2RlbHMvc291cmNlLWZpbGUuanNcIjtcbmltcG9ydCB7IFdFQkFQSV9QUk9KRUNUX0RJUiwgV0VCQVBJX1JFTEVBU0VfRU5UUlkgfSBmcm9tIFwiLi4vY29uc3QuanNcIjtcblxuLyoqXG4gKiBSZXBvLXJvb3QgcHJvZHVjdGlvbiBEb2NrZXJmaWxlIGZvciBQYWFTIChSYWlsd2F5L0ZseSkgYW5kIGxvY2FsIGBkb2NrZXIgYnVpbGRgLlxuICogUnVucyBjb252ZW50aW9uYWwgYHBucG0gcnVuIGJ1aWxkYCAvIGBwbnBtIHN0YXJ0YCBzbyBOaXhwYWNrcyBhbmQgRG9ja2VyIHNoYXJlIHNjcmlwdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJhcGlQcm9kdWN0aW9uRG9ja2VyZmlsZSBpbXBsZW1lbnRzIEtleWVkTW9kZWwge1xuXHRwdWJsaWMgcmVhZG9ubHkga2V5ID0gV0VMTF9LTk9XTl9GSUxFUy5QUk9EVUNUSU9OX0RPQ0tFUkZJTEU7XG5cblx0cHVibGljIGZpbGVzKCk6IFNvdXJjZUZpbGVbXSB7XG5cdFx0Y29uc3QgY29udGVudCA9IGAjIHN5bnRheD1kb2NrZXIvZG9ja2VyZmlsZToxXG4jIFNlbGYtY29udGFpbmVkIHByb2R1Y3Rpb24gaW1hZ2U6IGluc3RhbGwgKyBmb3JnZSBidWlsZCBoYXBwZW4gaW5zaWRlIGRvY2tlciBidWlsZC5cbiMgSG9zdHMgKFJhaWx3YXkvRmx5L2V0Yy4pIGNsb25lIGdpdCBhbmQgcnVuIFxcYGRvY2tlciBidWlsZFxcYCDigJQgdGhleSBkbyBub3QgcmVjZWl2ZSBDSSBkaXN0Ly5cbiNcbiMgUHJpdmF0ZSBAZGVjb2hlcmUvKiBwYWNrYWdlczogcGFzcyBhIEJ1aWxkS2l0IHNlY3JldCBuYW1lZCBucG1fdG9rZW4gKG5wbSBhdXRoIHRva2VuKSwgZS5nLlxuIyAgIGRvY2tlciBidWlsZCAtLXNlY3JldCBpZD1ucG1fdG9rZW4sZW52PU5PREVfQVVUSF9UT0tFTiAuXG4jIE9yIHNldCBOT0RFX0FVVEhfVE9LRU4gYXMgYSBidWlsZC1hcmcgb24gaG9zdHMgdGhhdCBvbmx5IHN1cHBvcnQgYnVpbGQtYXJncy5cblxuRlJPTSBub2RlOjI0LWJvb2t3b3JtIEFTIGJ1aWxkXG5XT1JLRElSIC9hcHBcblJVTiBjb3JlcGFjayBlbmFibGUgJiYgY29yZXBhY2sgcHJlcGFyZSBwbnBtQDEwIC0tYWN0aXZhdGVcblxuQ09QWSBwYWNrYWdlLmpzb24gLi9cbkNPUFkgcG5wbS1sb2NrLnlhbWwqIC4vXG5DT1BZIHRzY29uZmlnLmpzb24gYmlvbWUuanNvbiAuL1xuQ09QWSBjb25maWcgLi9jb25maWdcbkNPUFkgJHtXRUJBUElfUFJPSkVDVF9ESVJ9IC4vJHtXRUJBUElfUFJPSkVDVF9ESVJ9XG5cbkFSRyBOT0RFX0FVVEhfVE9LRU49XG5SVU4gLS1tb3VudD10eXBlPXNlY3JldCxpZD1ucG1fdG9rZW4scmVxdWlyZWQ9ZmFsc2UgXFxcXFxuXHRpZiBbIC1mIC9ydW4vc2VjcmV0cy9ucG1fdG9rZW4gXTsgdGhlbiBcXFxcXG5cdFx0VE9LRU49XCIkKGNhdCAvcnVuL3NlY3JldHMvbnBtX3Rva2VuKVwiOyBcXFxcXG5cdGVsc2UgXFxcXFxuXHRcdFRPS0VOPVwiXFwke05PREVfQVVUSF9UT0tFTn1cIjsgXFxcXFxuXHRmaTsgXFxcXFxuXHRpZiBbIC1uIFwiJFRPS0VOXCIgXTsgdGhlbiBcXFxcXG5cdFx0ZWNobyBcIi8vcmVnaXN0cnkubnBtanMub3JnLzpfYXV0aFRva2VuPVxcJHtUT0tFTn1cIiA+IC5ucG1yYzsgXFxcXFxuXHRmaTsgXFxcXFxuXHRpZiBbIC1mIHBucG0tbG9jay55YW1sIF07IHRoZW4gXFxcXFxuXHRcdHBucG0gaW5zdGFsbCAtLWZyb3plbi1sb2NrZmlsZTsgXFxcXFxuXHRlbHNlIFxcXFxcblx0XHRwbnBtIGluc3RhbGw7IFxcXFxcblx0Zmk7IFxcXFxcblx0cm0gLWYgLm5wbXJjXG5cblJVTiBwbnBtIHJ1biBidWlsZFxuXG5GUk9NIG5vZGU6MjQtYm9va3dvcm0tc2xpbSBBUyBydW5cbldPUktESVIgL2FwcFxuRU5WIE5PREVfRU5WPXByb2R1Y3Rpb25cblJVTiBjb3JlcGFjayBlbmFibGUgJiYgY29yZXBhY2sgcHJlcGFyZSBwbnBtQDEwIC0tYWN0aXZhdGVcblxuQ09QWSAtLWZyb209YnVpbGQgL2FwcC9wYWNrYWdlLmpzb24gLi9cbkNPUFkgLS1mcm9tPWJ1aWxkIC9hcHAvcG5wbS1sb2NrLnlhbWwqIC4vXG5DT1BZIC0tZnJvbT1idWlsZCAvYXBwL2NvbmZpZyAuL2NvbmZpZ1xuQ09QWSAtLWZyb209YnVpbGQgL2FwcC9kaXN0IC4vZGlzdFxuQ09QWSAtLWZyb209YnVpbGQgL2FwcC9ub2RlX21vZHVsZXMgLi9ub2RlX21vZHVsZXNcbkNPUFkgLS1mcm9tPWJ1aWxkIC9hcHAvJHtXRUJBUElfUFJPSkVDVF9ESVJ9L3BhY2thZ2UuanNvbiAuLyR7V0VCQVBJX1BST0pFQ1RfRElSfS9wYWNrYWdlLmpzb25cblxuRVhQT1NFIDMwMDBcbkNNRCBbXCJwbnBtXCIsIFwic3RhcnRcIl1cbiMgRW50cnkgcmVzb2x2ZWQgYnkgcGFja2FnZS5qc29uIFwic3RhcnRcIiDihpIgbm9kZSAke1dFQkFQSV9SRUxFQVNFX0VOVFJZfVxuYDtcblxuXHRcdHJldHVybiBbXG5cdFx0XHR7XG5cdFx0XHRcdGZpbGVQYXRoOiBcIkRvY2tlcmZpbGVcIixcblx0XHRcdFx0Y29udGVudCxcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdGZpbGVQYXRoOiBcIi5kb2NrZXJpZ25vcmVcIixcblx0XHRcdFx0Y29udGVudDogW1xuXHRcdFx0XHRcdFwibm9kZV9tb2R1bGVzXCIsXG5cdFx0XHRcdFx0XCJkaXN0XCIsXG5cdFx0XHRcdFx0XCIuZ2l0XCIsXG5cdFx0XHRcdFx0XCIuZGV2Y29udGFpbmVyXCIsXG5cdFx0XHRcdFx0XCIudnNjb2RlXCIsXG5cdFx0XHRcdFx0XCIuZ2l0aHViXCIsXG5cdFx0XHRcdFx0XCJwb3N0bWFuXCIsXG5cdFx0XHRcdFx0XCIucG9zdG1hblwiLFxuXHRcdFx0XHRcdFwiLmVudlwiLFxuXHRcdFx0XHRcdFwiLmVudi4qXCIsXG5cdFx0XHRcdFx0XCIhLmVudi5leGFtcGxlXCIsXG5cdFx0XHRcdFx0XCJjb3ZlcmFnZVwiLFxuXHRcdFx0XHRcdFwiKiovKi5zcGVjLnRzXCIsXG5cdFx0XHRcdFx0XCIqKi8qLnRlc3QudHNcIixcblx0XHRcdFx0XHRcIlwiLFxuXHRcdFx0XHRdLmpvaW4oXCJcXG5cIiksXG5cdFx0XHR9LFxuXHRcdF07XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJXRUxMX0tOT1dOX0ZJTEVTIiwiV0VCQVBJX1BST0pFQ1RfRElSIiwiV0VCQVBJX1JFTEVBU0VfRU5UUlkiLCJXZWJhcGlQcm9kdWN0aW9uRG9ja2VyZmlsZSIsImtleSIsIlBST0RVQ1RJT05fRE9DS0VSRklMRSIsImZpbGVzIiwiY29udGVudCIsImZpbGVQYXRoIiwiam9pbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsZ0JBQWdCLFFBQVEsd0JBQXdCO0FBRXpELFNBQVNDLGtCQUFrQixFQUFFQyxvQkFBb0IsUUFBUSxjQUFjO0FBRXZFOzs7Q0FHQyxHQUNELE9BQU8sTUFBTUM7SUFDSUMsTUFBTUosaUJBQWlCSyxxQkFBcUIsQ0FBQztJQUV0REMsUUFBc0I7UUFDNUIsTUFBTUMsVUFBVSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7O0tBZ0JkLEVBQUVOLG1CQUFtQixHQUFHLEVBQUVBLG1CQUFtQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozt1QkErQjNCLEVBQUVBLG1CQUFtQixnQkFBZ0IsRUFBRUEsbUJBQW1COzs7O2dEQUlqQyxFQUFFQyxxQkFBcUI7QUFDdkUsQ0FBQztRQUVDLE9BQU87WUFDTjtnQkFDQ00sVUFBVTtnQkFDVkQ7WUFDRDtZQUNBO2dCQUNDQyxVQUFVO2dCQUNWRCxTQUFTO29CQUNSO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO29CQUNBO2lCQUNBLENBQUNFLElBQUksQ0FBQztZQUNSO1NBQ0E7SUFDRjtBQUNEIn0=
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS9zcmMvd2ViYXBpL21vZGVscy9wcm9kdWN0aW9uLWRvY2tlcmZpbGUubW9kZWwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgV0VMTF9LTk9XTl9GSUxFUyB9IGZyb20gXCIuLi8uLi9tb2RlbHMvY29uc3QuanNcIjtcbmltcG9ydCB0eXBlIHsgS2V5ZWRNb2RlbCwgU291cmNlRmlsZSB9IGZyb20gXCIuLi8uLi9tb2RlbHMvc291cmNlLWZpbGUuanNcIjtcbmltcG9ydCB7IERFRkFVTFRfV0VCQVBJX05BTUUsIHdlYmFwaVByb2plY3REaXIsIHdlYmFwaVJlbGVhc2VFbnRyeSB9IGZyb20gXCIuLi9jb25zdC5qc1wiO1xuXG5leHBvcnQgdHlwZSBQcm9kdWN0aW9uRG9ja2VyZmlsZU9wdGlvbnMgPSB7XG5cdC8qKiBXaGVuIHRydWUsIG9ubHkgd3JpdGUgYERvY2tlcmZpbGUuPG5hbWU+YCAoZXhpc3Rpbmcgd29ya3NwYWNlIOKAlCBkbyBub3QgcmVwbGFjZSByb290IERvY2tlcmZpbGUpLiAqL1xuXHRuYW1lZE9ubHk/OiBib29sZWFuO1xufTtcblxuLyoqXG4gKiBQcm9kdWN0aW9uIERvY2tlcmZpbGVzIGZvciBQYWFTIChSYWlsd2F5L0ZseSkgYW5kIGxvY2FsIGBkb2NrZXIgYnVpbGRgLlxuICpcbiAqIENvbnRleHQgaXMgYWx3YXlzIHRoZSAqKnJlcG8gcm9vdCoqIChgZG9ja2VyIGJ1aWxkIC1mIERvY2tlcmZpbGUuYmlsbGluZyAuYCkuXG4gKiBSb290IGBEb2NrZXJmaWxlYCBpcyB0aGUgZmlyc3QgQVBJIChgcG5wbSBzdGFydGApLiBFeHRyYSBvciBjdXN0b20tbmFtZWQgQVBJc1xuICogYWxzbyBnZXQgYERvY2tlcmZpbGUuPG5hbWU+YCBzbyBlYWNoIHNlcnZpY2UgY2FuIGJlIGRlcGxveWVkIG9uIGl0cyBvd24uXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJhcGlQcm9kdWN0aW9uRG9ja2VyZmlsZSBpbXBsZW1lbnRzIEtleWVkTW9kZWwge1xuXHRwdWJsaWMgcmVhZG9ubHkga2V5ID0gV0VMTF9LTk9XTl9GSUxFUy5QUk9EVUNUSU9OX0RPQ0tFUkZJTEU7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKFxuXHRcdHByaXZhdGUgcmVhZG9ubHkgYXBpTmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdID0gW0RFRkFVTFRfV0VCQVBJX05BTUVdLFxuXHRcdHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogUHJvZHVjdGlvbkRvY2tlcmZpbGVPcHRpb25zID0ge30sXG5cdCkge31cblxuXHRwdWJsaWMgZmlsZXMoKTogU291cmNlRmlsZVtdIHtcblx0XHRjb25zdCBuYW1lcyA9IHRoaXMuYXBpTmFtZXMubGVuZ3RoID4gMCA/IHRoaXMuYXBpTmFtZXMgOiBbREVGQVVMVF9XRUJBUElfTkFNRV07XG5cdFx0Y29uc3QgZmlyc3QgPSBuYW1lc1swXSA/PyBERUZBVUxUX1dFQkFQSV9OQU1FO1xuXHRcdGNvbnN0IGZpbGVzOiBTb3VyY2VGaWxlW10gPSBbXTtcblxuXHRcdGlmICghdGhpcy5vcHRpb25zLm5hbWVkT25seSkge1xuXHRcdFx0ZmlsZXMucHVzaCh7XG5cdFx0XHRcdGZpbGVQYXRoOiBcIi5kb2NrZXJpZ25vcmVcIixcblx0XHRcdFx0Y29udGVudDogZG9ja2VyaWdub3JlQ29udGVudCgpLFxuXHRcdFx0fSk7XG5cdFx0XHRmaWxlcy5wdXNoKHtcblx0XHRcdFx0ZmlsZVBhdGg6IFwiRG9ja2VyZmlsZVwiLFxuXHRcdFx0XHRjb250ZW50OiByZW5kZXJQcm9kdWN0aW9uRG9ja2VyZmlsZShmaXJzdCwgXCJzdGFydFwiKSxcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGNvbnN0IGVtaXROYW1lZCA9XG5cdFx0XHR0aGlzLm9wdGlvbnMubmFtZWRPbmx5IHx8IG5hbWVzLmxlbmd0aCA+IDEgfHwgZmlyc3QgIT09IERFRkFVTFRfV0VCQVBJX05BTUU7XG5cdFx0aWYgKGVtaXROYW1lZCkge1xuXHRcdFx0Zm9yIChjb25zdCBuYW1lIG9mIG5hbWVzKSB7XG5cdFx0XHRcdGZpbGVzLnB1c2goe1xuXHRcdFx0XHRcdGZpbGVQYXRoOiBgRG9ja2VyZmlsZS4ke25hbWV9YCxcblx0XHRcdFx0XHRjb250ZW50OiByZW5kZXJQcm9kdWN0aW9uRG9ja2VyZmlsZShuYW1lLCBgc3RhcnQ6JHtuYW1lfWApLFxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmlsZXM7XG5cdH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlclByb2R1Y3Rpb25Eb2NrZXJmaWxlKGFwaU5hbWU6IHN0cmluZywgc3RhcnRTY3JpcHQ6IHN0cmluZyk6IHN0cmluZyB7XG5cdGNvbnN0IHByb2plY3REaXIgPSB3ZWJhcGlQcm9qZWN0RGlyKGFwaU5hbWUpO1xuXHRjb25zdCBzdGFydENtZCA9XG5cdFx0c3RhcnRTY3JpcHQgPT09IFwic3RhcnRcIlxuXHRcdFx0PyAnQ01EIFtcInBucG1cIiwgXCJzdGFydFwiXSdcblx0XHRcdDogYENNRCBbXCJwbnBtXCIsIFwicnVuXCIsIFwiJHtzdGFydFNjcmlwdH1cIl1gO1xuXHRjb25zdCBzdGFydEVudHJ5ID0gd2ViYXBpUmVsZWFzZUVudHJ5KGFwaU5hbWUpO1xuXG5cdHJldHVybiBgIyBzeW50YXg9ZG9ja2VyL2RvY2tlcmZpbGU6MVxuIyBTZWxmLWNvbnRhaW5lZCBwcm9kdWN0aW9uIGltYWdlOiBpbnN0YWxsICsgZm9yZ2UgYnVpbGQgaGFwcGVuIGluc2lkZSBkb2NrZXIgYnVpbGQuXG4jIEhvc3RzIChSYWlsd2F5L0ZseS9ldGMuKSBjbG9uZSBnaXQgYW5kIHJ1biBcXGBkb2NrZXIgYnVpbGRcXGAg4oCUIHRoZXkgZG8gbm90IHJlY2VpdmUgQ0kgZGlzdC8uXG4jIEJ1aWxkIGZyb20gdGhlIHJlcG8gcm9vdDogZG9ja2VyIGJ1aWxkIC1mIERvY2tlcmZpbGUke3N0YXJ0U2NyaXB0ID09PSBcInN0YXJ0XCIgPyBcIlwiIDogYC4ke2FwaU5hbWV9YH0gLlxuI1xuIyBQcml2YXRlIEBkZWNvaGVyZS8qIHBhY2thZ2VzOiBwYXNzIGEgQnVpbGRLaXQgc2VjcmV0IG5hbWVkIG5wbV90b2tlbiAobnBtIGF1dGggdG9rZW4pLCBlLmcuXG4jICAgZG9ja2VyIGJ1aWxkIC0tc2VjcmV0IGlkPW5wbV90b2tlbixlbnY9Tk9ERV9BVVRIX1RPS0VOIC5cbiMgT3Igc2V0IE5PREVfQVVUSF9UT0tFTiBhcyBhIGJ1aWxkLWFyZyBvbiBob3N0cyB0aGF0IG9ubHkgc3VwcG9ydCBidWlsZC1hcmdzLlxuXG5GUk9NIG5vZGU6MjQtYm9va3dvcm0gQVMgYnVpbGRcbldPUktESVIgL2FwcFxuUlVOIGNvcmVwYWNrIGVuYWJsZSAmJiBjb3JlcGFjayBwcmVwYXJlIHBucG1AMTAgLS1hY3RpdmF0ZVxuXG5DT1BZIHBhY2thZ2UuanNvbiAuL1xuQ09QWSBwbnBtLWxvY2sueWFtbCogLi9cbkNPUFkgdHNjb25maWcuanNvbiBiaW9tZS5qc29uIC4vXG5DT1BZIGNvbmZpZyAuL2NvbmZpZ1xuQ09QWSAke3Byb2plY3REaXJ9IC4vJHtwcm9qZWN0RGlyfVxuXG5BUkcgTk9ERV9BVVRIX1RPS0VOPVxuUlVOIC0tbW91bnQ9dHlwZT1zZWNyZXQsaWQ9bnBtX3Rva2VuLHJlcXVpcmVkPWZhbHNlIFxcXFxcblx0aWYgWyAtZiAvcnVuL3NlY3JldHMvbnBtX3Rva2VuIF07IHRoZW4gXFxcXFxuXHRcdFRPS0VOPVwiJChjYXQgL3J1bi9zZWNyZXRzL25wbV90b2tlbilcIjsgXFxcXFxuXHRlbHNlIFxcXFxcblx0XHRUT0tFTj1cIlxcJHtOT0RFX0FVVEhfVE9LRU59XCI7IFxcXFxcblx0Zmk7IFxcXFxcblx0aWYgWyAtbiBcIiRUT0tFTlwiIF07IHRoZW4gXFxcXFxuXHRcdGVjaG8gXCIvL3JlZ2lzdHJ5Lm5wbWpzLm9yZy86X2F1dGhUb2tlbj1cXCR7VE9LRU59XCIgPiAubnBtcmM7IFxcXFxcblx0Zmk7IFxcXFxcblx0aWYgWyAtZiBwbnBtLWxvY2sueWFtbCBdOyB0aGVuIFxcXFxcblx0XHRwbnBtIGluc3RhbGwgLS1mcm96ZW4tbG9ja2ZpbGU7IFxcXFxcblx0ZWxzZSBcXFxcXG5cdFx0cG5wbSBpbnN0YWxsOyBcXFxcXG5cdGZpOyBcXFxcXG5cdHJtIC1mIC5ucG1yY1xuXG5SVU4gcG5wbSBydW4gYnVpbGRcblxuRlJPTSBub2RlOjI0LWJvb2t3b3JtLXNsaW0gQVMgcnVuXG5XT1JLRElSIC9hcHBcbkVOViBOT0RFX0VOVj1wcm9kdWN0aW9uXG5SVU4gY29yZXBhY2sgZW5hYmxlICYmIGNvcmVwYWNrIHByZXBhcmUgcG5wbUAxMCAtLWFjdGl2YXRlXG5cbkNPUFkgLS1mcm9tPWJ1aWxkIC9hcHAvcGFja2FnZS5qc29uIC4vXG5DT1BZIC0tZnJvbT1idWlsZCAvYXBwL3BucG0tbG9jay55YW1sKiAuL1xuQ09QWSAtLWZyb209YnVpbGQgL2FwcC9jb25maWcgLi9jb25maWdcbkNPUFkgLS1mcm9tPWJ1aWxkIC9hcHAvZGlzdCAuL2Rpc3RcbkNPUFkgLS1mcm9tPWJ1aWxkIC9hcHAvbm9kZV9tb2R1bGVzIC4vbm9kZV9tb2R1bGVzXG5DT1BZIC0tZnJvbT1idWlsZCAvYXBwLyR7cHJvamVjdERpcn0vcGFja2FnZS5qc29uIC4vJHtwcm9qZWN0RGlyfS9wYWNrYWdlLmpzb25cblxuRVhQT1NFIDMwMDBcbiR7c3RhcnRDbWR9XG4jIEVudHJ5IHJlc29sdmVkIGJ5IHBhY2thZ2UuanNvbiBcIiR7c3RhcnRTY3JpcHR9XCIg4oaSIG5vZGUgJHtzdGFydEVudHJ5fVxuYDtcbn1cblxuZnVuY3Rpb24gZG9ja2VyaWdub3JlQ29udGVudCgpOiBzdHJpbmcge1xuXHRyZXR1cm4gW1xuXHRcdFwibm9kZV9tb2R1bGVzXCIsXG5cdFx0XCJkaXN0XCIsXG5cdFx0XCIuZ2l0XCIsXG5cdFx0XCIuZGV2Y29udGFpbmVyXCIsXG5cdFx0XCIudnNjb2RlXCIsXG5cdFx0XCIuZ2l0aHViXCIsXG5cdFx0XCJwb3N0bWFuXCIsXG5cdFx0XCIucG9zdG1hblwiLFxuXHRcdFwiLmVudlwiLFxuXHRcdFwiLmVudi4qXCIsXG5cdFx0XCIhLmVudi5leGFtcGxlXCIsXG5cdFx0XCJjb3ZlcmFnZVwiLFxuXHRcdFwiKiovKi5zcGVjLnRzXCIsXG5cdFx0XCIqKi8qLnRlc3QudHNcIixcblx0XHRcIlwiLFxuXHRdLmpvaW4oXCJcXG5cIik7XG59XG4iXSwibmFtZXMiOlsiV0VMTF9LTk9XTl9GSUxFUyIsIkRFRkFVTFRfV0VCQVBJX05BTUUiLCJ3ZWJhcGlQcm9qZWN0RGlyIiwid2ViYXBpUmVsZWFzZUVudHJ5IiwiV2ViYXBpUHJvZHVjdGlvbkRvY2tlcmZpbGUiLCJrZXkiLCJQUk9EVUNUSU9OX0RPQ0tFUkZJTEUiLCJhcGlOYW1lcyIsIm9wdGlvbnMiLCJmaWxlcyIsIm5hbWVzIiwibGVuZ3RoIiwiZmlyc3QiLCJuYW1lZE9ubHkiLCJwdXNoIiwiZmlsZVBhdGgiLCJjb250ZW50IiwiZG9ja2VyaWdub3JlQ29udGVudCIsInJlbmRlclByb2R1Y3Rpb25Eb2NrZXJmaWxlIiwiZW1pdE5hbWVkIiwibmFtZSIsImFwaU5hbWUiLCJzdGFydFNjcmlwdCIsInByb2plY3REaXIiLCJzdGFydENtZCIsInN0YXJ0RW50cnkiLCJqb2luIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxnQkFBZ0IsUUFBUSx3QkFBd0I7QUFFekQsU0FBU0MsbUJBQW1CLEVBQUVDLGdCQUFnQixFQUFFQyxrQkFBa0IsUUFBUSxjQUFjO0FBT3hGOzs7Ozs7Q0FNQyxHQUNELE9BQU8sTUFBTUM7OztJQUNJQyxNQUFNTCxpQkFBaUJNLHFCQUFxQixDQUFDO0lBRTdELFlBQ0MsQUFBaUJDLFdBQThCO1FBQUNOO0tBQW9CLEVBQ3BFLEFBQWlCTyxVQUF1QyxDQUFDLENBQUMsQ0FDekQ7YUFGZ0JELFdBQUFBO2FBQ0FDLFVBQUFBO0lBQ2Y7SUFFSUMsUUFBc0I7UUFDNUIsTUFBTUMsUUFBUSxJQUFJLENBQUNILFFBQVEsQ0FBQ0ksTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDSixRQUFRLEdBQUc7WUFBQ047U0FBb0I7UUFDOUUsTUFBTVcsUUFBUUYsS0FBSyxDQUFDLEVBQUUsSUFBSVQ7UUFDMUIsTUFBTVEsUUFBc0IsRUFBRTtRQUU5QixJQUFJLENBQUMsSUFBSSxDQUFDRCxPQUFPLENBQUNLLFNBQVMsRUFBRTtZQUM1QkosTUFBTUssSUFBSSxDQUFDO2dCQUNWQyxVQUFVO2dCQUNWQyxTQUFTQztZQUNWO1lBQ0FSLE1BQU1LLElBQUksQ0FBQztnQkFDVkMsVUFBVTtnQkFDVkMsU0FBU0UsMkJBQTJCTixPQUFPO1lBQzVDO1FBQ0Q7UUFFQSxNQUFNTyxZQUNMLElBQUksQ0FBQ1gsT0FBTyxDQUFDSyxTQUFTLElBQUlILE1BQU1DLE1BQU0sR0FBRyxLQUFLQyxVQUFVWDtRQUN6RCxJQUFJa0IsV0FBVztZQUNkLEtBQUssTUFBTUMsUUFBUVYsTUFBTztnQkFDekJELE1BQU1LLElBQUksQ0FBQztvQkFDVkMsVUFBVSxDQUFDLFdBQVcsRUFBRUssTUFBTTtvQkFDOUJKLFNBQVNFLDJCQUEyQkUsTUFBTSxDQUFDLE1BQU0sRUFBRUEsTUFBTTtnQkFDMUQ7WUFDRDtRQUNEO1FBRUEsT0FBT1g7SUFDUjtBQUNEO0FBRUEsT0FBTyxTQUFTUywyQkFBMkJHLE9BQWUsRUFBRUMsV0FBbUI7SUFDOUUsTUFBTUMsYUFBYXJCLGlCQUFpQm1CO0lBQ3BDLE1BQU1HLFdBQ0xGLGdCQUFnQixVQUNiLDBCQUNBLENBQUMscUJBQXFCLEVBQUVBLFlBQVksRUFBRSxDQUFDO0lBQzNDLE1BQU1HLGFBQWF0QixtQkFBbUJrQjtJQUV0QyxPQUFPLENBQUM7OztzREFHNkMsRUFBRUMsZ0JBQWdCLFVBQVUsS0FBSyxDQUFDLENBQUMsRUFBRUQsU0FBUyxDQUFDOzs7Ozs7Ozs7Ozs7OztLQWNoRyxFQUFFRSxXQUFXLEdBQUcsRUFBRUEsV0FBVzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozt1QkErQlgsRUFBRUEsV0FBVyxnQkFBZ0IsRUFBRUEsV0FBVzs7O0FBR2pFLEVBQUVDLFNBQVM7a0NBQ3VCLEVBQUVGLFlBQVksU0FBUyxFQUFFRyxXQUFXO0FBQ3RFLENBQUM7QUFDRDtBQUVBLFNBQVNSO0lBQ1IsT0FBTztRQUNOO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtLQUNBLENBQUNTLElBQUksQ0FBQztBQUNSIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decohere/create",
3
- "version": "0.0.1-dev.43",
3
+ "version": "0.0.1-dev.44",
4
4
  "description": "Scaffold a new Decohere project — build with Forge, serve with Flux",
5
5
  "keywords": [
6
6
  "decohere",
@@ -21,7 +21,7 @@
21
21
  "test": "echo \"Error: no test specified\" && exit 1"
22
22
  },
23
23
  "dependencies": {
24
- "@decohere/nexus": "0.0.1-dev.43",
24
+ "@decohere/nexus": "0.0.1-dev.44",
25
25
  "commander": "^13.1.0",
26
26
  "openapi-to-postmanv2": "^5.0.0"
27
27
  },
@@ -12,5 +12,16 @@ export declare class ConfigYaml implements KeyedModel {
12
12
  private readonly _sections;
13
13
  constructor(key: string, filePath: string, baseContent: string);
14
14
  addSection(yaml: string): this;
15
+ /** True when a datasource with this `name:` already appears in the file. */
16
+ hasDataSource(name: string): boolean;
17
+ hasDataSources(): boolean;
18
+ /**
19
+ * Insert a `dataSources` list item. Used by `webapi add` so we do not write a
20
+ * second top-level `database:` key (YAML last-key-wins).
21
+ */
22
+ appendDataSource(item: string): this;
23
+ static fromFile(key: string, relativePath: string, absolutePath: string): ConfigYaml;
15
24
  files(): SourceFile[];
16
25
  }
26
+ /** Insert a YAML list item under `dataSources:`; append a new `database:` block if missing. */
27
+ export declare function injectYamlDataSource(yaml: string, item: string): string;
@@ -10,5 +10,6 @@ export declare class EnvFile implements KeyedModel {
10
10
  readonly key: string;
11
11
  private readonly _entries;
12
12
  addEntry(key: string, value: string): this;
13
+ static fromFile(absolutePath: string): EnvFile;
13
14
  files(): SourceFile[];
14
15
  }
@@ -1,5 +1,7 @@
1
1
  import type { KeyedModel, SourceFile } from "./source-file.js";
2
2
  export declare class LaunchJson implements KeyedModel {
3
+ private readonly apiNames;
3
4
  readonly key: string;
5
+ constructor(apiNames?: readonly string[]);
4
6
  files(): SourceFile[];
5
7
  }
@@ -1,4 +1,11 @@
1
1
  import type { KeyedModel, SourceFile } from "./source-file.js";
2
+ export type PackageJsonOptions = {
3
+ startEntry?: string;
4
+ /** API slugs in this workspace. Drives `start:<name>` / `dev:<name>`. */
5
+ apiNames?: readonly string[];
6
+ /** Host workspace name used in `@<workspace>/<api>` for flux `--project`. */
7
+ workspaceName?: string;
8
+ };
2
9
  /**
3
10
  * Builder for the root `package.json`.
4
11
  *
@@ -9,12 +16,15 @@ import type { KeyedModel, SourceFile } from "./source-file.js";
9
16
  export declare class PackageJson implements KeyedModel {
10
17
  private readonly name;
11
18
  readonly key: string;
12
- private readonly _dependencies;
13
- private readonly _devDependencies;
14
- private readonly _scripts;
15
- constructor(name: string, options?: {
16
- startEntry?: string;
17
- });
19
+ private _dependencies;
20
+ private _devDependencies;
21
+ private _scripts;
22
+ private _version;
23
+ private _type;
24
+ private _rest;
25
+ constructor(name: string, options?: PackageJsonOptions);
26
+ /** Load an existing root package.json so `webapi add` can merge scripts/deps. */
27
+ static fromFile(filePath: string): PackageJson;
18
28
  addDependency(name: string, version: string): this;
19
29
  addDevDependency(name: string, version: string): this;
20
30
  addScript(name: string, command: string): this;
@@ -31,6 +31,7 @@ export declare abstract class WorkspaceScaffold {
31
31
  abstract getModel<T extends SourceFileProvider>(key: string): T | undefined;
32
32
  abstract getModels<T extends SourceFileProvider>(ctor: new (...args: never[]) => T): T[];
33
33
  abstract getProject(dir: string): ProjectScaffold | undefined;
34
+ abstract getProjects(): readonly ProjectScaffold[];
34
35
  abstract scaffold(): Promise<void> | void;
35
36
  }
36
37
  export declare class MonoRepoScaffold extends WorkspaceScaffold {
@@ -40,6 +41,8 @@ export declare class MonoRepoScaffold extends WorkspaceScaffold {
40
41
  addProject(project: ProjectScaffold): ProjectScaffold;
41
42
  /** Retrieve a previously-registered project by its directory path. */
42
43
  getProject(dir: string): ProjectScaffold | undefined;
44
+ /** All registered projects, in registration order. */
45
+ getProjects(): readonly ProjectScaffold[];
43
46
  /** Register a named model at workspace level. */
44
47
  addModel<T extends KeyedModel>(model: T): T;
45
48
  /**
@@ -0,0 +1,14 @@
1
+ /** Lowercase npm-safe directory slug: `billing`, `admin-api`. */
2
+ export declare const API_NAME_PATTERN: RegExp;
3
+ export declare class CreateCliError extends Error {
4
+ constructor(message: string);
5
+ }
6
+ export declare function assertValidApiName(name: string): void;
7
+ /** Default `["api"]` when the caller omitted `--name`. Rejects duplicates and invalid slugs. */
8
+ export declare function parseApiNames(raw: readonly string[] | undefined): string[];
9
+ export declare function isDecohereWorkspace(dir: string): boolean;
10
+ /** Directory names under `projects/` that already have a `package.json`. */
11
+ export declare function listExistingApiNames(dir: string): string[];
12
+ /** `billing` → `BILLING`, `admin-api` → `ADMIN_API` — prefix for `{PREFIX}_DB_HOST`. */
13
+ export declare function apiEnvPrefix(apiName: string): string;
14
+ export declare function apiNameFromProjectDir(dir: string): string;
@@ -1,7 +1,17 @@
1
- /** Relative path of the scaffolded API project inside the monorepo. */
2
- export declare const WEBAPI_PROJECT_DIR = "projects/api";
1
+ /** Default API project slug when `--name` is omitted. */
2
+ export declare const DEFAULT_WEBAPI_NAME = "api";
3
+ /** Relative path of an API project inside the monorepo. */
4
+ export declare function webapiProjectDir(name: string): string;
3
5
  /**
4
- * Forge release entry for the scaffolded API (`pack: true` → per-target outDir).
5
- * Keep in sync with root `package.json` `"start"` and the production Dockerfile.
6
+ * Forge release entry for a scaffolded API (`pack: true` → per-target outDir).
7
+ * Keep in sync with root `package.json` `"start"` / `"start:<name>"` and Dockerfiles.
6
8
  */
7
- export declare const WEBAPI_RELEASE_ENTRY = "dist/release/projects/api/es6/src/main.js";
9
+ export declare function webapiReleaseEntry(name: string): string;
10
+ /** npm package name for a scaffolded API (`flux serve --project`). */
11
+ export declare function webapiPackageName(workspaceName: string, apiName: string): string;
12
+ /** Local listen port for the nth API (0-based). Production uses `PORT`. */
13
+ export declare function webapiPort(index: number): number;
14
+ /** @deprecated Use `webapiProjectDir(name)`. Default path for the first API. */
15
+ export declare const WEBAPI_PROJECT_DIR: string;
16
+ /** @deprecated Use `webapiReleaseEntry(name)`. Default start entry for the first API. */
17
+ export declare const WEBAPI_RELEASE_ENTRY: string;
@@ -3,6 +3,10 @@ export type ApiOptions = {
3
3
  d?: string;
4
4
  /** Host project name (directory basename). Required when scaffolding into `/workspace`. */
5
5
  projectName?: string;
6
+ /** API slugs under `projects/`. Default `["api"]`. Repeatable `--name`. */
7
+ names?: string[];
8
+ /** Add APIs to an existing Decohere workspace instead of creating a new one. */
9
+ add?: boolean;
6
10
  authProvider?: "auth0" | "none";
7
11
  databaseProvider?: "none" | "postgres/typeorm";
8
12
  postmanProvider?: "api" | "local" | "none";
@@ -2,4 +2,4 @@
2
2
  * Format/lint-fix all files in the scaffolded workspace with Biome.
3
3
  * Prefer a global `biome` binary (builder image); fall back to `npx`.
4
4
  */
5
- export declare function formatScaffoldedFiles(targetDir: string): void;
5
+ export declare function formatScaffoldedFiles(targetDir: string, paths?: string[]): void;
@@ -1,16 +1,17 @@
1
1
  import type { KeyedModel, SourceFile } from "../../models/source-file.js";
2
2
  /**
3
- * Builder for `projects/api/package.json`.
3
+ * Builder for `projects/<api>/package.json`.
4
4
  *
5
5
  * Starts with the core cortex + crucible deps. Features can call
6
6
  * `addDependency` / `addDevDependency` to extend.
7
7
  */
8
8
  export declare class ApiPackageJson implements KeyedModel {
9
- private readonly projectName;
9
+ private readonly workspaceName;
10
+ private readonly apiName;
10
11
  readonly key: string;
11
12
  private readonly _dependencies;
12
13
  private readonly _devDependencies;
13
- constructor(projectName: string);
14
+ constructor(workspaceName: string, apiName?: string);
14
15
  addDependency(name: string, version: string): this;
15
16
  addDevDependency(name: string, version: string): this;
16
17
  files(): SourceFile[];
@@ -22,6 +22,7 @@ export declare class MainSourceFile implements KeyedModel {
22
22
  private readonly _entities;
23
23
  private readonly _repositories;
24
24
  private readonly _services;
25
+ private _dataSourceName;
25
26
  private _typeOrmSeed;
26
27
  constructor(appName: string);
27
28
  /** Adds a bare side-effect import, e.g. `@decohere/cortex/auth`. */
@@ -39,6 +40,11 @@ export declare class MainSourceFile implements KeyedModel {
39
40
  addRepository(repo: TypeOrmImport): this;
40
41
  /** Adds a service registered in `.withServices()`. */
41
42
  addService(service: ServiceImport): this;
43
+ /**
44
+ * Datasource name passed to `withTypeOrm({ name })`. Must match
45
+ * `database.dataSources[].name` in config.yaml.
46
+ */
47
+ setDataSourceName(name: string): this;
42
48
  /**
43
49
  * Inline seed callback body for `withTypeOrm({ seed })`.
44
50
  * Receives `dataSource` in scope. Example: `await dataSource.getRepository(User).save(...)`.
@@ -1,9 +1,20 @@
1
1
  import type { KeyedModel, SourceFile } from "../../models/source-file.js";
2
+ export type ProductionDockerfileOptions = {
3
+ /** When true, only write `Dockerfile.<name>` (existing workspace — do not replace root Dockerfile). */
4
+ namedOnly?: boolean;
5
+ };
2
6
  /**
3
- * Repo-root production Dockerfile for PaaS (Railway/Fly) and local `docker build`.
4
- * Runs conventional `pnpm run build` / `pnpm start` so Nixpacks and Docker share scripts.
7
+ * Production Dockerfiles for PaaS (Railway/Fly) and local `docker build`.
8
+ *
9
+ * Context is always the **repo root** (`docker build -f Dockerfile.billing .`).
10
+ * Root `Dockerfile` is the first API (`pnpm start`). Extra or custom-named APIs
11
+ * also get `Dockerfile.<name>` so each service can be deployed on its own.
5
12
  */
6
13
  export declare class WebapiProductionDockerfile implements KeyedModel {
14
+ private readonly apiNames;
15
+ private readonly options;
7
16
  readonly key: string;
17
+ constructor(apiNames?: readonly string[], options?: ProductionDockerfileOptions);
8
18
  files(): SourceFile[];
9
19
  }
20
+ export declare function renderProductionDockerfile(apiName: string, startScript: string): string;