@digital-herd/content-hub-cli 1.1.17 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -99,7 +99,7 @@ content-hub-tools <command> [options]
99
99
 
100
100
  - Create a new script (interactive prompts):
101
101
  ```bash
102
- content-hub-tools create-script -e local
102
+ content-hub-tools create-script
103
103
  ```
104
104
 
105
105
  The interactive prompts will guide you through:
@@ -130,7 +130,7 @@ content-hub-tools <command> [options]
130
130
 
131
131
  - Build all components using default tsconfig:
132
132
  ```bash
133
- content-hub-tools build -e local
133
+ content-hub-tools build
134
134
  ```
135
135
 
136
136
  - Build all components using mainEnvironment from config:
@@ -140,32 +140,32 @@ content-hub-tools <command> [options]
140
140
 
141
141
  - Build a single component:
142
142
  ```bash
143
- content-hub-tools build -c "ProductCard" -e local
143
+ content-hub-tools build -c "ProductCard"
144
144
  ```
145
145
 
146
146
  - Build multiple specific components:
147
147
  ```bash
148
- content-hub-tools build -c "Button,Card,Header" -e staging
148
+ content-hub-tools build -c "Button,Card,Header"
149
149
  ```
150
150
 
151
151
  - Build and publish to production:
152
152
  ```bash
153
- content-hub-tools build -c "Button,Card" -p -e production
153
+ content-hub-tools build -c "Button,Card" -p
154
154
  ```
155
155
 
156
156
  - Build all components and publish:
157
157
  ```bash
158
- content-hub-tools build -p -e staging
158
+ content-hub-tools build -p
159
159
  ```
160
160
 
161
161
  - Build using deprecated TS config (compatibility mode):
162
162
  ```bash
163
- content-hub-tools build -d -e local
163
+ content-hub-tools build -d
164
164
  ```
165
165
 
166
166
  - Build specific components with deprecated config and publish:
167
167
  ```bash
168
- content-hub-tools build -c "LegacyComponent" -d -p -e staging
168
+ content-hub-tools build -c "LegacyComponent" -d -p
169
169
  ```
170
170
 
171
171
  - **watch** — Watch and serve External component(s) with HMR (development)
@@ -174,11 +174,13 @@ content-hub-tools <command> [options]
174
174
  - `-c, --components <comp>`: comma-separated list of components to watch. If omitted, watches all components.
175
175
  - `-d, --deprecated`: use `tsconfig.deprecated.json` (TypeScript strict mode disabled) while watching.
176
176
 
177
+ When using `-c` or `--components`, the external component is set to localhost for the selected environment.
178
+
177
179
  Examples:
178
180
 
179
181
  - Watch all components with HMR:
180
182
  ```bash
181
- content-hub-tools watch -e local
183
+ content-hub-tools watch
182
184
  ```
183
185
 
184
186
  - Watch all components using mainEnvironment:
@@ -188,22 +190,22 @@ content-hub-tools <command> [options]
188
190
 
189
191
  - Watch a single component for development:
190
192
  ```bash
191
- content-hub-tools watch -c "ProductCard" -e local
193
+ content-hub-tools watch -c "ProductCard"
192
194
  ```
193
195
 
194
196
  - Watch multiple specific components:
195
197
  ```bash
196
- content-hub-tools watch -c "Button,Card,Header" -e local
198
+ content-hub-tools watch -c "Button,Card,Header"
197
199
  ```
198
200
 
199
201
  - Watch with deprecated tsconfig:
200
202
  ```bash
201
- content-hub-tools watch -d -e local
203
+ content-hub-tools watch -d
202
204
  ```
203
205
 
204
206
  - Watch specific components with deprecated config:
205
207
  ```bash
206
- content-hub-tools watch -c "LegacyComponent,OldCard" -d -e local
208
+ content-hub-tools watch -c "LegacyComponent,OldCard" -d
207
209
  ```
208
210
 
209
211
  - **publish-script** — Publish scripts to environment
@@ -215,17 +217,17 @@ content-hub-tools <command> [options]
215
217
 
216
218
  - Publish a single script:
217
219
  ```bash
218
- content-hub-tools publish-script -s "myScript" -e staging
220
+ content-hub-tools publish-script -s "myScript"
219
221
  ```
220
222
 
221
223
  - Publish multiple scripts:
222
224
  ```bash
223
- content-hub-tools publish-script -s "myScript,anotherScript" -e staging
225
+ content-hub-tools publish-script -s "myScript,anotherScript"
224
226
  ```
225
227
 
226
228
  - Publish to production environment:
227
229
  ```bash
228
- content-hub-tools publish-script -s "ProductionScript" -e production
230
+ content-hub-tools publish-script -s "ProductionScript"
229
231
  ```
230
232
 
231
233
  - Publish scripts using mainEnvironment:
@@ -239,12 +241,12 @@ content-hub-tools <command> [options]
239
241
 
240
242
  - Sync scripts from staging environment:
241
243
  ```bash
242
- content-hub-tools sync-scripts -e staging
244
+ content-hub-tools sync-scripts
243
245
  ```
244
246
 
245
247
  - Sync scripts from production:
246
248
  ```bash
247
- content-hub-tools sync-scripts -e production
249
+ content-hub-tools sync-scripts
248
250
  ```
249
251
 
250
252
  - Sync using mainEnvironment from config:
@@ -254,7 +256,7 @@ content-hub-tools <command> [options]
254
256
 
255
257
  - Sync from local development environment:
256
258
  ```bash
257
- content-hub-tools sync-scripts -e local
259
+ content-hub-tools sync-scripts
258
260
  ```
259
261
 
260
262
  - **create-manual-patch** — Create a new manual patch from template (interactive)
@@ -290,12 +292,12 @@ content-hub-tools <command> [options]
290
292
 
291
293
  - Run a patch (interactive selection):
292
294
  ```bash
293
- content-hub-tools run-manual-patch -e staging
295
+ content-hub-tools run-manual-patch
294
296
  ```
295
297
 
296
298
  - Run a patch on production:
297
299
  ```bash
298
- content-hub-tools run-manual-patch -e production
300
+ content-hub-tools run-manual-patch
299
301
  ```
300
302
 
301
303
  The interactive prompt will show:
package/lib/bin.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});let commander_1=require("commander"),modules_1=__importDefault(require("./modules")),program=new commander_1.Command;program.name("content-hub-tools").description("ContentHub build & utility CLI").version("1.1.17");for(let o of modules_1.default)for(let e of o.commands)program.addCommand(e);program.parse(process.argv);
2
+ var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});let commander_1=require("commander"),modules_1=__importDefault(require("./modules")),program=new commander_1.Command;program.name("content-hub-tools").description("ContentHub build & utility CLI").version("1.2.0");for(let o of modules_1.default)for(let e of o.commands)program.addCommand(e);program.parse(process.argv);
@@ -1 +1 @@
1
- var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildExternalComponentCommand=void 0;let commander_1=require("commander"),globalCommandConfig_js_1=require("../../../utils/globalCommandConfig.js"),ExternalComponentBuildService_js_1=__importDefault(require("../services/ExternalComponentBuildService.js")),ExternalComponentPublishService_js_1=__importDefault(require("../services/ExternalComponentPublishService.js")),logger_js_1=__importDefault(require("../../../utils/logger.js"));exports.buildExternalComponentCommand=(0,globalCommandConfig_js_1.setGlobalConfig)(new commander_1.Command("build")).option("-c, --components <comp>","component list to build").option("-d, --deprecated","build with deprecated tsconfig").option("-p, --publish","Deploy the compoonent to the environment").description("Build External component(s)").action(async e=>{process.env.NODE_ENV="production";var o,{config:t,contenthubService:n}=await(0,globalCommandConfig_js_1.globalCommandConfig)(e),i=e.deprecated?"tsconfig.deprecated.json":void 0,i=(e.deprecated&&logger_js_1.default.info("Work with Deprecated tsconfig"),new ExternalComponentBuildService_js_1.default(t,i));let l=[];l=e.components?(o=e.components.split(",").map(e=>e.trim()),await i.build(o)):await i.buildAll(),e.publish&&await new ExternalComponentPublishService_js_1.default(n,t).publishToPortalAsset(l)});
1
+ var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.buildExternalComponentCommand=void 0;let commander_1=require("commander"),globalCommandConfig_js_1=require("../../../utils/globalCommandConfig.js"),ExternalComponentBuildService_js_1=__importDefault(require("../services/ExternalComponentBuildService.js")),ExternalComponentPublishService_js_1=__importDefault(require("../services/Publish/ExternalComponentPublishService.js")),logger_js_1=__importDefault(require("../../../utils/logger.js"));exports.buildExternalComponentCommand=(0,globalCommandConfig_js_1.setGlobalConfig)(new commander_1.Command("build")).option("-c, --components <comp>","component list to build").option("-d, --deprecated","build with deprecated tsconfig").option("-p, --publish","Deploy the component to the environment").description("Build External component(s)").action(async e=>{process.env.NODE_ENV="production";var o,{config:t,contenthubService:n}=await(0,globalCommandConfig_js_1.globalCommandConfig)(e),i=e.deprecated?"tsconfig.deprecated.json":void 0,i=(e.deprecated&&logger_js_1.default.info("Work with Deprecated tsconfig"),new ExternalComponentBuildService_js_1.default(t,i));let l=[];l=e.components?(o=e.components.split(",").map(e=>e.trim()),await i.build(o)):await i.buildAll(),e.publish&&await new ExternalComponentPublishService_js_1.default(n,t).publish(l)});
@@ -1,2 +1,2 @@
1
- var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&("get"in o?t.__esModule:!o.writable&&!o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){e[i=void 0===i?r:i]=t[r]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||(()=>{var o=function(e){return(o=Object.getOwnPropertyNames||function(e){var t,r=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&(r[r.length]=t);return r})(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r=o(e),i=0;i<r.length;i++)"default"!==r[i]&&__createBinding(t,e,r[i]);return __setModuleDefault(t,e),t}})(),__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});let FileService_1=__importDefault(require("../../../services/FileService")),vite_1=require("vite"),path_1=__importDefault(require("path")),lodash_1=require("lodash"),fs_1=__importDefault(require("fs")),https_1=__importDefault(require("https")),connect_1=__importDefault(require("connect")),chokidar_1=require("chokidar"),selfsigned_1=__importDefault(require("selfsigned")),logger_1=__importDefault(require("../../../utils/logger")),TypeCheckService_1=__importDefault(require("./TypeCheckService")),ExternalComponentPublishService_1=__importDefault(require("./ExternalComponentPublishService"));class ExternalComponentWatchService{config;fileService;typeCheck;publishService;componentBuilds=new Map;componentWatcher;constructor(e,t,r){this.config=t,this.fileService=new FileService_1.default(t),this.typeCheck=new TypeCheckService_1.default(t,r),this.publishService=new ExternalComponentPublishService_1.default(e,t)}async watchAll(){logger_1.default.info("In watch all mode, it does not update the external components to local path");var e=this.fileService.getAllComponentNames();await this.watchComponents(e,!1)}async watchSingleComponent(e){await this.watchComponents([e])}async getOrCreateCertificate(){var e=path_1.default.resolve(process.cwd(),".vite-certs"),t=path_1.default.join(e,"key.pem"),r=path_1.default.join(e,"cert.pem");if(fs_1.default.existsSync(t)&&fs_1.default.existsSync(r))return{key:fs_1.default.readFileSync(t,"utf-8"),cert:fs_1.default.readFileSync(r,"utf-8")};fs_1.default.existsSync(e)||fs_1.default.mkdirSync(e,{recursive:!0});try{var i=[{name:"commonName",value:"localhost"}],o=selfsigned_1.default.generate(i,{keySize:2048,days:365,algorithm:"sha256",extensions:[{name:"subjectAltName",altNames:[{type:2,value:"localhost"},{type:7,ip:"127.0.0.1"}]}]});return fs_1.default.writeFileSync(t,o.private),fs_1.default.writeFileSync(r,o.cert),{key:o.private,cert:o.cert}}catch(e){throw logger_1.default.error("Failed to generate certificate:",e),new Error("Failed to generate self-signed certificate.")}}setupFileWatcher(r){var e=path_1.default.dirname(this.config.componentDir),e=(0,chokidar_1.watch)(e,{ignored:/(node_modules|\.git|\.vite-cache)/,awaitWriteFinish:{stabilityThreshold:100,pollInterval:100}});e.on("change",()=>{var e,t=this.componentBuilds.keys();logger_1.default.info(`
1
+ var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&("get"in o?t.__esModule:!o.writable&&!o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){e[i=void 0===i?r:i]=t[r]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||(()=>{var o=function(e){return(o=Object.getOwnPropertyNames||function(e){var t,r=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&(r[r.length]=t);return r})(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r=o(e),i=0;i<r.length;i++)"default"!==r[i]&&__createBinding(t,e,r[i]);return __setModuleDefault(t,e),t}})(),__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});let FileService_1=__importDefault(require("../../../services/FileService")),vite_1=require("vite"),path_1=__importDefault(require("path")),lodash_1=require("lodash"),fs_1=__importDefault(require("fs")),https_1=__importDefault(require("https")),connect_1=__importDefault(require("connect")),chokidar_1=require("chokidar"),selfsigned_1=__importDefault(require("selfsigned")),logger_1=__importDefault(require("../../../utils/logger")),TypeCheckService_1=__importDefault(require("./TypeCheckService")),ExternalComponentPortalPublishService_1=__importDefault(require("./Publish/ExternalComponentPortalPublishService"));class ExternalComponentWatchService{config;fileService;typeCheck;publishService;componentBuilds=new Map;componentWatcher;constructor(e,t,r){this.config=t,this.fileService=new FileService_1.default(t),this.typeCheck=new TypeCheckService_1.default(t,r),this.publishService=new ExternalComponentPortalPublishService_1.default(e,t)}async watchAll(){logger_1.default.info("In watch all mode, it does not update the external components to local path");var e=this.fileService.getAllComponentNames();await this.watchComponents(e,!1)}async watchSingleComponent(e){await this.watchComponents([e])}async getOrCreateCertificate(){var e=path_1.default.resolve(process.cwd(),".vite-certs"),t=path_1.default.join(e,"key.pem"),r=path_1.default.join(e,"cert.pem");if(fs_1.default.existsSync(t)&&fs_1.default.existsSync(r))return{key:fs_1.default.readFileSync(t,"utf-8"),cert:fs_1.default.readFileSync(r,"utf-8")};fs_1.default.existsSync(e)||fs_1.default.mkdirSync(e,{recursive:!0});try{var i=[{name:"commonName",value:"localhost"}],o=selfsigned_1.default.generate(i,{keySize:2048,days:365,algorithm:"sha256",extensions:[{name:"subjectAltName",altNames:[{type:2,value:"localhost"},{type:7,ip:"127.0.0.1"}]}]});return fs_1.default.writeFileSync(t,o.private),fs_1.default.writeFileSync(r,o.cert),{key:o.private,cert:o.cert}}catch(e){throw logger_1.default.error("Failed to generate certificate:",e),new Error("Failed to generate self-signed certificate.")}}setupFileWatcher(r){var e=path_1.default.dirname(this.config.componentDir),e=(0,chokidar_1.watch)(e,{ignored:/(node_modules|\.git|\.vite-cache)/,awaitWriteFinish:{stabilityThreshold:100,pollInterval:100}});e.on("change",()=>{var e,t=this.componentBuilds.keys();logger_1.default.info(`
2
2
  📝 File changed, rebuilding`),this.componentBuilds.clear();for(e of t)try{this.buildComponent(e,r)}catch(e){logger_1.default.error(e)}}),this.componentWatcher=e}async watchComponents(o,e=!0){let t=this.fileService.getAllComponentNames();var r=o.filter(e=>!t.includes(e)),r=(r.length&&(logger_1.default.error("Some components does not exists: "+r.join(", ")),process.exit(-1)),await Promise.resolve().then(()=>__importStar(require("vite")))).loadConfigFromFile,r=await r({command:"serve",mode:"development"},path_1.default.resolve(process.cwd(),"vite.config.js"));if(!r)throw new Error("Vite config not found");var i=this.config.port||4e3;e&&await this.publishService.publishToLocalPath("https://localhost:"+i,o);let a=(0,lodash_1.cloneDeep)(r.config),n=await(0,vite_1.createServer)({...a,server:{middlewareMode:!0}});e=(0,connect_1.default)(),this.setupFileWatcher(a),e.use(async(t,r,e)=>{t=t.url.match(/^\/([a-zA-Z0-9_]+)\.js$/);if(t){t=t[1];if(!o.includes(t))return r.statusCode=404,void r.end("Component not found");try{var i=await this.buildComponent(t,a);return r.setHeader("Content-Type","application/javascript"),r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Cache-Control","no-cache, no-store, must-revalidate"),void r.end(i)}catch(e){return logger_1.default.error(`Error building ${t}:`,e),r.statusCode=500,void r.end("Error building component: "+e)}}e()}),e.use(n.middlewares),r=await this.getOrCreateCertificate();let l=https_1.default.createServer(r,e);l.listen(i,()=>{logger_1.default.info("\n✓ Dev server ready at https://localhost:4000"),logger_1.default.info("\nAvailable components:"),o.forEach(e=>{logger_1.default.info(` • https://localhost:4000/${e}.js`)})}),process.on("SIGINT",async()=>{logger_1.default.info("\nShutting down dev server..."),this.componentWatcher&&await this.componentWatcher.close(),await n.close(),l.close(),process.exit(0)})}async buildComponent(t,e){if(this.componentBuilds.has(t))return this.componentBuilds.get(t);await this.typeCheck.specificComponents(t);var r=this.fileService.getEntryOfComponent(t),e=(0,lodash_1.cloneDeep)(e),r=(e.build={...e.build,lib:{formats:["es"],fileName:t,entry:r},outDir:path_1.default.resolve(process.cwd(),".vite-cache",t),emptyOutDir:!1,minify:!1},e.mode="development",e.logLevel="warn",logger_1.default.info(`Building ${t}...`),(0,vite_1.build)(e).then(()=>{var e=path_1.default.resolve(process.cwd(),".vite-cache",t,t+".js");return logger_1.default.info(t+" build finished"),fs_1.default.readFileSync(e,"utf-8")}));return this.componentBuilds.set(t,r),r}}exports.default=ExternalComponentWatchService;
@@ -0,0 +1,9 @@
1
+ import { BlobStorageConfig, ContenthubConfig } from "../../../../types/ContentHubConfig.interface";
2
+ declare class ExternalComponentBlobPublishService {
3
+ blobStorageConfig: BlobStorageConfig;
4
+ private fileService;
5
+ constructor(config: ContenthubConfig, blobStorageConfig: BlobStorageConfig);
6
+ publishToBlobStorage(components: string | string[]): Promise<void>;
7
+ private uploadBlobFile;
8
+ }
9
+ export default ExternalComponentBlobPublishService;
@@ -0,0 +1 @@
1
+ var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r);var i=Object.getOwnPropertyDescriptor(t,r);i&&("get"in i?t.__esModule:!i.writable&&!i.configurable)||(i={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,o,i)}:function(e,t,r,o){e[o=void 0===o?r:o]=t[r]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||(()=>{var i=function(e){return(i=Object.getOwnPropertyNames||function(e){var t,r=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&(r[r.length]=t);return r})(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r=i(e),o=0;o<r.length;o++)"default"!==r[o]&&__createBinding(t,e,r[o]);return __setModuleDefault(t,e),t}})(),__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});let FileService_1=__importDefault(require("../../../../services/FileService")),logger_1=__importStar(require("../../../../utils/logger")),storage_blob_1=require("@azure/storage-blob"),fs_1=require("fs");class ExternalComponentBlobPublishService{blobStorageConfig;fileService;constructor(e,t){this.blobStorageConfig=t,this.fileService=new FileService_1.default(e)}async publishToBlobStorage(e){var{connectionString:t,containerName:r}=this.blobStorageConfig,e=Array.isArray(e)?e:[e];if(t&&r){var o,i=storage_blob_1.BlobServiceClient.fromConnectionString(t).getContainerClient(r);await i.createIfNotExists(),logger_1.default.info(`Start uploading files to blob container "${r}"`);for(o of e){var n=this.fileService.getComponentBuild(o);n&&(0,fs_1.existsSync)(n)?(await this.uploadBlobFile(r,i,n),n=n+".map",(0,fs_1.existsSync)(n)&&await this.uploadBlobFile(r,i,n)):logger_1.default.error(`Build file not found for component "${o}"`)}}else logger_1.default.warn("Blob publish skipped. Missing connection string or container name.")}async uploadBlobFile(e,t,r){var o=r.split(/[/\\]/).pop(),t=t.getBlockBlobClient(o),r=(0,fs_1.readFileSync)(r),i=o.endsWith(".map");await t.upload(r,r.length,{blobHTTPHeaders:{blobContentType:i?"application/json":"text/javascript"}}),logger_1.loggerSuccess.info(`"${o}" uploaded to blob container "${e}"`)}}exports.default=ExternalComponentBlobPublishService;
@@ -0,0 +1,14 @@
1
+ import { ContenthubConfig } from "../../../../types/ContentHubConfig.interface";
2
+ import ContenthubService from "../../../../services/ContenthubService";
3
+ declare class ExternalComponentPortalPublishService {
4
+ contenthubService: ContenthubService;
5
+ private fileService;
6
+ constructor(contenthubService: ContenthubService, config: ContenthubConfig);
7
+ publishToPortalAsset(components: string | string[]): Promise<void>;
8
+ publishToLocalPath(host: string, components: string | string[]): Promise<void>;
9
+ private updateExternalComponents;
10
+ private createOrUpdateAsset;
11
+ private getOrCreateAsset;
12
+ private getAssetFromFileName;
13
+ }
14
+ export default ExternalComponentPortalPublishService;
@@ -0,0 +1 @@
1
+ var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,n,i){void 0===i&&(i=n);var r=Object.getOwnPropertyDescriptor(t,n);r&&("get"in r?t.__esModule:!r.writable&&!r.configurable)||(r={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,i,r)}:function(e,t,n,i){e[i=void 0===i?n:i]=t[n]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||(()=>{var r=function(e){return(r=Object.getOwnPropertyNames||function(e){var t,n=[];for(t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[n.length]=t);return n})(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n=r(e),i=0;i<n.length;i++)"default"!==n[i]&&__createBinding(t,e,n[i]);return __setModuleDefault(t,e),t}})(),__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});let sc_contenthub_webclient_sdk_1=require("@sitecore/sc-contenthub-webclient-sdk"),FileService_1=__importDefault(require("../../../../services/FileService")),array_1=require("../../../../utils/array"),apiCatch_1=require("../../../../utils/apiCatch"),hash_1=require("../../../../utils/hash"),logger_1=__importStar(require("../../../../utils/logger")),lodash_1=require("lodash");class ExternalComponentPortalPublishService{contenthubService;fileService;constructor(e,t){this.contenthubService=e,this.fileService=new FileService_1.default(t)}async publishToPortalAsset(e){var t;for(t of Array.isArray(e)?e:[e]){var n=this.fileService.getComponentConfig(t),i=this.fileService.getComponentBuild(t),n=await this.fileService.tsFileImport(n),i=await this.createOrUpdateAsset(t,i,n);await this.updateExternalComponents(t,n,{assetId:i.id}),logger_1.loggerSuccess.info(t+" Published")}}async publishToLocalPath(e,t){var n;for(n of Array.isArray(t)?t:[t]){var i=this.fileService.getComponentConfig(n),i=await this.fileService.tsFileImport(i),r=`${e}/${n}.js`;await this.updateExternalComponents(n,i,{path:r}),logger_1.loggerSuccess.info(`"${n}" Page component updated to local path`)}}async updateExternalComponents(n,i,{assetId:r,path:o}){var e=i.components.flatMap(e=>e.pageComponentIdentifiers),a=(logger_1.default.info(`Start updating ${e.length} External Page components`),await Promise.all((0,array_1.arrayToChunks)(e,50).map(e=>(0,apiCatch_1.apiErrorCatch)(()=>this.contenthubService.client.entities.getManyAsync(e,new sc_contenthub_webclient_sdk_1.EntityLoadConfiguration(sc_contenthub_webclient_sdk_1.CultureLoadOption.Default,new sc_contenthub_webclient_sdk_1.PropertyLoadOption("PageComponent.Settings"),new sc_contenthub_webclient_sdk_1.RelationLoadOption(["AssetToPageComponent"])))))).then(e=>e.flat()));for(let t of e){let e=a.find(e=>e.identifier===t);var s=i.components.find(e=>e.pageComponentIdentifiers.includes(t)),c=(e||(logger_1.default.error(t+` was not found that was specified in the config of "${n}"`),process.exit(-1)),await e.getPropertyValue("PageComponent.Settings")),s={...c,config:s.config,path:o||void 0},c=((0,lodash_1.isEqual)(c,s)||e.setPropertyValue("PageComponent.Settings",s),e.getRelation("AssetToPageComponent"));r&&!c.getIds().includes(r)?c.setIds([r]):o&&c.setIds([]),e.isDirty&&await(0,apiCatch_1.apiErrorCatch)(()=>this.contenthubService.client.entities.saveAsync(e))}}async createOrUpdateAsset(e,t,n){var n=await this.getOrCreateAsset(e,n),i=n.getPropertyValue("Digest");if(i){var r=await(0,hash_1.sha1FromFile)(t);if(i.replace("0x","")===r)return logger_1.default.info(`"${e}" source code wasn't updated so skip.`),n}i=new sc_contenthub_webclient_sdk_1.LocalUploadSource("file://"+t);let o=new sc_contenthub_webclient_sdk_1.UploadRequest(i,"AssetUploadConfiguration","NewMainFile");return o.actionParameters={AssetId:n.id},await(0,apiCatch_1.apiErrorCatch)(()=>this.contenthubService.client.uploads.uploadAsync(o)),logger_1.default.info(`"${e}" source code uploaded to asset`),n}async getOrCreateAsset(e,t){let n=await this.getAssetFromFileName(e);return(n=!n&&t.deprecatedAssetFileName?await this.getAssetFromFileName(t.deprecatedAssetFileName):n)?n.getPropertyValue("Title")!==e&&(n.setPropertyValue("Title",e),n.setPropertyValue("FileName",e+".js"),await(0,apiCatch_1.apiErrorCatch)(()=>this.contenthubService.client.entities.saveAsync(n))):(t=await this.contenthubService.getOrFetchId("M.Content.Repository.Portal"),(n=await this.contenthubService.client.entityFactory.createAsync("M.Asset")).setPropertyValue("Title",e),n.setPropertyValue("FileName",e+".js"),n.getRelation("ContentRepositoryToAsset")?.setIds([t]),n.id=await(0,apiCatch_1.apiErrorCatch)(()=>this.contenthubService.client.entities.saveAsync(n))),n}async getAssetFromFileName(e){var t=await this.contenthubService.getOrFetchId("M.Content.Repository.Portal"),e=e.replace(".js","");let n=new sc_contenthub_webclient_sdk_1.Query({filter:new sc_contenthub_webclient_sdk_1.CompositeQueryFilter({combineMethod:sc_contenthub_webclient_sdk_1.CompositeFilterOperator.And,children:[new sc_contenthub_webclient_sdk_1.DefinitionQueryFilter({name:"M.Asset",operator:sc_contenthub_webclient_sdk_1.ComparisonOperator.Equals}),new sc_contenthub_webclient_sdk_1.CompositeQueryFilter({combineMethod:sc_contenthub_webclient_sdk_1.CompositeFilterOperator.Or,children:[new sc_contenthub_webclient_sdk_1.PropertyQueryFilter({property:"Title",dataType:sc_contenthub_webclient_sdk_1.FilterDataType.String,values:[e,e+".js"],operator:sc_contenthub_webclient_sdk_1.ComparisonOperator.Equals}),new sc_contenthub_webclient_sdk_1.PropertyQueryFilter({property:"FileName",dataType:sc_contenthub_webclient_sdk_1.FilterDataType.String,values:[e,e+".js"],operator:sc_contenthub_webclient_sdk_1.ComparisonOperator.Equals})]}),new sc_contenthub_webclient_sdk_1.RelationQueryFilter({relation:"ContentRepositoryToAsset",parentId:t})]}),take:1});return(await(0,apiCatch_1.apiErrorCatch)(()=>this.contenthubService.client.querying.queryAsync(n,new sc_contenthub_webclient_sdk_1.EntityLoadConfiguration(sc_contenthub_webclient_sdk_1.CultureLoadOption.Default,new sc_contenthub_webclient_sdk_1.PropertyLoadOption(["FileName","Title","Digest"]),new sc_contenthub_webclient_sdk_1.RelationLoadOption(["AssetToPageComponent"]))))).items[0]}}exports.default=ExternalComponentPortalPublishService;
@@ -0,0 +1,11 @@
1
+ import ContenthubService from "@/services/ContenthubService";
2
+ import { ContenthubConfig } from "@/types/ContentHubConfig.interface";
3
+ declare class ExternalComponentPortalPublishService {
4
+ contenthubService: ContenthubService;
5
+ config: ContenthubConfig;
6
+ constructor(contenthubService: ContenthubService, config: ContenthubConfig);
7
+ publish(components: string | string[]): Promise<void>;
8
+ private publishViaBlob;
9
+ private publishPortal;
10
+ }
11
+ export default ExternalComponentPortalPublishService;
@@ -0,0 +1 @@
1
+ var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});let ExternalComponentBlobPublishService_1=__importDefault(require("./ExternalComponentBlobPublishService"));class ExternalComponentPortalPublishService{contenthubService;config;constructor(e,t){this.contenthubService=e,this.config=t}publish(e){return"blob"===this.config.publish?.type?this.publishViaBlob(e,this.config.publish.blobConfig):this.publishPortal(e)}publishViaBlob(e,t){return new ExternalComponentBlobPublishService_1.default(this.config,t).publishToBlobStorage(e)}publishPortal(e){return new ExternalComponentPortalPublishService(this.contenthubService,this.config).publish(e)}}exports.default=ExternalComponentPortalPublishService;
@@ -3,11 +3,19 @@ export interface ContenthubEnvironment {
3
3
  name: string;
4
4
  apiToken: string;
5
5
  }
6
+ export interface BlobStorageConfig {
7
+ connectionString: string;
8
+ containerName: string;
9
+ }
6
10
  export interface ContenthubConfig {
7
11
  componentDir: string;
8
12
  scriptDir: string;
9
13
  patchDir: string;
10
14
  port: number;
15
+ publish?: {
16
+ type: "blob" | "portal-assets";
17
+ blobConfig?: BlobStorageConfig;
18
+ };
11
19
  commands?: {
12
20
  watch?: {
13
21
  disabledEnvironments?: string[];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@digital-herd/content-hub-cli",
3
3
  "description": "CLI tools for managing Sitecore Content Hub external components and scripts",
4
- "version": "1.1.17",
4
+ "version": "1.2.1",
5
5
  "type": "commonjs",
6
6
  "main": "./lib/index.js",
7
7
  "types": "./lib/index.d.ts",
@@ -23,6 +23,7 @@
23
23
  "watch": "tsc --watch"
24
24
  },
25
25
  "dependencies": {
26
+ "@azure/storage-blob": "12.31.0",
26
27
  "@inquirer/input": "^5.0.4",
27
28
  "@inquirer/prompts": "^8.2.0",
28
29
  "@inquirer/select": "^5.0.4",
@@ -48,5 +49,6 @@
48
49
  },
49
50
  "peerDependencies": {
50
51
  "@sitecore/sc-contenthub-webclient-sdk": "1.2.96"
51
- }
52
+ },
53
+ "optionalDependencies": {}
52
54
  }