@lakeql/cli 0.4.1 → 0.5.0
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/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +8 -8
- package/dist/commands-metadata.d.mts +31 -0
- package/dist/commands-metadata.mjs +1 -0
- package/dist/index.d.mts +29 -1
- package/dist/index.mjs +1 -1
- package/dist/pull-metadata-D8Z0WHKQ.mjs +1 -0
- package/package.json +13 -9
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/cli.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{
|
|
3
|
-
`)}function P(){return process.env.INIT_CWD??process.cwd()}const se={sourcePath:`.`};async function ce(){let{config:e}=await m({name:`lakeql`,cwd:P(),defaults:se,packageJson:!1,globalRc:!1,rcFile:!1,dotenv:!1});return e}async function F(e){let t=await ce(),n=P(),r=e??t.sourcePath;return c.isAbsolute(r)?r:c.resolve(n,r)}const I=new t(`--catalog <catalog>`,`catalog to use`).env(`HIVE_CATALOG`),L=new t(`--schema <schema>`,`schema to use`),le=new t(`--table <table>`,`table to use`),ue=new t(`--type <type>`,`Show tables or views`),R=new t(`--source-path <path>`,"Base path for generated code (resolved from the command invocation directory). Files are created in `schemas/generated|custom` inside this path.").default(P(),`command invocation directory`),de=new t(`--skip-registry`,`Skip config registry generation`).default(!1);function fe(){return new e(`create-registry`).description("Generates the config registry to ensure the type-safety while using `createPermission`").addOption(R).action(async({sourcePath:e})=>{await z(e!==process.env.INIT_CWD&&e!==process.cwd()?e:void 0)})}async function z(e){let t=await F(e),n=await h({fileName:`config-registry.ts`,nodes:v({configPaths:(await y(`schemas/**/config.ts`,{cwd:t,onlyFiles:!0})).map(e=>{let t=c.parse(e);return c.join(t.dir,t.name)})})});r(c.join(t,`config-registry.ts`))&&await o(c.join(t,`config-registry.ts`),{force:!0,recursive:!0}),await s(c.join(t,`config-registry.ts`),n.text)}function pe(e,t){return{baseClassName:`${x(b(e))}_${x(b(t))}`,queryName:`${b(e)}${x(b(t))}`,mutationName:`create${b(e)}${x(b(t))}`}}const{factory:B}=S;function V(e){return B.createIdentifier(e)}function H(e){return V(e)}function U(e){return B.createStringLiteral(e)}function W(e,t){return B.createPropertyAssignment(V(e),t)}function G(e,t=!0){return B.createObjectLiteralExpression(e,t)}function me(e){return e?B.createTrue():B.createFalse()}function he(e){return B.createParameterDeclaration(void 0,void 0,V(e))}function K(e,t,n){return B.createArrowFunction(n?.async?[B.createToken(S.SyntaxKind.AsyncKeyword)]:void 0,void 0,e.map(e=>typeof e==`string`?he(e):e),void 0,B.createToken(S.SyntaxKind.EqualsGreaterThanToken),t)}function ge(e){return B.createParenthesizedExpression(e)}function _e(e,t=!0){return K([`t`],ge(G(e,t)))}function q(e,t){return B.createPropertyAccessExpression(typeof e==`string`?V(e):e,V(t))}function ve(e,t=[],n){return B.createCallExpression(e,n,t)}function J(e,t,n=[],r){return ve(q(e,t),n,r)}function ye(e,t=[],n){return J(`builder`,e,t,n)}function be(e,t){return B.createVariableStatement(void 0,B.createVariableDeclarationList([B.createVariableDeclaration(V(e),void 0,void 0,t)],S.NodeFlags.Const))}function Y(e,t,n){return B.createImportDeclaration(void 0,B.createImportClause(n?.typeOnly??!1,void 0,B.createNamedImports(t.map(e=>B.createImportSpecifier(!1,void 0,V(e))))),U(e))}function xe(e,t,n){return B.createImportDeclaration(void 0,B.createImportClause(n?.typeOnly??!1,V(t),void 0),U(e))}function Se({models:e,mutationName:t,mutationConfig:n,hasValidations:r,fieldDefinitions:i}){if(!n)return[];let a=Object.values(e).find(e=>e.root);if(!a)return[];let o=Ce(i),s=Object.values(e).filter(e=>!e.root);return[...we(r),...s.map(t=>Te(t,e,o)),Te(a,e,o),ke(t,a,r)]}function Ce(e){let t=new Map;if(!e)return t;for(let n of e){let e=n.options?.required===!0;t.set(n.name,e)}return t}function we(e){let t=[Y(`@lakeql/adapters`,[`executeWritePipeline`]),Y(`@lakeql/trino-client`,[`TrinoClient`]),Y(`@lakeql/api/builder`,[`builder`]),Y(`~/env`,[`env`]),Y(`./config`,[`hiveConfig`,`storageConfig`]),xe(`./json-schema.json`,`jsonSchema`)];return e&&t.push(Y(`./validations`,[`validationSchema`])),t}function Te(e,t,n){let r=`${e.modelName}Input`,i=Object.values(e.fields).map(e=>Ee(e,t,n));return be(r,ye(`inputType`,[U(r),G([W(`fields`,_e(i))])]))}function Ee(e,t,n){let r=W(`required`,me(n.get(e.name)??!0));if(e.isArray){let t=e.graphqlType.replace(/^\[/u,``).replace(/\]$/u,``),n=Oe(t);if(n)return W(e.name,J(`t`,n,[G([r],!1)]));let i=`${t}Input`;return W(e.name,J(`t`,`field`,[G([W(`type`,S.factory.createArrayLiteralExpression([H(i)])),r],!1)]))}let i=De(e.graphqlType);if(i)return W(e.name,J(`t`,i,[G([r],!1)]));if(Object.keys(t).includes(e.graphqlType)){let t=`${e.graphqlType}Input`;return W(e.name,J(`t`,`field`,[G([W(`type`,H(t)),r],!1)]))}return W(e.name,J(`t`,`string`,[G([r],!1)]))}function De(e){switch(e){case`String`:return`string`;case`Int`:return`int`;case`Float`:return`float`;case`Boolean`:return`boolean`;default:return}}function Oe(e){switch(e){case`String`:return`stringList`;case`Int`:return`intList`;case`Float`:return`floatList`;case`Boolean`:return`booleanList`;default:return}}function ke(e,t,n){let r=`${t.modelName}Input`,i=[];n&&i.push(S.factory.createExpressionStatement(J(`validationSchema`,`parse`,[H(`input`)]))),i.push(S.factory.createVariableStatement(void 0,S.factory.createVariableDeclarationList([S.factory.createVariableDeclaration(H(`trinoClient`),void 0,void 0,S.factory.createNewExpression(H(`TrinoClient`),void 0,[G([W(`host`,q(`env`,`HIVE_HOST`)),W(`port`,q(`env`,`HIVE_PORT`)),W(`auth`,G([W(`type`,U(`basic`)),W(`username`,q(`env`,`HIVE_USERNAME`)),W(`password`,q(`env`,`HIVE_PASSWORD`))],!1)),W(`catalog`,q(`env`,`HIVE_CATALOG`)),W(`source`,q(`env`,`HIVE_SOURCE`))])]))],S.NodeFlags.Const)));let a=S.factory.createAwaitExpression(ve(H(`executeWritePipeline`),[G([W(`records`,H(`input`)),W(`jsonSchema`,S.factory.createAsExpression(H(`jsonSchema`),S.factory.createKeywordTypeNode(S.SyntaxKind.AnyKeyword))),W(`config`,G([W(`loadStrategy`,q(`storageConfig`,`loadStrategy`)),W(`bucket`,q(`storageConfig`,`bucket`)),W(`basePath`,q(`storageConfig`,`basePath`)),W(`table`,G([W(`catalog`,q(`hiveConfig`,`catalog`)),W(`schema`,q(`hiveConfig`,`schema`)),W(`tableName`,q(`hiveConfig`,`tableName`))],!1)),W(`trinoClient`,H(`trinoClient`))]))])]));i.push(S.factory.createExpressionStatement(a)),i.push(S.factory.createReturnStatement(S.factory.createTrue()));let o=S.factory.createBlock(i,!0),s=K([he(`_root`),S.factory.createParameterDeclaration(void 0,void 0,S.factory.createObjectBindingPattern([S.factory.createBindingElement(void 0,void 0,S.factory.createIdentifier(`input`))]))],o,{async:!0}),c=W(e,J(`t`,`boolean`,[G([W(`args`,G([W(`input`,J(`t`,`arg`,[G([W(`type`,H(r)),W(`required`,me(!0))],!1)]))],!1)),W(`resolve`,s)])]));return S.factory.createExpressionStatement(ye(`mutationFields`,[_e([c])]))}function X(e){if(typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(X);let t={},n=Object.keys(e).toSorted();for(let r of n)t[r]=X(e[r]);return t}function Ae(e){let t=X(e);return`${JSON.stringify(t,null,2).replaceAll(`\r
|
|
2
|
+
import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s,t as c}from"./pull-metadata-D8Z0WHKQ.mjs";import{Command as l}from"@commander-js/extra-typings";import u from"node:path";import{readPackage as d}from"read-pkg";import{existsSync as f}from"node:fs";import{mkdir as p,readFile as m,rm as h,writeFile as g}from"node:fs/promises";import{confirm as _,multiselect as v,question as y,select as b,validators as ee}from"@topcli/prompts";import{loadConfig as x}from"c12";import{generateCode as S}from"@lakeql/file-generator";import{generateConfig as te}from"@lakeql/file-generator/config";import{generateInterface as ne}from"@lakeql/file-generator/interface";import{generateQuerySchema as re}from"@lakeql/file-generator/query-schema";import{generateModel as ie}from"@lakeql/schema-generator/graphql-schema";import{generateJsonSchemaFromFields as ae}from"@lakeql/schema-generator/json-schema";import{generateConfigReqistry as C}from"@lakeql/file-generator/config-registry";import{globby as w}from"globby";import{camelCase as T,upperFirst as E}from"lodash-es";import D from"typescript";import{endpointDefinitionSchema as O,findDuplicateFieldNames as k}from"@lakeql/schema-generator/endpoint-schema";import{TrinoClient as A}from"@lakeql/trino-client";import{ClimtTable as j}from"climt";import{createEnv as M}from"@t3-oss/env-core";import oe from"dotenv";import{enum as se,number as ce,string as N}from"zod/v4";import{error as le}from"@lakeql/logger/console";import{Listr as ue}from"listr2";import{parseColumns as de}from"@lakeql/column-parser";import{convertTrinoResponse as fe}from"@lakeql/response-transformer";import P from"kleur";const pe={sourcePath:`.`};async function me(){let{config:e}=await x({name:`lakeql`,cwd:t(),defaults:pe,packageJson:!1,globalRc:!1,rcFile:!1,dotenv:!1});return e}async function F(e){let n=await me(),r=t(),i=e??n.sourcePath;return u.isAbsolute(i)?i:u.resolve(r,i)}function he(){return a().action(async({sourcePath:e})=>{await I(e!==process.env.INIT_CWD&&e!==process.cwd()?e:void 0)})}async function I(e){let t=await F(e),n=await S({fileName:`config-registry.ts`,nodes:C({configPaths:(await w(`schemas/**/config.ts`,{cwd:t,onlyFiles:!0})).map(e=>{let t=u.parse(e);return u.join(t.dir,t.name)})})});f(u.join(t,`config-registry.ts`))&&await h(u.join(t,`config-registry.ts`),{force:!0,recursive:!0}),await g(u.join(t,`config-registry.ts`),n.text)}function ge(e,t){return{baseClassName:`${E(T(e))}_${E(T(t))}`,queryName:`${T(e)}${E(T(t))}`,mutationName:`create${T(e)}${E(T(t))}`}}const{factory:L}=D;function R(e){return L.createIdentifier(e)}function z(e){return R(e)}function B(e){return L.createStringLiteral(e)}function V(e,t){return L.createPropertyAssignment(R(e),t)}function H(e,t=!0){return L.createObjectLiteralExpression(e,t)}function U(e){return e?L.createTrue():L.createFalse()}function _e(e){return L.createParameterDeclaration(void 0,void 0,R(e))}function W(e,t,n){return L.createArrowFunction(n?.async?[L.createToken(D.SyntaxKind.AsyncKeyword)]:void 0,void 0,e.map(e=>typeof e==`string`?_e(e):e),void 0,L.createToken(D.SyntaxKind.EqualsGreaterThanToken),t)}function ve(e){return L.createParenthesizedExpression(e)}function ye(e,t=!0){return W([`t`],ve(H(e,t)))}function G(e,t){return L.createPropertyAccessExpression(typeof e==`string`?R(e):e,R(t))}function be(e,t=[],n){return L.createCallExpression(e,n,t)}function K(e,t,n=[],r){return be(G(e,t),n,r)}function xe(e,t=[],n){return K(`builder`,e,t,n)}function Se(e,t){return L.createVariableStatement(void 0,L.createVariableDeclarationList([L.createVariableDeclaration(R(e),void 0,void 0,t)],D.NodeFlags.Const))}function q(e,t,n){return L.createImportDeclaration(void 0,L.createImportClause(n?.typeOnly??!1,void 0,L.createNamedImports(t.map(e=>L.createImportSpecifier(!1,void 0,R(e))))),B(e))}function Ce(e,t,n){return L.createImportDeclaration(void 0,L.createImportClause(n?.typeOnly??!1,R(t),void 0),B(e))}function we({models:e,mutationName:t,mutationConfig:n,hasValidations:r,fieldDefinitions:i}){if(!n)return[];let a=Object.values(e).find(e=>e.root);if(!a)return[];let o=Te(i),s=Ee(i),c=Object.values(e).filter(e=>!e.root);return[...De(r),...c.map(t=>Oe(t,e,o,s)),Oe(a,e,o,s),Me(t,a,r)]}function Te(e){let t=new Map;if(!e)return t;for(let n of e){let e=n.options?.required===!0;t.set(n.name,e)}return t}function Ee(e){let t=new Set;if(!e)return t;for(let n of e)n.options?.readOnly===!0&&t.add(n.name);return t}function De(e){let t=[q(`@lakeql/adapters`,[`executeWritePipeline`]),q(`@lakeql/trino-client`,[`TrinoClient`]),q(`@lakeql/api/builder`,[`builder`]),q(`~/env`,[`env`]),q(`./config`,[`hiveConfig`,`storageConfig`]),Ce(`./json-schema.json`,`jsonSchema`)];return e&&t.push(q(`./validations`,[`validationSchema`])),t}function Oe(e,t,n,r){let i=`${e.modelName}Input`,a=Object.values(e.fields).filter(e=>!r.has(e.name)).map(e=>ke(e,t,n));return Se(i,xe(`inputType`,[B(i),H([V(`fields`,ye(a))])]))}function ke(e,t,n){let r=V(`required`,U(n.get(e.name)??!0));if(e.isArray){let t=e.graphqlType.replace(/^\[/u,``).replace(/\]$/u,``),n=je(t);if(n)return V(e.name,K(`t`,n,[H([r],!1)]));let i=`${t}Input`;return V(e.name,K(`t`,`field`,[H([V(`type`,D.factory.createArrayLiteralExpression([z(i)])),r],!1)]))}let i=Ae(e.graphqlType);if(i)return V(e.name,K(`t`,i,[H([r],!1)]));if(Object.keys(t).includes(e.graphqlType)){let t=`${e.graphqlType}Input`;return V(e.name,K(`t`,`field`,[H([V(`type`,z(t)),r],!1)]))}return V(e.name,K(`t`,`string`,[H([r],!1)]))}function Ae(e){switch(e){case`String`:return`string`;case`Int`:return`int`;case`Float`:return`float`;case`Boolean`:return`boolean`;default:return}}function je(e){switch(e){case`String`:return`stringList`;case`Int`:return`intList`;case`Float`:return`floatList`;case`Boolean`:return`booleanList`;default:return}}function Me(e,t,n){let r=`${t.modelName}Input`,i=[];n&&i.push(D.factory.createExpressionStatement(K(`validationSchema`,`parse`,[z(`input`)]))),i.push(D.factory.createVariableStatement(void 0,D.factory.createVariableDeclarationList([D.factory.createVariableDeclaration(z(`trinoClient`),void 0,void 0,D.factory.createNewExpression(z(`TrinoClient`),void 0,[H([V(`host`,G(`env`,`HIVE_HOST`)),V(`port`,G(`env`,`HIVE_PORT`)),V(`auth`,H([V(`type`,B(`basic`)),V(`username`,G(`env`,`HIVE_USERNAME`)),V(`password`,G(`env`,`HIVE_PASSWORD`))],!1)),V(`catalog`,G(`env`,`HIVE_CATALOG`)),V(`source`,G(`env`,`HIVE_SOURCE`))])]))],D.NodeFlags.Const)));let a=D.factory.createAwaitExpression(be(z(`executeWritePipeline`),[H([V(`records`,z(`input`)),V(`jsonSchema`,D.factory.createAsExpression(z(`jsonSchema`),D.factory.createKeywordTypeNode(D.SyntaxKind.AnyKeyword))),V(`config`,H([V(`loadStrategy`,G(`storageConfig`,`loadStrategy`)),V(`bucket`,G(`storageConfig`,`bucket`)),V(`basePath`,G(`storageConfig`,`basePath`)),V(`table`,H([V(`catalog`,G(`hiveConfig`,`catalog`)),V(`schema`,G(`hiveConfig`,`schema`)),V(`tableName`,G(`hiveConfig`,`tableName`))],!1)),V(`trinoClient`,z(`trinoClient`))]))])]));i.push(D.factory.createExpressionStatement(a)),i.push(D.factory.createReturnStatement(D.factory.createTrue()));let o=D.factory.createBlock(i,!0),s=W([_e(`_root`),D.factory.createParameterDeclaration(void 0,void 0,D.factory.createObjectBindingPattern([D.factory.createBindingElement(void 0,void 0,D.factory.createIdentifier(`input`))]))],o,{async:!0}),c=V(e,K(`t`,`boolean`,[H([V(`args`,H([V(`input`,K(`t`,`arg`,[H([V(`type`,z(r)),V(`required`,U(!0))],!1)]))],!1)),V(`resolve`,s)])]));return D.factory.createExpressionStatement(xe(`mutationFields`,[ye([c])]))}function J(e){if(typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(J);let t={},n=Object.keys(e).toSorted();for(let r of n)t[r]=J(e[r]);return t}function Ne(e){let t=J(e);return`${JSON.stringify(t,null,2).replaceAll(`\r
|
|
4
3
|
`,`
|
|
5
|
-
`)}\n`}async function
|
|
6
|
-
`);console.error(`Error:
|
|
7
|
-
`);console.error(`Error: Validation failed for ${
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
`)}\n`}async function Pe(e){let{definition:t,outputDir:n,skipRegistry:r,sourcePathOverride:i}=e,{catalog:a,schema:o,tableName:s,fields:c}=t,{baseClassName:l,queryName:d,mutationName:m}=ge(o,s),_=ae(c),v=ie({isRoot:!0,models:{},name:l,source:_}),y=Object.values(v).find(e=>e.root===!0),b=y?.fields?Object.values(y.fields).filter(e=>e.filter===!0).map(e=>({name:e.name,type:e.graphqlType})):[],ee=[...new Set(b.map(e=>e.type))],x=[...new Set(Object.values(v).filter(e=>e.transformFields.length>0).flatMap(e=>e.transformFields))],C=[...new Set(Object.values(v).filter(e=>e.dateTimeFields.length>0).flatMap(e=>e.dateTimeFields))],w=await S({fileName:`config.ts`,nodes:te({catalog:a,queryName:d,schema:o,tableName:s,mutationName:[m],storageConfig:t.mutation?{loadStrategy:t.mutation.loadStrategy,type:t.mutation.type,bucket:t.mutation.bucket,basePath:t.mutation.basePath,region:t.mutation.region,endpoint:t.mutation.endpoint,partitioning:t.mutation.loadStrategy===`full_load`?void 0:t.mutation.partitioning,partitioningFormat:t.mutation.loadStrategy===`full_load`?void 0:t.mutation.partitioningFormat}:void 0})}),T=await S({fileName:`interface.ts`,nodes:ne(v)}),E=await S({fileName:`query-schema.ts`,nodes:re({dateTimeFields:C,filterFields:b,filterTypes:ee,models:v,queryName:d,transformFields:x})}),D=c.some(e=>e.options?.validations&&e.options.validations.length>0),O=we({models:v,mutationName:m,mutationConfig:t.mutation,hasValidations:D,fieldDefinitions:c}),k=``;O.length>0&&(k=(await S({fileName:`mutation-schema.ts`,nodes:O})).text);let A=Ne(_),j=Ne(t),M=[{fileName:`config.ts`,content:w.text},{fileName:`interface.ts`,content:T.text},{fileName:`query-schema.ts`,content:E.text},{fileName:`json-schema.json`,content:A},{fileName:`endpoint.json`,content:j}];k&&M.push({fileName:`mutation-schema.ts`,content:k}),f(n)&&await h(n,{force:!0,recursive:!0}),await p(n,{recursive:!0});for(let e of M)await g(u.join(n,e.fileName),e.content);return r||await I(i),{files:M,outputDir:n}}function Y(e,t=0){let n=[],r=` `.repeat(t+1);for(let i of e)if(i.type===`Object`)n.push(`${r}${i.name}: Object`),i.fields&&n.push(Y(i.fields,t+1));else if(i.type===`Array`){let e=i.items?.type??`Unknown`;n.push(`${r}${i.name}: Array<${e}>`),i.items?.type===`Object`&&i.items.fields&&n.push(Y(i.items.fields,t+1))}else n.push(`${r}${i.name}: ${i.type}`);return n.filter(e=>e.length>0).join(`
|
|
5
|
+
`)}function Fe(){return s().action(async e=>{let{fromFile:t,sourcePath:n,skipRegistry:r,force:i}=e,a=u.isAbsolute(t)?t:u.resolve(process.cwd(),t);f(a)||(console.error(`Error: File not found: ${a}`),process.exit(1));let o;try{o=await m(a,`utf-8`)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`Error: Cannot read file: ${a}: ${t}`),process.exit(1)}let s;try{s=JSON.parse(o)}catch(e){let t=e instanceof Error?e.message:String(e);console.error(`Error: Invalid JSON in ${a}: ${t}`),process.exit(1)}let c=O.safeParse(s);if(!c.success){let e=c.error.issues.map(e=>` - ${e.path.length>0?e.path.join(`.`):`root`}: ${e.message}`).join(`
|
|
6
|
+
`);console.error(`Error: Validation failed for ${a}:\n${e}`),process.exit(1)}let l=c.data,d=k(l.fields);if(d.length>0){let e=d.map(e=>{let t=e.path.length>0?e.path.join(`.`):`root`;return` - Duplicate field "${e.name}" at level: ${t}`}).join(`
|
|
7
|
+
`);console.error(`Error: Validation failed for ${a}:\n${e}`),process.exit(1)}console.log(`
|
|
8
|
+
Loaded definition summary:`),console.log(` tableName: ${l.tableName}`),console.log(` catalog: ${l.catalog}`),console.log(` schema: ${l.schema}`);let p=l.mutation?l.mutation.loadStrategy:`disabled`;console.log(` mutation: ${p}`),console.log(`
|
|
9
|
+
Fields:`),console.log(Y(l.fields)),console.log(``);let h=await F(n===process.cwd()?void 0:n),g=u.join(h,`schemas/custom`,l.catalog,l.schema,l.tableName);f(g)&&!i&&(await _(`Directory "${g}" already exists. Overwrite?`)||(console.log(`Aborted.`),process.exit(0))),await Pe({definition:l,outputDir:g,skipRegistry:r,sourcePathOverride:n===process.cwd()?void 0:n}),console.log(`Endpoint generated successfully at: ${g}`)})}let Ie;function Le(){return oe.config({path:`../../.env`}),M({runtimeEnv:process.env,server:{HIVE_CATALOG:N().min(1),HIVE_HOST:N(),HIVE_PASSWORD:N().min(1),HIVE_PORT:N().transform(e=>Number.parseInt(e,10)).pipe(ce()),HIVE_SOURCE:N().optional(),HIVE_USERNAME:N().min(1),LOG_LEVEL:se([`info`,`warn`,`error`,`debug`]).default(`warn`)}})}function X(){return Ie||=Le(),Ie}function Re(){let t=e();return t.action(async({catalog:e,schema:t,table:n})=>{let r=X(),i=e??r.HIVE_CATALOG,a=new A({auth:{password:r.HIVE_PASSWORD,type:`basic`,username:r.HIVE_USERNAME},catalog:i,host:r.HIVE_HOST,port:r.HIVE_PORT}),o=t;if(o===void 0){let e=await a.schemas({catalog:i});o=await b(`Choose a schema from the ${i} catalog`,{autocomplete:!0,choices:e})}let s=n;if(s===void 0){let e=await a.tables({catalog:i,schema:o});s=await b(`Choose a table from "${i}.${o}"`,{autocomplete:!0,choices:e})}let c=(await a.columns({catalog:i,schema:o,table:s})).map(([e,t,n,r])=>({description:r,extra:n,name:e,type:t})),l=new j;l.column(`Column Name`,`name`),l.column(`Type`,`type`),l.column(`Extra`,`extra`),l.column(`Description`,`description`),l.render(c)}),t}function ze(){let e=n();return e.action(async({catalog:e})=>{let t=X(),n=e??t.HIVE_CATALOG,r=await new A({auth:{password:t.HIVE_PASSWORD,type:`basic`,username:t.HIVE_USERNAME},catalog:n,host:t.HIVE_HOST,port:t.HIVE_PORT}).schemas({catalog:n}),i=new j;i.column(`Schema Name`,`s`),i.render(r.map(e=>({s:e})))}),e}function Be(){let e=o();return e.action(async({catalog:e,schema:t})=>{let n=X(),r=e??n.HIVE_CATALOG,i=new A({auth:{password:n.HIVE_PASSWORD,type:`basic`,username:n.HIVE_USERNAME},catalog:r,host:n.HIVE_HOST,port:n.HIVE_PORT}),a=t;if(a===void 0){let e=await i.schemas({catalog:r});a=await b(`Choose a schema from the ${r} catalog`,{autocomplete:!0,choices:e})}let o=await i.tables({catalog:r,schema:a}),s=new j;s.column(`Table Name`,`t`),s.render(o.map(e=>({t:e})))}),e}function Ve(){let e=i();return e.action(async({catalog:e,schema:t})=>{let n=X(),r=e??n.HIVE_CATALOG,i=new A({auth:{password:n.HIVE_PASSWORD,type:`basic`,username:n.HIVE_USERNAME},catalog:r,host:n.HIVE_HOST,port:n.HIVE_PORT}),a=t;if(a===void 0){let e=await i.schemas({catalog:r});a=await b(`Choose a schema from the ${r} catalog`,{choices:e})}let o=await i.views({catalog:r,schema:a}),s=new j;s.column(`View Name`,`v`),s.render(o.map(e=>({v:e})))}),e}function Z(e){switch(e.replaceAll(/[^a-zA-Z]/gu,``)){case`varchar`:return`String`;case`decimal`:case`double`:case`float`:return`Float`;case`integer`:case`bigint`:return`Integer`;case`boolean`:return`Boolean`;case`timestamp`:return`DateTime`;case`date`:return`Date`;default:return`String`}}function He(e,t){return typeof t==`string`?{name:e,type:Z(t)}:Array.isArray(t)?{name:e,type:`Array`,items:Ue(t)}:typeof t==`object`&&t?{name:e,type:`Object`,fields:Q(t)}:{name:e,type:`String`}}function Ue(e){if(e.length===0)return{type:`String`};let[t]=e;return typeof t==`string`?{type:Z(t)}:typeof t==`object`&&t&&!Array.isArray(t)?{type:`Object`,fields:Q(t)}:{type:`String`}}function Q(e){let t=[];for(let[n,r]of Object.entries(e))t.push(He(n,r));return t}function We(e){let{tableName:t,catalog:n,schema:r,parsedColumns:i}=e;return{version:`1.0`,tableName:t,catalog:n,schema:r,fields:Q(i),mutation:!1}}async function $(e){let{trinoClient:t,catalog:n,schema:r,tables:i,resolvedTargetPath:a,skipRegistry:o,sourcePathOverride:s}=e;for(let e of i)await Pe({definition:We({tableName:e,catalog:n,schema:r,parsedColumns:de((await t.columns({catalog:n,schema:r,table:e})).map(e=>fe({keys:[`name`,`type`,`extra`,`description`],values:e})))}),outputDir:u.join(a,`schemas/generated`,n,r,e),skipRegistry:o,sourcePathOverride:s})}async function Ge(e){let n=t(),r;if(e){let t=u.isAbsolute(e)?e:u.resolve(n,e),i=u.parse(t);r=u.join(i.dir,i.name)}let{config:i}=await x({name:`import`,cwd:n,configFile:r,defaults:{default:[]},packageJson:!1,globalRc:!1,rcFile:!1,dotenv:!1}),a=i;return Array.isArray(a)?a:a&&typeof a==`object`&&`default`in a&&Array.isArray(a.default)?a.default:[]}async function Ke(e){let{configPath:t,catalog:n,sourcePathOverride:r,skipRegistry:i}=e,a=X(),o=await F(r),s=await Ge(t);if(s.length===0){console.log(`No entries found in bulk config.`);return}await new ue([{title:`Pull data`,task:(e,t)=>t.newListr(s.map(e=>{let t=n??e.catalog??a.HIVE_CATALOG,i=(e.tables?.length??0)+(e.views?.length??0);return{title:`${t}/${e.schema} — ${i} item(s)`,task:async(n,s)=>{let c=new A({auth:{password:a.HIVE_PASSWORD,type:`basic`,username:a.HIVE_USERNAME},catalog:t,host:a.HIVE_HOST,port:a.HIVE_PORT});e.tables&&e.tables.length>0&&(s.output=`Pulling ${e.tables.length} table(s)...`,await $({trinoClient:c,catalog:t,schema:e.schema,tables:e.tables,resolvedTargetPath:o,skipRegistry:!0,sourcePathOverride:r})),e.views&&e.views.length>0&&(s.output=`Pulling ${e.views.length} view(s)...`,await $({trinoClient:c,catalog:t,schema:e.schema,tables:e.views,resolvedTargetPath:o,skipRegistry:!0,sourcePathOverride:r})),s.title=`${t}/${e.schema} — ${i} item(s) pulled`}}}),{concurrent:!0,exitOnError:!1})},{title:`Create registry`,enabled:!i,task:async()=>{await I(r)}}],{concurrent:!1,exitOnError:!0}).run()}function qe(){let e=c();return e.action(async t=>{let{skipRegistry:n,sourcePath:r,bulk:i,bulkConfig:a}=t,o=r===(process.env.INIT_CWD??process.cwd())?void 0:r;if(i){await Ke({configPath:a,catalog:t.catalog,sourcePathOverride:o,skipRegistry:n});return}let s=X(),c=t.catalog??s.HIVE_CATALOG,{schema:l,table:u,type:d}=t,f=await F(o),p=new A({auth:{password:s.HIVE_PASSWORD,type:`basic`,username:s.HIVE_USERNAME},catalog:c,host:s.HIVE_HOST,port:s.HIVE_PORT});if(!l){let e=await p.schemas({catalog:c});l=await b(`Choose a schema from the ${c} catalog`,{autocomplete:!0,choices:e})}if(u.length===0&&(d??=await b(`What do you want to see from ${c}/${l}`,{choices:[{label:`Show tables`,value:`tables`},{label:`Show views`,value:`views`}]})),u.length===0){d??=`tables`;let t=[];t=d===`views`?await p.views({catalog:c,schema:l}):await p.tables({catalog:c,schema:l}),t.length===0&&e.error(le(`There are no ${d} in schema '${c}.${l}'.`),{exitCode:0}),u=await v(`Choose the ${d} to pull`,{autocomplete:!0,choices:t,validators:[ee.required()]})}await $({trinoClient:p,catalog:c,schema:l,tables:[...u],resolvedTargetPath:f,skipRegistry:n,sourcePathOverride:o})}),e}const Je=[`lakeql.config.mjs`,`lakeql.config.ts`,`lakeql.config.json`];function Ye(e){return`/** @type {import('@lakeql/cli').LakeQLConfig} */\nexport default {\n${Object.entries(e).map(([e,t])=>` ${e}: ${JSON.stringify(t)},`).join(`
|
|
10
|
+
`)}\n}\n`}function Xe(e){for(let t of Je)if(f(u.join(e,t)))return t;return null}function Ze(){return r().action(async()=>{let e=t(),n=Xe(e);if(n&&await b(`${n} already exists. Overwrite?`,{choices:[{label:`Yes`,value:`yes`},{label:`No`,value:`no`}]})===`no`){console.log(P.yellow(`Aborted.`));return}let r=await b(`Config format:`,{choices:[{label:`lakeql.config.mjs (recommended)`,value:`mjs`},{label:`lakeql.config.json`,value:`json`}]}),i=f(u.join(e,`src`)),a;if(i)a=`src`,console.log(P.cyan(`Detected src/ directory — generated code will be placed in src/`));else{let e=await b(`Where should generated code be placed?`,{choices:[{label:`./ (project root)`,value:`.`},{label:`Custom path`,value:`__custom__`}]});a=e,e===`__custom__`&&(a=await y(`Enter the source path (relative to project root):`,{defaultValue:`.`}))}let o={sourcePath:a},s=r===`mjs`?`lakeql.config.mjs`:`lakeql.config.json`,c=u.join(e,s);await g(c,r===`mjs`?Ye(o):`${JSON.stringify(o,null,2)}\n`),console.log(P.green(`Created ${s} at ${c}`))})}async function Qe(){let e=await d(),t=new l;t.configureHelp({sortSubcommands:!0}),t.name(`lakeql-cli`).description(`LakeQL CLI`).version(e.version).addCommand(ze()).addCommand(Be()).addCommand(Ve()).addCommand(Re()).addCommand(qe()).addCommand(Fe()).addCommand(he()).addCommand(Ze()),await t.parseAsync()}Qe().catch(()=>{process.exit(1)});export{};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/commands-metadata.d.ts
|
|
2
|
+
type AvailableCommand = "create-registry" | "create-endpoint" | "init" | "list-columns" | "list-schemas" | "list-tables" | "list-views" | "pull";
|
|
3
|
+
interface CommandArgumentMeta {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
required: boolean;
|
|
7
|
+
variadic: boolean;
|
|
8
|
+
defaultValue?: unknown;
|
|
9
|
+
defaultValueDescription?: string;
|
|
10
|
+
}
|
|
11
|
+
interface CommandOptionMeta {
|
|
12
|
+
flags: string;
|
|
13
|
+
description: string;
|
|
14
|
+
required: boolean;
|
|
15
|
+
defaultValue?: unknown;
|
|
16
|
+
defaultValueDescription?: string;
|
|
17
|
+
envVar?: string;
|
|
18
|
+
isBoolean: boolean;
|
|
19
|
+
long?: string;
|
|
20
|
+
short?: string;
|
|
21
|
+
}
|
|
22
|
+
interface CommandConfig {
|
|
23
|
+
name: string;
|
|
24
|
+
description: string;
|
|
25
|
+
arguments: CommandArgumentMeta[];
|
|
26
|
+
options: CommandOptionMeta[];
|
|
27
|
+
}
|
|
28
|
+
declare function getCommandConfig(commandName: string): CommandConfig;
|
|
29
|
+
declare const availableCommands: AvailableCommand[];
|
|
30
|
+
//#endregion
|
|
31
|
+
export { CommandArgumentMeta, CommandConfig, CommandOptionMeta, availableCommands, getCommandConfig };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Command as e,Option as t}from"@commander-js/extra-typings";function n(){return new e(`init`).description(`Initialize a lakeql config file`)}function r(){return process.env.INIT_CWD??process.cwd()}function i(){return new t(`--catalog <catalog>`,`catalog to use`).env(`HIVE_CATALOG`)}function a(){return new t(`--schema <schema>`,`schema to use`)}function o(){return new t(`--table <table>`,`table to use`)}function s(){return new t(`--type <type>`,`Show tables or views`)}function c(){return new t(`--source-path <path>`,"Base path for generated code (resolved from the command invocation directory). Files are created in `schemas/generated|custom` inside this path.").default(r(),`command invocation directory`)}function l(){return new t(`--skip-registry`,`Skip config registry generation`).default(!1)}function u(){return new e(`create-endpoint`).description(`Create a custom endpoint from a JSON definition file`).addOption(new t(`--from-file <path>`,`Path to a JSON definition file conforming to the Endpoint_Definition_Format`).makeOptionMandatory(!0)).addOption(c()).addOption(l()).addOption(new t(`--force`,`Overwrite existing files without prompting`).default(!1))}function d(){return new e(`create-registry`).description("Generates the config registry to ensure the type-safety while using `createPermission`").addOption(c())}function f(){return new e(`list-columns`).description(`Lists the columns for the specified table`).addOption(i()).addOption(a().makeOptionMandatory()).addOption(o().makeOptionMandatory())}function p(){return new e(`list-schemas`).description(`Lists the available schemas for the configured catalog`).addOption(i())}function m(){return new e(`list-tables`).description(`Lists the available tables for the configured catalog/schema`).addOption(i()).addOption(a())}function h(){return new e(`list-views`).description(`Lists the available views for the configured catalog/schema`).addOption(i()).addOption(a())}const g=new t(`--bulk`,`Run in bulk mode using a config file`).default(!1),_=new t(`--bulk-config <path>`,`Path to the bulk import config file (default: import.config.{mjs,ts,js,json})`);function v(){return new e(`pull`).description(`Interactive query endpoint generation based on a remote table`).addOption(i()).addOption(s()).addOption(a().makeOptionMandatory(!1)).addOption(o().makeOptionMandatory(!1).default([]).argParser((e,t)=>[...t,e])).addOption(new t(`--skip-registry`,`Skip registry update`).default(!1)).addOption(c()).addOption(g).addOption(_)}function y(e){let t={name:e.name(),description:e.description,required:e.required,variadic:e.variadic};return e.defaultValue!==void 0&&(t.defaultValue=e.defaultValue),e.defaultValueDescription&&(t.defaultValueDescription=e.defaultValueDescription),t}function b(e){let t={flags:e.flags,description:e.description,required:e.mandatory,isBoolean:!e.required&&!e.optional};return e.defaultValue!==void 0&&!e.defaultValueDescription&&(t.defaultValue=e.defaultValue),e.defaultValueDescription&&(t.defaultValueDescription=e.defaultValueDescription),e.envVar&&(t.envVar=e.envVar),e.long&&(t.long=e.long),e.short&&(t.short=e.short),t}const x={"create-registry":d,"create-endpoint":u,init:n,"list-columns":f,"list-schemas":p,"list-tables":m,"list-views":h,pull:v};function S(e){let t=x[e];if(!t)throw Error(`No command named '${e}'`);let n=t();return{name:n.name(),description:n.description(),arguments:n.registeredArguments.map(y),options:n.options.map(b)}}const C=Object.keys(x);export{C as availableCommands,S as getCommandConfig};
|
package/dist/index.d.mts
CHANGED
|
@@ -37,4 +37,32 @@ interface LakeQLConfig {
|
|
|
37
37
|
sourcePath: string;
|
|
38
38
|
}
|
|
39
39
|
//#endregion
|
|
40
|
-
|
|
40
|
+
//#region src/commands-metadata.d.ts
|
|
41
|
+
interface CommandArgumentMeta {
|
|
42
|
+
name: string;
|
|
43
|
+
description: string;
|
|
44
|
+
required: boolean;
|
|
45
|
+
variadic: boolean;
|
|
46
|
+
defaultValue?: unknown;
|
|
47
|
+
defaultValueDescription?: string;
|
|
48
|
+
}
|
|
49
|
+
interface CommandOptionMeta {
|
|
50
|
+
flags: string;
|
|
51
|
+
description: string;
|
|
52
|
+
required: boolean;
|
|
53
|
+
defaultValue?: unknown;
|
|
54
|
+
defaultValueDescription?: string;
|
|
55
|
+
envVar?: string;
|
|
56
|
+
isBoolean: boolean;
|
|
57
|
+
long?: string;
|
|
58
|
+
short?: string;
|
|
59
|
+
}
|
|
60
|
+
interface CommandConfig {
|
|
61
|
+
name: string;
|
|
62
|
+
description: string;
|
|
63
|
+
arguments: CommandArgumentMeta[];
|
|
64
|
+
options: CommandOptionMeta[];
|
|
65
|
+
}
|
|
66
|
+
declare function getCommandConfig(commandName: string): CommandConfig;
|
|
67
|
+
//#endregion
|
|
68
|
+
export { type BulkPullConfig, type BulkPullEntry, type CommandArgumentMeta, type CommandConfig, type CommandOptionMeta, type LakeQLConfig, getCommandConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{};
|
|
1
|
+
import{a as e,i as t,l as n,n as r,o as i,r as a,s as o,t as s}from"./pull-metadata-D8Z0WHKQ.mjs";function c(e){let t={name:e.name(),description:e.description,required:e.required,variadic:e.variadic};return e.defaultValue!==void 0&&(t.defaultValue=e.defaultValue),e.defaultValueDescription&&(t.defaultValueDescription=e.defaultValueDescription),t}function l(e){let t={flags:e.flags,description:e.description,required:e.mandatory,isBoolean:!e.required&&!e.optional};return e.defaultValue!==void 0&&!e.defaultValueDescription&&(t.defaultValue=e.defaultValue),e.defaultValueDescription&&(t.defaultValueDescription=e.defaultValueDescription),e.envVar&&(t.envVar=e.envVar),e.long&&(t.long=e.long),e.short&&(t.short=e.short),t}const u={"create-registry":i,"create-endpoint":o,init:n,"list-columns":e,"list-schemas":t,"list-tables":a,"list-views":r,pull:s};function d(e){let t=u[e];if(!t)throw Error(`No command named '${e}'`);let n=t();return{name:n.name(),description:n.description(),arguments:n.registeredArguments.map(c),options:n.options.map(l)}}export{d as getCommandConfig};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Command as e,Option as t}from"@commander-js/extra-typings";import"node:path";function n(){return new e(`init`).description(`Initialize a lakeql config file`)}function r(){return process.env.INIT_CWD??process.cwd()}function i(){return new t(`--catalog <catalog>`,`catalog to use`).env(`HIVE_CATALOG`)}function a(){return new t(`--schema <schema>`,`schema to use`)}function o(){return new t(`--table <table>`,`table to use`)}function s(){return new t(`--type <type>`,`Show tables or views`)}function c(){return new t(`--source-path <path>`,"Base path for generated code (resolved from the command invocation directory). Files are created in `schemas/generated|custom` inside this path.").default(r(),`command invocation directory`)}function l(){return new t(`--skip-registry`,`Skip config registry generation`).default(!1)}function u(){return new e(`create-endpoint`).description(`Create a custom endpoint from a JSON definition file`).addOption(new t(`--from-file <path>`,`Path to a JSON definition file conforming to the Endpoint_Definition_Format`).makeOptionMandatory(!0)).addOption(c()).addOption(l()).addOption(new t(`--force`,`Overwrite existing files without prompting`).default(!1))}function d(){return new e(`create-registry`).description("Generates the config registry to ensure the type-safety while using `createPermission`").addOption(c())}function f(){return new e(`list-columns`).description(`Lists the columns for the specified table`).addOption(i()).addOption(a().makeOptionMandatory()).addOption(o().makeOptionMandatory())}function p(){return new e(`list-schemas`).description(`Lists the available schemas for the configured catalog`).addOption(i())}function m(){return new e(`list-tables`).description(`Lists the available tables for the configured catalog/schema`).addOption(i()).addOption(a())}function h(){return new e(`list-views`).description(`Lists the available views for the configured catalog/schema`).addOption(i()).addOption(a())}const g=new t(`--bulk`,`Run in bulk mode using a config file`).default(!1),_=new t(`--bulk-config <path>`,`Path to the bulk import config file (default: import.config.{mjs,ts,js,json})`);function v(){return new e(`pull`).description(`Interactive query endpoint generation based on a remote table`).addOption(i()).addOption(s()).addOption(a().makeOptionMandatory(!1)).addOption(o().makeOptionMandatory(!1).default([]).argParser((e,t)=>[...t,e])).addOption(new t(`--skip-registry`,`Skip registry update`).default(!1)).addOption(c()).addOption(g).addOption(_)}export{f as a,r as c,p as i,n as l,h as n,d as o,m as r,u as s,v as t};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lakeql/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CLI for introspecting Trino schemas and generating type-safe GraphQL endpoints",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -43,6 +43,10 @@
|
|
|
43
43
|
},
|
|
44
44
|
"./cli": {
|
|
45
45
|
"import": "./dist/cli.mjs"
|
|
46
|
+
},
|
|
47
|
+
"./commands-metadata": {
|
|
48
|
+
"import": "./dist/commands-metadata.mjs",
|
|
49
|
+
"types": "./dist/commands-metadata.d.mts"
|
|
46
50
|
}
|
|
47
51
|
},
|
|
48
52
|
"dependencies": {
|
|
@@ -60,19 +64,19 @@
|
|
|
60
64
|
"lodash-es": "4.18.1",
|
|
61
65
|
"read-pkg": "10.1.0",
|
|
62
66
|
"zod": "4.4.3",
|
|
63
|
-
"@lakeql/
|
|
64
|
-
"@lakeql/column-parser": "0.1.
|
|
65
|
-
"@lakeql/
|
|
66
|
-
"@lakeql/
|
|
67
|
-
"@lakeql/
|
|
68
|
-
"@lakeql/
|
|
69
|
-
"@lakeql/trino-client": "0.
|
|
67
|
+
"@lakeql/file-generator": "0.1.8",
|
|
68
|
+
"@lakeql/column-parser": "0.1.4",
|
|
69
|
+
"@lakeql/logger": "0.1.3",
|
|
70
|
+
"@lakeql/response-transformer": "0.1.4",
|
|
71
|
+
"@lakeql/schema-generator": "0.4.2",
|
|
72
|
+
"@lakeql/helpers": "0.1.4",
|
|
73
|
+
"@lakeql/trino-client": "0.4.0"
|
|
70
74
|
},
|
|
71
75
|
"devDependencies": {
|
|
72
76
|
"@types/lodash-es": "4.17.12",
|
|
73
77
|
"@types/node": "24.13.2",
|
|
74
78
|
"fast-check": "^4.8.0",
|
|
75
|
-
"tsdown": "0.22.
|
|
79
|
+
"tsdown": "0.22.3",
|
|
76
80
|
"tsx": "4.22.4",
|
|
77
81
|
"typescript": "6.0.3",
|
|
78
82
|
"vitest": "4.1.9",
|