From cad3243a937bad8f2e508c2e52a5c690de40d73b Mon Sep 17 00:00:00 2001 From: Gergely Varga Date: Wed, 8 Nov 2023 15:56:46 +0800 Subject: [PATCH] feat(cli): add excel loader example --- packages/galileo-cli/.projen/deps.json | 8 + packages/galileo-cli/.projen/tasks.json | 4 +- .../csv-loader/metadata-provider-object.ts | 4 +- .../csv-loader/metadata-provider-string.ts | 14 +- .../examples/csv-loader/parser-common.ts | 29 +- .../examples/excel-loader/example.xlsx | Bin 0 -> 13115 bytes .../examples/excel-loader/excel-loader.ts | 193 +++++++++++++ .../examples/excel-loader/index.ts | 45 +++ packages/galileo-cli/package.json | 2 + pnpm-lock.yaml | 260 +++++++++++++++++- projenrc/framework/galileo-cli.ts | 2 + 11 files changed, 524 insertions(+), 37 deletions(-) create mode 100644 packages/galileo-cli/examples/excel-loader/example.xlsx create mode 100644 packages/galileo-cli/examples/excel-loader/excel-loader.ts create mode 100644 packages/galileo-cli/examples/excel-loader/index.ts diff --git a/packages/galileo-cli/.projen/deps.json b/packages/galileo-cli/.projen/deps.json index 5750be05..8e25ee4c 100644 --- a/packages/galileo-cli/.projen/deps.json +++ b/packages/galileo-cli/.projen/deps.json @@ -21,6 +21,10 @@ "name": "@types/csv-parse", "type": "build" }, + { + "name": "@types/exceljs", + "type": "build" + }, { "name": "@types/execa", "type": "build" @@ -219,6 +223,10 @@ "name": "csv-parse", "type": "runtime" }, + { + "name": "exceljs", + "type": "runtime" + }, { "name": "execa", "type": "runtime" diff --git a/packages/galileo-cli/.projen/tasks.json b/packages/galileo-cli/.projen/tasks.json index 044ea363..ea3158f0 100644 --- a/packages/galileo-cli/.projen/tasks.json +++ b/packages/galileo-cli/.projen/tasks.json @@ -118,13 +118,13 @@ "exec": "pnpm update npm-check-updates" }, { - "exec": "npm-check-updates --upgrade --target=minor --peer --dep=dev,peer,prod,optional --filter=@aws-sdk/types,@oclif/test,@types/chalk,@types/clear,@types/csv-parse,@types/execa,@types/fs-extra,@types/jest,@types/jsonschema,@types/lodash,@types/node-localstorage,@types/node,@types/ora,@types/prompts,@typescript-eslint/eslint-plugin,@typescript-eslint/parser,eslint-config-prettier,eslint-import-resolver-node,eslint-import-resolver-typescript,eslint-plugin-header,eslint-plugin-import,eslint-plugin-prettier,eslint,jest,jest-junit,npm-check-updates,prettier,projen,ts-jest,ts-node,typescript,@aws-sdk/client-cognito-identity-provider,@aws-sdk/client-s3,@aws-sdk/client-sfn,@aws-sdk/client-ssm,@aws-sdk/client-sts,@aws-sdk/credential-providers,@aws-sdk/lib-storage,@oclif/core,@oclif/errors,@oclif/plugin-autocomplete,@oclif/plugin-commands,@oclif/plugin-help,@oclif/plugin-not-found,@oclif/plugin-plugins,@oclif/plugin-update,@oclif/plugin-warn-if-update-available,@smithy/property-provider,chalk,clear,csv-parse,execa,figlet,fs-extra,ink,jsonschema,lodash,node-localstorage,ora,prompts" + "exec": "npm-check-updates --upgrade --target=minor --peer --dep=dev,peer,prod,optional --filter=@aws-sdk/types,@oclif/test,@types/chalk,@types/clear,@types/csv-parse,@types/exceljs,@types/execa,@types/fs-extra,@types/jest,@types/jsonschema,@types/lodash,@types/node-localstorage,@types/node,@types/ora,@types/prompts,@typescript-eslint/eslint-plugin,@typescript-eslint/parser,eslint-config-prettier,eslint-import-resolver-node,eslint-import-resolver-typescript,eslint-plugin-header,eslint-plugin-import,eslint-plugin-prettier,eslint,jest,jest-junit,npm-check-updates,prettier,projen,ts-jest,ts-node,typescript,@aws-sdk/client-cognito-identity-provider,@aws-sdk/client-s3,@aws-sdk/client-sfn,@aws-sdk/client-ssm,@aws-sdk/client-sts,@aws-sdk/credential-providers,@aws-sdk/lib-storage,@oclif/core,@oclif/errors,@oclif/plugin-autocomplete,@oclif/plugin-commands,@oclif/plugin-help,@oclif/plugin-not-found,@oclif/plugin-plugins,@oclif/plugin-update,@oclif/plugin-warn-if-update-available,@smithy/property-provider,chalk,clear,csv-parse,exceljs,execa,figlet,fs-extra,ink,jsonschema,lodash,node-localstorage,ora,prompts" }, { "exec": "pnpm i --no-frozen-lockfile" }, { - "exec": "pnpm update @aws-sdk/types @oclif/test @types/chalk @types/clear @types/csv-parse @types/execa @types/fs-extra @types/jest @types/jsonschema @types/lodash @types/node-localstorage @types/node @types/ora @types/prompts @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-import-resolver-node eslint-import-resolver-typescript eslint-plugin-header eslint-plugin-import eslint-plugin-prettier eslint jest jest-junit npm-check-updates prettier projen ts-jest ts-node typescript @aws-sdk/client-cognito-identity-provider @aws-sdk/client-s3 @aws-sdk/client-sfn @aws-sdk/client-ssm @aws-sdk/client-sts @aws-sdk/credential-providers @aws-sdk/lib-storage @oclif/core @oclif/errors @oclif/plugin-autocomplete @oclif/plugin-commands @oclif/plugin-help @oclif/plugin-not-found @oclif/plugin-plugins @oclif/plugin-update @oclif/plugin-warn-if-update-available @smithy/property-provider chalk clear csv-parse execa figlet fs-extra ink jsonschema lodash node-localstorage ora prompts" + "exec": "pnpm update @aws-sdk/types @oclif/test @types/chalk @types/clear @types/csv-parse @types/exceljs @types/execa @types/fs-extra @types/jest @types/jsonschema @types/lodash @types/node-localstorage @types/node @types/ora @types/prompts @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-import-resolver-node eslint-import-resolver-typescript eslint-plugin-header eslint-plugin-import eslint-plugin-prettier eslint jest jest-junit npm-check-updates prettier projen ts-jest ts-node typescript @aws-sdk/client-cognito-identity-provider @aws-sdk/client-s3 @aws-sdk/client-sfn @aws-sdk/client-ssm @aws-sdk/client-sts @aws-sdk/credential-providers @aws-sdk/lib-storage @oclif/core @oclif/errors @oclif/plugin-autocomplete @oclif/plugin-commands @oclif/plugin-help @oclif/plugin-not-found @oclif/plugin-plugins @oclif/plugin-update @oclif/plugin-warn-if-update-available @smithy/property-provider chalk clear csv-parse exceljs execa figlet fs-extra ink jsonschema lodash node-localstorage ora prompts" }, { "exec": "npx projen" diff --git a/packages/galileo-cli/examples/csv-loader/metadata-provider-object.ts b/packages/galileo-cli/examples/csv-loader/metadata-provider-object.ts index af3862bf..c14f3601 100644 --- a/packages/galileo-cli/examples/csv-loader/metadata-provider-object.ts +++ b/packages/galileo-cli/examples/csv-loader/metadata-provider-object.ts @@ -1,8 +1,8 @@ /*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. PDX-License-Identifier: Apache-2.0 */ -import { parseCsv } from "./parser-common"; -import { DocumentMetadata, IMetadataProvider } from "../../src"; +import { parseCsv } from './parser-common'; +import { DocumentMetadata, IMetadataProvider } from '../../src'; export class MetadataProvider implements IMetadataProvider { async getMetadata(): Promise { diff --git a/packages/galileo-cli/examples/csv-loader/metadata-provider-string.ts b/packages/galileo-cli/examples/csv-loader/metadata-provider-string.ts index b96b6a4d..61a70466 100644 --- a/packages/galileo-cli/examples/csv-loader/metadata-provider-string.ts +++ b/packages/galileo-cli/examples/csv-loader/metadata-provider-string.ts @@ -1,10 +1,10 @@ /*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. PDX-License-Identifier: Apache-2.0 */ -import * as fs from "node:fs"; -import * as path from "node:path"; -import { parseCsv } from "./parser-common"; -import { DocumentMetadata, IMetadataProvider } from "../../src"; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { parseCsv } from './parser-common'; +import { DocumentMetadata, IMetadataProvider } from '../../src'; export class MetadataProvider implements IMetadataProvider { async getMetadata(): Promise { @@ -12,15 +12,15 @@ export class MetadataProvider implements IMetadataProvider { const docMetadata = parseCsv(); // save it as a metadata.json file - const outputDir = path.join(__dirname, "generated"); - const outputFile = path.join(outputDir, "metadata.json"); + const outputDir = path.join(__dirname, 'generated'); + const outputFile = path.join(outputDir, 'metadata.json'); // create generated folder if doesn't exist fs.mkdirSync(outputDir, { recursive: true }); // save into a file fs.writeFileSync(outputFile, JSON.stringify(docMetadata, null, 2), { - encoding: "utf-8", + encoding: 'utf-8', }); // return absolute path diff --git a/packages/galileo-cli/examples/csv-loader/parser-common.ts b/packages/galileo-cli/examples/csv-loader/parser-common.ts index 8da8721e..e8955e7b 100644 --- a/packages/galileo-cli/examples/csv-loader/parser-common.ts +++ b/packages/galileo-cli/examples/csv-loader/parser-common.ts @@ -1,35 +1,30 @@ /*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. PDX-License-Identifier: Apache-2.0 */ -import * as fs from "node:fs"; -import * as path from "node:path"; -import { parse } from "csv-parse/sync"; -import { DocumentMetadata } from "../../src"; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { parse } from 'csv-parse/sync'; +import { DocumentMetadata } from '../../src'; export const parseCsv = (): DocumentMetadata => { try { - const filename = "example.csv"; + const filename = 'example.csv'; const filepath = path.join(__dirname, filename); - const csvFileContent = fs.readFileSync(filepath, { encoding: "utf-8" }); + const csvFileContent = fs.readFileSync(filepath, { encoding: 'utf-8' }); const rows: any[] = parse(csvFileContent, { - columns: [ - { name: "service" }, - { name: "description" }, - { name: "serviceType" }, - { name: "freeTierType" }, - ], - delimiter: ",", - encoding: "utf-8", + columns: [{ name: 'service' }, { name: 'description' }, { name: 'serviceType' }, { name: 'freeTierType' }], + delimiter: ',', + encoding: 'utf-8', from_line: 2, // don't parse header line }); const docMetadata: DocumentMetadata = { // leave it empty as we're not using any files // if you want to use files, use absolute path - rootDir: "", + rootDir: '', metadata: { - domain: "aws-services", + domain: 'aws-services', }, documents: {}, }; @@ -41,7 +36,7 @@ export const parseCsv = (): DocumentMetadata => { metadata: { serviceType: row.serviceType, // only include this metadata entry if value present - freeTierType: row.freeTierType === "" ? undefined : row.freeTierType, + freeTierType: row.freeTierType === '' ? undefined : row.freeTierType, }, }; } diff --git a/packages/galileo-cli/examples/excel-loader/example.xlsx b/packages/galileo-cli/examples/excel-loader/example.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..3fcd9dd78d4ad782700c8a1c8b09555e79eeaee3 GIT binary patch literal 13115 zcmeHtRbU)RvaMLMn3)+YX117_nVFf{VrFJp%*@QPShC0hOBPtn47cssy))~b{d@20 zZhd5BS5-u3b)U#Q87JhWK*3OfAb_BNfPjdAB%S7#ZGeG*C?SA=P=KI7w1n(zolR_= z^^`sAO`LS-+-9wO2SYhR084_vv{7tgN>$f5;avA6eGB%sIB7hH#MQVrh1=Nu^r)YLb{!(64Rsu9UkBGqapZjJVITv9GB;yhEAWOT$v98sp)s?M77iKx-a`|OO_vj8%0eaVLy@=bcY;*s zlQ;#l%05ZXP9oT0Exe5Eb%>*GH|%INOi2HrnWN{1=Hc~@ZZ#lNs&UGU%UhF7?bb0XszjoqTEn}R>r@*;p--;ZyBr&{5`A$u;1PG$06J08y&vXkzU| zPxrI^Z*=}24#~f~dS!x)+yDb?$eH+a=;+0*)|l&)Q|)D^9z`BGz>B%<>d!gYw#bZXe|P(I;?p!22&Xb#J0Y#82G11}0Hom7R? zwy@_NCQfJiEu|Fyfa4G2ls=wIM;moAG+U|m9L(r0<>Dk zU;uXvz<_|TfuMlht?B=W6E{0YD?>XwtDlS6KVt?Mu%ZE;{l9&5CiPkV!c0(C(5#O` zg6le_izii(Zp$gKbirVLINo~~tqouDTGxOC9YHz>iTgKx(v`J!x3w_2Yh~^V!f-=G zb0@WhX2o*{Zy$FEfl8Zv95V%hSg?-cSKFtM=so*z>GgOh>J(JWy;Bj%ak%CT;-!4J z?(AIWV5aDu=xaY#LL7?-q5NKg2(&PxP4NAI=*jA{HhYKu-`WEuPf1OB;sLiCH5e z@K9gQxFsD5hUqP=)RWxZ9^E%DxDTHfyJwH#bxJC!JRFgoLPS?3(`Cl^zdmE_X1U-? zgRf%0f8cd}UL30F$vUfC+tBPV0n=|!SlVa_M$E3P3pgEYHXm(ht_GG7o*5+#RWV5!jH&y<&YMk=*$gEUNH)mKo|k>6ObRgSm4t5|$-lZW$c-a^PxRh^3Suhfz+ z)svr-id{oDF|{|lPm{^*kaNjOw6%H4&sOW8mu9T|gxa}#mGo1xC((%#ZZ8zQoFRDV zsxC+~Lnog!!eN&uRuc$U`0w>?*RdC4}< ze!=*326h}mv+7?AtuY7PPAi<>*C~V=O^hXKRm6u(J4$OEr$4+UZb@d3AX70G<`vF0 zhfeKmSfIdR8*(O3H7YMA5R5w(Gd&$CnWf_(zun{(m7`|2G54iAlzY|uF#Ry!M$Ld? zKR4Q01bgISWuJcR*!tCzPfyq*XR@GzXR^@S!39f){K2tK`~Bta@ih&SqXrS}b+_+~ zf^iIRKttV{pP|(xDex19bRtA$Nxp8GzwM*-G z`I2LsKz;aGgI?ew0B>yu0L0= z$jF2;;n@fIl@gg%%PUK_lqdMJ`8Y|KX`VSC=g9V(O%H4q9^+;E_B5!7&~IQZlwf%F0iop!!UH_6hV2)Z(3{B6Fx#9vk}pd34)7!QX`o z2D&I)E`XY(fdc_y{uwS#<|Zc2PV~P{EI%jTq`AqMH9|z7Ew4}ApxfQUF-mSmLmD>h z5$!GIhtpU)4pAUcFvf|UJ|i(YRgIyh^!N;T zugmM}PUr>B(JTjf+Za&K23HpYj~`zVx%@}P?en*FqI{@?f@-Y%0*K74T?V-9>mXv8di=e(-(HP-(GOeH^IkQ8M=; zwzP5XjG{DCO`i4&)%_B3$Y&;1X6lvI`K?M7AGDc~NLCxgN9#(m5=VLf@nn-2*5XinsMtosIlN6GOlv z{I-uSD$j;t9``h8L3#2Ysxp^nrSd{&KG4LH`;N@3%{~jq0d`3{9O1 z(+snkBIUUBw11t{B}{KYu_Uy_0~y&v8-uQ>rJ~tY+R8!dK86W~ zSy6Gy@=qS{H){X}Vz(?L5YRB;&zJ?1o)m>-^3L`F=KZtOTCT4nlFb;@$TH}IuyuY4fduCoHTn=#NPKIrDM!F2dDMt_ zKS?h72rgdGMjATJC&emEl7xHRKtp*iA0{G_W4L5VKd-V*xo?c|f^bokn`-5CWchVF z1NDMo!3T<`ctoq0204t}_}gA{ca+G;zUB{PFZ&oR^yssytZ%l2{`rhiZ zPM1IWEawQJf;7E8>4BDNkK7!+X!bPEl>nQw1SS_ZFLNCw+r}Bd$v-aUcc`7IOrUSf z=;<`H;g!b*FXbuw)rJtjwr`2R)Cf@VX%B>Eo0gazE#;x=X$>q%o#@K9TwBQtOE|WM z&;>VHy0xvM8TTK=plrYf33Me;O)JE~RU9iSNvjjH?`lS!GVuZVgD8?pY>y4W%FRI4 zw?pbw<=S?Nvhn}@CCdUlSDK#Fcl^1=!dK0DBijo4vtATKhxwb zvJ=wh@Or(T|F{b6;q|*dco@*DZ)>8KvV|m5QaW9X)q8t+!PwC2c|AY8VE?f|anV26 z^ZYQ8+Vgh7byK_j6^*{z=koGLBF3iA&AwbL-s&1IUfMZPc-?vRH={H1NP__Qrwd^I z>_G;>!GsS;2d<^36QdxyT7-xFF1089Yq;ve;GH}@Rx9lU7j2|5={2Ht;9rfRTru6a zw#qXm&d=?0q}LO#+QK`+XX33+=_D(G?)I7U)V38@qH9g|;3AO2i#ht{lzQrfqVOs@ zgu-^0c$v1PYs0Tk5o?0N=E;N{^~n_J8ifqQCi+bXKdxR*ZrIcelv*wFdK;4%0LH=K z8&gv(x{YR-iuFxB7fgWhs9r!1F zok6w)DaV7kwn$9ocwX1#Xn7u|Rq2G$L0@usB9VBvAPEfb*cEPJULjohdd9CU@0$Bx zOo>~;zguP`QG`93OySjaMx}QVU^oZXMw+bhG%q(zhBI?>U6m!Tc3>(wM-5|oweUHq z&loUI?6=LT5$h-89ZOcyj83WCWa$H&B$Qiyp>j-xqA|IYm_RNlfm)T+k*(LZMIZw3&e!!5>(Iasb4W(h0>WO~ptz%E)Yu7NMueZT_ z(hY{?ZHYyA+j2XJs9+VyV-Nxb4U4fJ7>4$$Eu3AUX?>cMxtz&{0E#NA+J%z%J$h(5 zyq@COZ5-bX*a-qWR_o#^i7S)RWM4R-;oTj4B;u0HFmJ}ZBiny)G9unWy#gNEk5d%GplwHqq1DiC6do3w9)R??W>8C4BEl`iU; z$Xu2VEN@89Oc?8|w9@Y2Vd-K~-X&5*OA_VW5X~^h5Qy>ZJ@;hFlg4m+dgua^T$^DV zjwAD7Gy;;92r)%#06DqR%pkYzLz5*`3pELg)dR`_=D?CWL>tM17Dj`E9``610zjHup1= zj7F#IKtw}>!dfHqdnj1B1-5$|7f}x0i)sq~(d^HfE+5_>NoLFt(~ta`s1Xgd*~v*k`{qk!4Y@A4Oq+yl(1WNPq?nJ?ToLSw zsXFmet9|G~jj*L3ub>S-fAk2fZ7?I^YEd(?M0dKgOFJ2i6d5V4_Zg$<+v9e(_KLT| z84_XkQ`2~!hK;LbuxS%7C0Lhi;mq+Du3+6Ntur{!_1alnp7SmeIQZ2?Tlph)=qAS& zEhtMe6W>COQpjXU?$Q>Vm%JB38YBH(Dj(x+pgYTs=C{Ay&1>{uyk!A6|+RwZP=pzBxy48xTX{BhEp*dn@i@|bx!~6LvB0*E@&lEC@4 zpAs@hB3X~oyk`!mbI7R7woutt@u**q_FrFN%!nkH#Dn0eeS>=mTHJEk%&tdffQ3cD zFsL_%mQw}676X!r`tWhr8xN|YoUb8~JQ3=#A}f(RGSK@aPws^&Uua>iwW{<(4~_eV z-fj1diob-)-WlX;xWG(F`tjV{LEFfMY2x73kR&lzjPC~t(OU_%)30cj2lL|dZT*8( zW~E`jls*XXKoQ%pN0WmG{UVh$8f{t*b?Z^Do#q^&Zk#yB)kv`eLrzK;Nl?JBr2-s@ zsJh?YMU~ytO_&?|i5|qED0VV#?!)-;#~gH+HNl>L+-tEl6zlj<0U(uf@%T1 zNu@MqCuQald|&~QJhKEJPvHz=V)y4mgY;1$53C&z!RpKJ%x0_~TbDp1nO&ffPA<1$ z)5ovcvbMFmrxFU(OGJFRjah{#r{dl}#o~W);v5nIX}h!oHf;Px|0i8bnpJ=XAwu;3 zRuKj{x>#iB5Ii0k_Kw%4jznv{`<-C6$6AX^50bAa zNT$AsPLjO4lnmr)5Sx!PK4mxFww~ar)j{T|H$ncM&WkK}yC$=txv#8}DM(Zbfu=_i__l>2M}XzoH-=11gf`he3i#DFT4P(b@7 z-`vT9>9|rnibNQhSHW`6=f%8Z9iju=k&*C6{8_s9_v^z{xAUlY+F%U_K292-AaWxi zR+{dbQ(1bLt)f7M7?7z5h_==Yzh?#$S;D#ivmv%mk5U@-8wF}S`Pf07)|8&f-!Ur^ zj>5*z(HT9|bhEO3=(_6jfn+#~G%kL0`r{r?N42~R4Vf_J)@RGjXEE|=Mb9%$mY8@g z>fspU*<=gfom-$FsiE(bmx&oH@u%3!(X@Wz@O&y?Zio187ND>n<~V~2atH>Yg#;T; zXoJ*PXdTj7)7JCOue87rpBP_)hJw>48zskI%v439OwMzT+&r$nD*>)>nqFUk$Oh~5 zqru?mq8+q-5P8A|oSt313&bs(O)!xZ_ga4dMUZXLW&5-;j$<4b)-kD)tfC8!t0J}h(d}}(pf)$G6%1&F zd9qgpC&F^?cJ86c*?SI8_4l!%_xNTXBAq%ko0<{Xi^Sp0=Vc|Vxt{vqGvniM#h_Oi z4boAX_QMY)d5|cQQs&Cg*;9nT&$cRhPPteN*R{6gTTh>SDZjeBaHDozc~dHj3f+#u z?@(?H8Ar_pH|Q$2b~k-#w%4vqhK)HPrcRzI2t2ej$?BlgNlO3;ATF;r!x} zjA6ndC$Lzx8xr5#^!TYOvDdZ>Ie|<;LwP7c8@N>AeX0a%&zD7ZZ;~huW!RXB+X%0(h&Nat*r zRf!agGsHs> zzM<8#(`*{g!&4<>I%RTLve5ThJg8he5q!~*)uicV^}G_k>Eht}GJqzE&q$U$7+1NVIyep8NQj--Hh2 zpK+xeF;Pt8h*CTdZwyD)ZJd3UsbM|;0J@3w=!1jGxK4!Pq5y|0ufOFXG<|7<@mlAx z`@njzT9Q-ERW1%Hq9B4z89|*ng^g$YT3m9SEQV&0NBQdpo^w_JCrDDK+SdcD;I*eumtZnugv~C9SBz__tW3_L30mVHZ(F~OhI-HxX*^t(hYRd1 zeUz&QhhdFuGzQ%oj6qJIZLf`2Lo~4wru}X$3`Yt$a~aMSEcbTLO#ngm&9JN-9vF8Y zLwc`eimi3t?$45Y@pv}MV05OhUJsbYC-{Ii#qGdZ5{}_4Z2NSstX+I87;^A~iS79$ zns{jNJ#3rhMbzmbcf$4Fe|*TeQOELu9ERx%rtwuP>~ao$;_&Gl6KPLIJ!6dCX3-e+w4tiktW{c#iNJPPEw6=Y z4sTJc(+7eI;Dp(IlFN0_%Rafe*ZVMU^|iBT$a|48@2zxXzTR^8eFP|A@*Ay3=P_~h zz7rOI!qOQaRUB?O{~T%-|MUx4P(sQjpaqX0G=d+H=rYzah9L0v@q};M#6%;>^k5tUOlbfdl?B9z4_fGaO`>2T98pyOGl9Mo zggl5rx6A?1lqv}L_%^ESiU~t3PpM{OS*yH5u8LdO7t>Pl9W<8DCA0xti2uhk(hxWA z<`nn?oB{XuKR?X&g3q^mM^KlX(PUY!?ao4%2ahw;gLYZz(q|rA#O~=sDxoh3ndsJy zu3;C>G7}oDv-!<=uF9YaXrLKtfX?rbUCAW$PtmF*UcO&dt{q~nvSaJt=r5qKNQ-8} z<3>dPexXzcl;2lS25ArwDmw&n!HRA~HxdYaKc>!r%cAbA|3N*jNNy1(gGIgIj8|f_ z<7s=;RDM(sQ6H;|0X>!k&mRdr&6^s~o7{wgk>*2-9Eo@J`|gG4`12Z`4ifsziE<@d z4Bbfs?nL6XkDnc`MT*F4!guQ7Z3oo0LvcqmqYI7*?N8(r_b@+u9{tImQ7|J%6h5O= z8|U<@^Tho6-k#5;#5*<;!%LJruEa~zKE%n`kFCu$D;e{WfNv*#B)V5MRb*Ae(G1m~O+keejquCZ`e0db0V0 zpg+g=_1e%K18iV&hloZLL`sv%X-VxUbIsvV}mF|olpe>cO!-^vA^ z2-RKX03zJ{pSO0u(yLJk696)dC~^n>hyZqnbYmYZT8m4{7-g!~Xwgwz8ZVNDkX&T+ zbjDqDO#FduH4MRFs;hJ0WkIAlT82P$)}Z;>!qX9QyMZp`*|l5xW;Rc z96oD4Kh4}q?t3IcL{iMnImVA=2A?C5SnkrZd$)4?xF$jA)^i@lfX|fTRVzPVWmwR` zWxtEo>aQIj1h=l@uw*a@;gILa^Wz^M+cejF-)C_OKk`FXotLN}Q8Gj-P_aPds-FGJ zh3vPk>7j^79Bx{^ttQkdPwtPf4%Tds7gKk~IYbr>r(_$1!?L)rv_9`MY(!Q}vo9ZL zzkT1Fl-OFAlP3hZUM80`e9mqPbw3AhaU^|oCPZ$7x`fLSC`;i>Mr%H|Lk@RJ(tl&! zn6~rmSg1dXasE2cpyFptAc{IvGCR;4OZ{A1Vn=vq)Vq!?6u!dpVgjS9uQVgADvD)* z#&jXo7!?b{yt}{h5>+{V3`2%@Uz->&63+3ce` zj&I*77_n#w>CS|<<4#*$Ua7w4|B2!C&rMWP{5n83fECpXJ_lmLe5J(;9|y<=7nT_U zY(8FAER~3Mu1mMxGP0UsErG&f5tb{A99$2 zT_yt}|3@5 ze@>M_%~p`;(mC-2Cum9SyzS=sW{<0z9w&@KyDYZz%sC9$YwN?ag^!>g6zB(I($<-C zqTxDp;!@yBSge?>1BqCG9H!NSVQ@{@@q^4tIDJ3)mmFpZki&dx{wjz0VP0dRPnK(O z(7b%(*q~}8L8@Zo(j^CEE)Ms*gy^+|d~zd`l_Pm=_|8>nVu7F1kSMAJ_-~&H@qfx; zC1pV@u6y}*_bmk*DF8Wa-dmR?tG|O)YR47{;YXj-(s|ZLAP8m4ED7qGbFg6+Z><@u zkRFtbFTxS*S1+CyZu3Yl=atF8IWy0*I=BaVgvCL+_%hGoC1-heLPZ^Da72>@r$5y& z_<(+6CCA_p>2{`y`DtP1r2VoS)B4X5mdR?n7*m>14kd}B>0BXUt`D}7&ml?7f-a(` zY8p4Wqc2hNIti#NCs?XiN6M+N4^`1&7L>0rpLl8copc{3wKzhabej%O&s` z(GZaaiU`M-?=E~B;l^hRVD((JnN;fM6MiJLZEx@ijd`>wyv=g7os~J3t*VyMM3hCS zCF!8ORvbL!%XMe4!Dm9OAr@Y0{6*c_k&0ufM1V{B(6?`UW5L~mek z{}Z=>lC%Go&j9d|rSvQH2uRlWA$l)cM6c6PhDf{CeZtYq>jNRRna+|P5wwwr!z5X$ zA+RBd>AGFO>AAkY7az+M(g}y~nfX#QyZb&I4BN!X#?|7w^~L3a6*-{yySzq_h4Ucd zx-kL&Xj2P3uLW!%k+gVW!YJ)FM=7!u6tgVO6zZ3y566!>){%lVolTZ{h57f?64gdL zh#9z7Fzi60yxRr&cY%AVP0#)Fw+CtV7>y&(p(0)7Up35)Vio_ zaIaI@H;)swZ#0Y-nqw!ozk%o(L~2dcOg7E?jjL97b@e1Xm}{C*og$e(@+s>q@CH3M z&vjGysnjrFVeQP_=PTk6XdwI7hh*{WQ=U^l(CXe^cwP#KiW9KC(fmHonLRR|_Np%M z{`rg&fi|i>qp4KJtUkmzw@w2+#!&=aw~B`ag0Hpj`;Hm-1v+ILm!1~*9X>}0OpQTJq=3I|dQ66iyjI^*^x*ZiNCsyxAk)pvm4*B0+EEL=k6oRjNi)tJ zF&+qYNwC~o0Do!1UKS)&`kksdIE-QtN$Sdj#<)y>Q?OSBoO;q0NKKJ;|74&yVa7+r z5&k@5+byi|ptIE!SRV@~OUySz&KUz#8H;zLU_zp9f%!jB$8;6XW#_D|XQ7~E^Zk)g zxv&uoJ--t#&%JQY5K??rG_-k^_39{D4Q$aL+2C41swl@+E*uWIBbZNJTo-Dvq+Fz< zfhUy$my9r}l$Yw-ln9iz^IUXaRgq+N1`_UF4PxJ5`hI2Qc5WBAFllJh9bwU!(wO&To`a zI}8~$g&IuV;sq;5wo4n&bfL`(r#jDC4onim^C&|>AHI0=hQwKEwWOc>E*SOoTejsLAU>31)Eztw;I=>;3`y8~Y3_iB*e z9sI6f{plbb{cnfyOV9e<%kQeepI)r6etG#f4dHhWzo&oy^za?$4-fyF4F28p_nq3G zrp}~)`wGAIZNGc@oe%%%MVaDnz5HUwzkB&tR`RD0fS5uJ1oS&c`Q7?oXYs#U6Vv|1 b`k!;Uyc9S9uRqh}a6pOx$j|@OvVi^v8n7SJ literal 0 HcmV?d00001 diff --git a/packages/galileo-cli/examples/excel-loader/excel-loader.ts b/packages/galileo-cli/examples/excel-loader/excel-loader.ts new file mode 100644 index 00000000..47739dea --- /dev/null +++ b/packages/galileo-cli/examples/excel-loader/excel-loader.ts @@ -0,0 +1,193 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +PDX-License-Identifier: Apache-2.0 */ +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import ExcelJs from 'exceljs'; +import { isEmpty } from 'lodash'; +import { DocumentMetadata } from '../../src'; + +export interface ExcelLoaderOptions { + /** + * Path to the excel file. + */ + readonly execFilepath: string; + + /** + * The domain to use in the root metadata object. + * @default "my-example-domain" + */ + readonly domain?: string; + + /** + * Additional metadata to use in the root metadata object. + */ + readonly rootMetadata: Record; + + /** + * The name of the key to add the worksheet's name as metadata. + * + * E.g.: if the value of this parameter is "category" and the worksheet's name is "Sheet1", + * it will be added as `category: Sheet1` into the document's metadata object. + * + * If it's not set, the worksheet's name won't be added as a metadata. + */ + readonly worksheetNameMetadataKey?: string; + + /** + * Whether to save the document metadata as a `metadata.json` file. + * If it's `true`, the metadata will be saved next to the excel file and its path is returned; + * otherwise, the `DocumentMetadata` object is returned. + */ + readonly saveMetadata?: boolean; + + /** + * The index of the header row. This is 1-based (i.e.: excel row indexing) + * @default 1 + */ + readonly headerRowIndex?: number; + + /** + * The start index of the rows containing data. This is 1-based (i.e.: excel row indexing) + * @default 2 + */ + readonly dataRowStartIndex?: number; + + /** + * Column selector to include data in the `pageContent`. + * Use column index (1-based) or column letter. + * + * The content will be added to `pageContent` in the order of the selector items, + * using `headerValue`: `cellValue` lines + */ + readonly pageContentColumnSelector: (string | number)[]; + + /** + * Column selector to use to include data in the entry's `metadata`. + * Use column index (1-based) or column letter. + * + * This will be added to the entry's `metadata` + * in the format of `headerValue`: `cellValue` + * + * @default undefined + */ + readonly entryMetadataColumnSelector?: (string | number)[]; + + /** + * Whether to use base64 encoded metadata in the entries' metadata section. + * Set this to `true` if you have metadata that uses non-US-ASCII characters (e.g.: Vietnamese chars) + * + * @default false + */ + readonly useBase64EncodedEntryMetadata?: boolean; +} + +export class ExcelLoader { + readonly options: ExcelLoaderOptions; + + constructor(options: ExcelLoaderOptions) { + this.options = options; + } + + async process(): Promise { + const documentMetadata: DocumentMetadata = { + rootDir: '', + metadata: { + domain: this.options.domain ?? 'my-example-domain', + ...this.options.rootMetadata, + }, + documents: {}, + }; + const excelFilename = path.basename(this.options.execFilepath); + + const headerRowIndex = this.options.headerRowIndex ?? 1; + const dataRowStartIndex = this.options.dataRowStartIndex ?? 2; + + const workbook = new ExcelJs.Workbook(); + await workbook.xlsx.readFile(this.options.execFilepath); + + for (const worksheet of workbook.worksheets) { + console.log(`Processing worksheet ${worksheet.name}`); + + const headerRow = worksheet.getRow(headerRowIndex); + const keys: Record = {}; + + this.options.pageContentColumnSelector.forEach((columnNameOrIdx) => { + keys[`${columnNameOrIdx}`] = headerRow.getCell(columnNameOrIdx).toString(); + }); + + // if there are no data rows, skip processing + if (worksheet.rowCount <= dataRowStartIndex) { + continue; + } + + const lastrowIdx = worksheet.rowCount; + + for (let rowIdx = 2; rowIdx <= lastrowIdx; rowIdx++) { + const row = worksheet.getRow(rowIdx); + + const content: string[] = []; + this.options.pageContentColumnSelector.forEach((columnNameOrIdx) => { + const val = row.getCell(columnNameOrIdx).toString(); + + if (!isEmpty(val)) { + content.push(`${keys[`${columnNameOrIdx}`]}: ${val}`); + } + }); + + const entryMeta: Record = {}; + if (this.options.entryMetadataColumnSelector) { + this.options.entryMetadataColumnSelector.forEach((columnNameOrIdx) => { + const val = row.getCell(columnNameOrIdx).toString(); + + if (!isEmpty(val)) { + entryMeta[keys[`${columnNameOrIdx}`]] = val; + } + }); + } + + let entryMetadata: Record = {}; + if (this.options.worksheetNameMetadataKey) { + entryMetadata[this.options.worksheetNameMetadataKey] = worksheet.name; + } + + if (this.options.useBase64EncodedEntryMetadata) { + entryMetadata['json-base64'] = Buffer.from(JSON.stringify(entryMeta)).toString('base64'); + } else { + entryMetadata = { + ...entryMetadata, + ...entryMeta, + }; + } + + const pageContent = content.join('\n'); + if (isEmpty(pageContent)) { + continue; + } + + documentMetadata.documents[`${excelFilename}/${worksheet.name}/row-${rowIdx}`] = { + metadata: entryMetadata, + pageContent: content.join('\n'), + }; + } + } + + if (this.options.saveMetadata) { + // save it as a metadata.json file + const outputDirPath = path.join(path.dirname(this.options.execFilepath), 'generated'); + if (!fs.existsSync(outputDirPath)) { + fs.mkdirSync(outputDirPath); + } + const outputFilepath = path.join(outputDirPath, 'metadata.json'); + + // save into a file + fs.writeFileSync(outputFilepath, JSON.stringify(documentMetadata, null, 2), { + encoding: 'utf-8', + }); + + // return absolute path + return outputFilepath; + } + + return documentMetadata; + } +} diff --git a/packages/galileo-cli/examples/excel-loader/index.ts b/packages/galileo-cli/examples/excel-loader/index.ts new file mode 100644 index 00000000..704df669 --- /dev/null +++ b/packages/galileo-cli/examples/excel-loader/index.ts @@ -0,0 +1,45 @@ +/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved. +PDX-License-Identifier: Apache-2.0 */ +import chalk from 'chalk'; +import prompts from 'prompts'; + +import { ExcelLoader } from './excel-loader'; +import { DocumentMetadata, IMetadataProvider } from '../../src'; + +export class MetadataProvider implements IMetadataProvider { + async getMetadata(): Promise { + // build the metadata + const { excelPath } = await prompts({ + type: 'text', + name: 'excelPath', + message: `Enter the path to the excel file (${chalk.grey(`CWD: ${process.cwd()}`)}):`, + }); + + const excelLoader = new ExcelLoader({ + execFilepath: excelPath, + domain: 'aws-services', + rootMetadata: { + collection: 'example-collection', + }, + worksheetNameMetadataKey: 'serviceType', + saveMetadata: true, + headerRowIndex: 1, + dataRowStartIndex: 2, + + pageContentColumnSelector: [ + 'A', // service + 2, // description -- note, column index + 'D', // url + 'C', // free tier type + ], + + entryMetadataColumnSelector: [ + 'D', // url + 3, // free tier type -- note, column index + ], + useBase64EncodedEntryMetadata: false, + }); + const result = await excelLoader.process(); + return result; + } +} diff --git a/packages/galileo-cli/package.json b/packages/galileo-cli/package.json index 1cf55499..ae4cfb0c 100644 --- a/packages/galileo-cli/package.json +++ b/packages/galileo-cli/package.json @@ -30,6 +30,7 @@ "@types/chalk": "^2.2.0", "@types/clear": "^0.1.2", "@types/csv-parse": "^1.2.2", + "@types/exceljs": "^1.3.0", "@types/execa": "^2.0.0", "@types/fs-extra": "^11.0.3", "@types/jest": "^29.5.4", @@ -78,6 +79,7 @@ "chalk": "^4", "clear": "^0.1.0", "csv-parse": "^5.5.0", + "exceljs": "^4.4.0", "execa": "^5.1.1", "figlet": "^1.6.0", "fs-extra": "^11.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a062a0f8..0ed4faef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1254,6 +1254,9 @@ importers: csv-parse: specifier: ^5.5.0 version: 5.5.0 + exceljs: + specifier: ^4.4.0 + version: 4.4.0 execa: specifier: ^5.1.1 version: 5.1.1 @@ -1297,6 +1300,9 @@ importers: '@types/csv-parse': specifier: ^1.2.2 version: 1.2.2 + '@types/exceljs': + specifier: ^1.3.0 + version: 1.3.0 '@types/execa': specifier: ^2.0.0 version: 2.0.0 @@ -5891,6 +5897,27 @@ packages: resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} dev: true + /@fast-csv/format@4.3.5: + resolution: {integrity: sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A==} + dependencies: + '@types/node': 14.18.63 + lodash.escaperegexp: 4.1.2 + lodash.isboolean: 3.0.3 + lodash.isequal: 4.5.0 + lodash.isfunction: 3.0.9 + lodash.isnil: 4.0.0 + + /@fast-csv/parse@4.3.6: + resolution: {integrity: sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA==} + dependencies: + '@types/node': 14.18.63 + lodash.escaperegexp: 4.1.2 + lodash.groupby: 4.6.0 + lodash.isfunction: 3.0.9 + lodash.isnil: 4.0.0 + lodash.isundefined: 3.0.1 + lodash.uniq: 4.5.0 + /@fastify/busboy@2.0.0: resolution: {integrity: sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==} engines: {node: '>=14'} @@ -10409,6 +10436,13 @@ packages: /@types/estree@1.0.1: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + /@types/exceljs@1.3.0: + resolution: {integrity: sha512-V3BOkD+eQVEFuYACksKiNEDP3QumTMMrPeXef/F5EAT/MquojQzUwEJt6vwsEwTOZFPfponJMyvdZ0NL71K76Q==} + deprecated: This is a stub types definition. exceljs provides its own type definitions, so you do not need this installed. + dependencies: + exceljs: 4.4.0 + dev: true + /@types/execa@2.0.0: resolution: {integrity: sha512-aBnkJ0r3khaZkHzu9pDZeWXrDg1N/ZtDGRQkK+KIqNVvvTvW+URXMUHQQCQMYdb2GPrcwu9Fq6l9iiT+pirIbg==} deprecated: This is a stub types definition. execa provides its own type definitions, so you do not need this installed. @@ -10594,6 +10628,9 @@ packages: resolution: {integrity: sha512-tfE27I0XNLHjmK6fJh00ZB+0bpyJbz/hp4PDuDtIUlzs2bI8v5Q0QrQYPpV5TR1XtzgPlUoH3ZDSo/++01IBBQ==} dev: true + /@types/node@14.18.63: + resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==} + /@types/node@16.18.39: resolution: {integrity: sha512-8q9ZexmdYYyc5/cfujaXb4YOucpQxAV4RMG0himLyDUOEr8Mr79VrqsFI+cQ2M2h89YIuy95lbxuYjxT4Hk4kQ==} @@ -11592,6 +11629,48 @@ packages: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} dev: true + /archiver-utils@2.1.0: + resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} + engines: {node: '>= 6'} + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 2.3.8 + + /archiver-utils@3.0.4: + resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} + engines: {node: '>= 10'} + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + /archiver@5.3.2: + resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} + engines: {node: '>= 10'} + dependencies: + archiver-utils: 2.1.0 + async: 3.2.4 + buffer-crc32: 0.2.13 + readable-stream: 3.6.2 + readdir-glob: 1.1.3 + tar-stream: 2.2.0 + zip-stream: 4.1.1 + /are-we-there-yet@3.0.1: resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -12238,7 +12317,6 @@ packages: /big-integer@1.6.51: resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} engines: {node: '>=0.6'} - dev: true /big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -12251,6 +12329,12 @@ packages: resolution: {integrity: sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==} dev: false + /binary@0.3.0: + resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==} + dependencies: + buffers: 0.1.1 + chainsaw: 0.1.0 + /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} dependencies: @@ -12258,6 +12342,9 @@ packages: inherits: 2.0.4 readable-stream: 3.6.2 + /bluebird@3.4.7: + resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} + /bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} @@ -12375,7 +12462,6 @@ packages: /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - dev: true /buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} @@ -12384,6 +12470,10 @@ packages: /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + /buffer-indexof-polyfill@1.0.2: + resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} + engines: {node: '>=0.10'} + /buffer-writer@2.0.0: resolution: {integrity: sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==} engines: {node: '>=4'} @@ -12409,6 +12499,10 @@ packages: base64-js: 1.5.1 ieee754: 1.2.1 + /buffers@0.1.1: + resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} + engines: {node: '>=0.2.0'} + /builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} @@ -12604,6 +12698,11 @@ packages: aws-cdk-lib: 2.99.1(constructs@10.2.70) constructs: 10.2.70 + /chainsaw@0.1.0: + resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==} + dependencies: + traverse: 0.3.9 + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -13009,6 +13108,15 @@ packages: dot-prop: 5.3.0 dev: true + /compress-commons@4.1.2: + resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} + engines: {node: '>= 10'} + dependencies: + buffer-crc32: 0.2.13 + crc32-stream: 4.0.3 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + /compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} @@ -13395,6 +13503,18 @@ packages: path-type: 4.0.0 dev: true + /crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + /crc32-stream@4.0.3: + resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} + engines: {node: '>= 10'} + dependencies: + crc-32: 1.2.2 + readable-stream: 3.6.2 + /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -13710,7 +13830,6 @@ packages: /dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} - dev: false /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} @@ -14140,7 +14259,7 @@ packages: dependencies: semver: 7.5.4 shelljs: 0.8.5 - typescript: 5.4.0-dev.20231105 + typescript: 5.4.0-dev.20231108 dev: true /drange@1.1.1: @@ -14148,6 +14267,11 @@ packages: engines: {node: '>=4'} dev: false + /duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + dependencies: + readable-stream: 2.3.8 + /duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} @@ -15078,6 +15202,20 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + /exceljs@4.4.0: + resolution: {integrity: sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==} + engines: {node: '>=8.3.0'} + dependencies: + archiver: 5.3.2 + dayjs: 1.11.10 + fast-csv: 4.3.6 + jszip: 3.10.1 + readable-stream: 3.6.2 + saxes: 5.0.1 + tmp: 0.2.1 + unzipper: 0.10.14 + uuid: 8.3.2 + /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -15228,6 +15366,13 @@ packages: resolution: {integrity: sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==} dev: false + /fast-csv@4.3.6: + resolution: {integrity: sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw==} + engines: {node: '>=10.0.0'} + dependencies: + '@fast-csv/format': 4.3.5 + '@fast-csv/parse': 4.3.6 + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -15751,6 +15896,15 @@ packages: requiresBuild: true optional: true + /fstream@1.0.12: + resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} + engines: {node: '>=0.6'} + dependencies: + graceful-fs: 4.2.11 + inherits: 2.0.4 + mkdirp: 0.5.6 + rimraf: 2.7.1 + /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} @@ -16563,6 +16717,9 @@ packages: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} + /immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + /immer@9.0.21: resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} @@ -18592,6 +18749,14 @@ packages: object.assign: 4.1.4 object.values: 1.1.6 + /jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + /just-extend@4.2.1: resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} dev: true @@ -18981,6 +19146,12 @@ packages: dotenv-expand: 10.0.0 dev: true + /lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + dependencies: + readable-stream: 2.3.8 + /leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -18992,6 +19163,11 @@ packages: prelude-ls: 1.2.1 type-check: 0.4.0 + /lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + dependencies: + immediate: 3.0.6 + /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -19004,6 +19180,9 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true + /listenercount@1.0.1: + resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==} + /load-json-file@4.0.0: resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} engines: {node: '>=4'} @@ -19098,25 +19277,50 @@ packages: /lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + /lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + + /lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + + /lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + + /lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + /lodash.get@4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} dev: true + /lodash.groupby@4.6.0: + resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==} + + /lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + /lodash.isempty@4.4.0: resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + /lodash.isfunction@3.0.9: resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} - dev: true /lodash.ismatch@4.4.0: resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} dev: true + /lodash.isnil@4.0.0: + resolution: {integrity: sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng==} + /lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} requiresBuild: true - dev: true + + /lodash.isundefined@3.0.1: + resolution: {integrity: sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==} /lodash.kebabcase@4.1.1: resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} @@ -19170,6 +19374,9 @@ packages: /lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + /lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + /lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} @@ -21095,6 +21302,9 @@ packages: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} dev: true + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + /param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} dependencies: @@ -23237,6 +23447,11 @@ packages: string_decoder: 1.3.0 util-deprecate: 1.0.2 + /readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + dependencies: + minimatch: 5.1.6 + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -23942,6 +24157,9 @@ packages: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} dev: true + /setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + /setprototypeof@1.1.0: resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} @@ -25074,7 +25292,6 @@ packages: engines: {node: '>=8.17.0'} dependencies: rimraf: 3.0.2 - dev: true /tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -25129,6 +25346,9 @@ packages: dependencies: punycode: 2.3.0 + /traverse@0.3.9: + resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} + /traverse@0.6.7: resolution: {integrity: sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==} @@ -25513,8 +25733,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - /typescript@5.4.0-dev.20231105: - resolution: {integrity: sha512-TN7QRSjarOvoxvHuZdVmofCnXJYklxsiZ1tyJKiKkghPWXwrkQ68R3NN3vhtS8B+jIeZoETKssmfbmhCl8rwxQ==} + /typescript@5.4.0-dev.20231108: + resolution: {integrity: sha512-/DNtrqpbir9XaRxE6qwjhB94pCZzw/9R/PhB8309frJBEBGZ5qSDqstl7YYbhWbqs+zWpCCbwBjWDGlz8wn8GA==} engines: {node: '>=14.17'} hasBin: true dev: true @@ -25696,6 +25916,20 @@ packages: engines: {node: '>=8'} dev: true + /unzipper@0.10.14: + resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} + dependencies: + big-integer: 1.6.51 + binary: 0.3.0 + bluebird: 3.4.7 + buffer-indexof-polyfill: 1.0.2 + duplexer2: 0.1.4 + fstream: 1.0.12 + graceful-fs: 4.2.11 + listenercount: 1.0.1 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + /upath@1.2.0: resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} engines: {node: '>=4'} @@ -26685,6 +26919,14 @@ packages: resolution: {integrity: sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==} dev: false + /zip-stream@4.1.1: + resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} + engines: {node: '>= 10'} + dependencies: + archiver-utils: 3.0.4 + compress-commons: 4.1.2 + readable-stream: 3.6.2 + /zod-to-json-schema@3.21.4(zod@3.22.4): resolution: {integrity: sha512-fjUZh4nQ1s6HMccgIeE0VP4QG/YRGPmyjO9sAh890aQKPEk3nqbfUXhMFaC+Dr5KvYBm8BCyvfpZf2jY9aGSsw==} peerDependencies: diff --git a/projenrc/framework/galileo-cli.ts b/projenrc/framework/galileo-cli.ts index fb9526e1..eb3ed1fd 100644 --- a/projenrc/framework/galileo-cli.ts +++ b/projenrc/framework/galileo-cli.ts @@ -52,6 +52,7 @@ export class GalileoCli extends TypeScriptAppProject { 'chalk@^4', 'clear', 'csv-parse', + 'exceljs', 'execa', 'fs-extra', 'figlet', @@ -71,6 +72,7 @@ export class GalileoCli extends TypeScriptAppProject { '@types/chalk', '@types/clear', '@types/csv-parse', + '@types/exceljs', '@types/execa', '@types/jsonschema', '@types/fs-extra',