@aurios/mizzling 1.1.0 → 1.1.2

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.
@@ -0,0 +1,15 @@
1
+
2
+ > @aurios/mizzling@1.1.2 build /home/runner/work/mizzle/mizzle/packages/mizzling
3
+ > tsup
4
+
5
+ CLI Building entry: src/cli.ts, src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.5.1
8
+ CLI Using tsup config: /home/runner/work/mizzle/mizzle/packages/mizzling/tsup.config.ts
9
+ CLI Target: esnext
10
+ CLI Cleaning output folder
11
+ ESM Build start
12
+ ESM dist/cli.js 13.77 KB
13
+ ESM dist/index.js 87.00 B
14
+ ESM dist/chunk-DKDRM5WU.js 1.79 KB
15
+ ESM ⚡️ Build success in 37ms
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lucas A. Ouverney
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import{join as s}from"path";import{existsSync as c}from"fs";import{DynamoDBClient as a}from"@aws-sdk/client-dynamodb";import{fromIni as p}from"@aws-sdk/credential-provider-ini";import{NodeHttpHandler as f}from"@smithy/node-http-handler";import l from"http";import m from"https";function v(e){return e}function M(e){let i={keepAlive:!0,maxSockets:1/0},t={region:e.region||"us-east-1",endpoint:e.endpoint,maxAttempts:e.maxAttempts,requestHandler:new f({httpAgent:new l.Agent(i),httpsAgent:new m.Agent(i)})};return e.credentials?t.credentials=e.credentials:e.profile?t.credentials=p({profile:e.profile}):e.endpoint&&(e.endpoint.includes("localhost")||e.endpoint.includes("127.0.0.1"))&&(t.credentials={accessKeyId:"local",secretAccessKey:"local"}),new a(t)}async function h(e="mizzle.config.ts"){let t=process.env.MIZZLE_CONFIG||s(process.cwd(),e);if(!c(t))throw new Error(`Could not find ${e} in current directory.`);try{let n=await import(t),o=n.default||n;if(!o||typeof o!="object")throw new Error("Invalid config: default export must be an object");if(!o.schema)throw new Error("Invalid config: missing 'schema' path");if(!o.out)throw new Error("Invalid config: missing 'out' directory");let r={...o};return process.env.MIZZLE_REGION&&(r.region=process.env.MIZZLE_REGION),process.env.MIZZLE_ENDPOINT&&(r.endpoint=process.env.MIZZLE_ENDPOINT),process.env.MIZZLE_SCHEMA&&(r.schema=process.env.MIZZLE_SCHEMA),process.env.MIZZLE_OUT&&(r.out=process.env.MIZZLE_OUT),process.env.MIZZLE_VERBOSE&&(r.verbose=process.env.MIZZLE_VERBOSE==="true"),process.env.MIZZLE_STRICT&&(r.strict=process.env.MIZZLE_STRICT==="true"),r}catch(n){if(n instanceof Error&&n.message.startsWith("Invalid config"))throw n;let o=n instanceof Error?n.message:String(n);throw new Error(`Failed to load config: ${o}`)}}export{v as a,M as b,h as c};
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{b as g,c as N}from"./chunk-SNI5EXF5.js";import{Command as Re}from"commander";import*as b from"@clack/prompts";var f={COLUMNS:Symbol.for("mizzle:Columns"),INDEXES:Symbol.for("mizzle:Indexes"),SORT_KEY:Symbol.for("mizzle:SortKey"),TABLE_NAME:Symbol.for("mizzle:TableName"),PARTITION_KEY:Symbol.for("mizzle:PartitionKey")},p={ENTITY_NAME:Symbol.for("mizzle:EntityName"),ENTITY_STRATEGY:Symbol.for("mizzle:EntityStrategy"),PHYSICAL_TABLE:Symbol.for("mizzle:PhysicalTable"),COLUMNS:Symbol.for("mizzle:Columns"),ENTITY_KIND:Symbol.for("mizzle:EntityKind")};var O=class{[f.TABLE_NAME]="";[f.INDEXES]=void 0;[f.PARTITION_KEY]={};[f.SORT_KEY]=void 0;static Symbol=f;constructor(e,n){this[f.TABLE_NAME]=e,this[f.PARTITION_KEY]=n.pk.build(this),this[f.SORT_KEY]=n.sk?n.sk.build(this):void 0,this[f.INDEXES]=n.indexes}},v=class{[p.ENTITY_NAME]="";[p.PHYSICAL_TABLE]={};[p.COLUMNS]={};[p.ENTITY_STRATEGY]={};static Symbol=p;constructor(e,n,t,o){this[p.ENTITY_NAME]=e,this[p.PHYSICAL_TABLE]=n,this[p.COLUMNS]=t,this[p.ENTITY_STRATEGY]=o}};var M={COLUMNS:Symbol.for("mizzle:Columns"),INDEXES:Symbol.for("mizzle:Indexes"),SORT_KEY:Symbol.for("mizzle:SortKey"),TABLE_NAME:Symbol.for("mizzle:TableName"),PARTITION_KEY:Symbol.for("mizzle:PartitionKey")},K={ENTITY_NAME:Symbol.for("mizzle:EntityName"),ENTITY_STRATEGY:Symbol.for("mizzle:EntityStrategy"),PHYSICAL_TABLE:Symbol.for("mizzle:PhysicalTable"),COLUMNS:Symbol.for("mizzle:Columns"),ENTITY_KIND:Symbol.for("mizzle:EntityKind")};import Q from"fast-glob";import{stat as Z}from"fs/promises";import{resolve as ee}from"path";async function A(e){let n=Array.isArray(e.schema)?e.schema:[e.schema],t=[],o=[],a=new Set,i=async r=>{let s=ee(process.cwd(),r);if(!a.has(s)){a.add(s);try{let l=await import(s);for(let m in l){let c=l[m];!c||typeof c!="object"||(c instanceof O||c[M.TABLE_NAME]!==void 0?t.push(c):(c instanceof v||c[K.ENTITY_NAME]!==void 0)&&o.push(c))}}catch(l){console.warn(`Failed to import schema file: ${s}`,l)}}};for(let r of n){let s=r,l=!1;try{let c=await Z(r);c.isDirectory()?s=`${r}/**/*.{ts,js,tsx,jsx}`:c.isFile()&&(l=!0)}catch{}if(l){await i(r);continue}let m=await Q(s,{absolute:!0});for(let c of m)await i(c)}return{tables:t,entities:o}}import{join as $}from"path";import{writeFile as te,readFile as ne,mkdir as oe,readdir as ae}from"fs/promises";import{existsSync as k}from"fs";var j="snapshot.json";async function Y(e,n){k(e)||await oe(e,{recursive:!0});let t=$(e,j);await te(t,JSON.stringify(n,null,2),"utf-8")}async function P(e){let n=$(e,j);if(!k(n))return null;let t=await ne(n,"utf-8");return JSON.parse(t)}function E(e){let n={};for(let t of e.tables){let o=e.entities.filter(i=>i[p.PHYSICAL_TABLE]===t),a=ie(t,o);n[a.TableName]=a}return{version:"1",tables:n}}async function R(e){if(!k(e))return"0000";let n=await ae(e),t=-1;for(let o of n){if(!o.endsWith(".ts"))continue;let a=o.match(/^(\d{4})_/);if(a){let i=parseInt(a[1],10);i>t&&(t=i)}}return t===-1?"0000":(t+1).toString().padStart(4,"0")}function ie(e,n){let t=e[f.TABLE_NAME],o=new Map,a=e[f.PARTITION_KEY];o.set(a.name,a.getDynamoType());let i=e[f.SORT_KEY];i&&o.set(i.name,i.getDynamoType());let r=[{AttributeName:a.name,KeyType:"HASH"}];i&&r.push({AttributeName:i.name,KeyType:"RANGE"});let s=[],l=[],m=e[f.INDEXES]||{};for(let[d,y]of Object.entries(m)){let B=y.type,u=y.config;if(B==="gsi"){if(u.pk){let T=_(u.pk,e,n);o.set(u.pk,T)}if(u.sk){let T=_(u.sk,e,n);o.set(u.sk,T)}let x={IndexName:d,KeySchema:[{AttributeName:u.pk,KeyType:"HASH"}],Projection:{ProjectionType:"ALL"}};u.sk&&x.KeySchema.push({AttributeName:u.sk,KeyType:"RANGE"}),s.push(x)}else if(B==="lsi"){if(u.sk){let T=_(u.sk,e,n);o.set(u.sk,T)}let x={IndexName:d,KeySchema:[{AttributeName:a.name,KeyType:"HASH"},{AttributeName:u.sk,KeyType:"RANGE"}],Projection:{ProjectionType:"ALL"}};l.push(x)}}let c=Array.from(o.entries()).map(([d,y])=>({AttributeName:d,AttributeType:y})).sort((d,y)=>d.AttributeName.localeCompare(y.AttributeName));s.sort((d,y)=>(d.IndexName||"").localeCompare(y.IndexName||"")),l.sort((d,y)=>(d.IndexName||"").localeCompare(y.IndexName||""));let S={TableName:t,AttributeDefinitions:c,KeySchema:r};return s.length>0&&(S.GlobalSecondaryIndexes=s),l.length>0&&(S.LocalSecondaryIndexes=l),S}function _(e,n,t){let o=n[f.PARTITION_KEY];if(o.name===e)return o.getDynamoType();let a=n[f.SORT_KEY];if(a&&a.name===e)return a.getDynamoType();for(let i of t){let r=i[p.COLUMNS];if(r){let s=r[e];if(s)return s.getDynamoType()}}throw new Error(`Could not resolve type for column '${e}' in table '${n[f.TABLE_NAME]}'. Ensure it is defined in an Entity.`)}function w(e,n){let t=[],o=E(e).tables,a=n.tables||{},i=new Set([...Object.keys(o),...Object.keys(a)]);for(let r of i){let s=o[r],l=a[r];s&&!l?t.push({type:"create",table:s}):!s&&l?t.push({type:"delete",tableName:r}):s&&l&&(re(s,l)||t.push({type:"update",tableName:r,changes:["Changed"]}))}return t}function re(e,n){let t=o=>{let a={...o};return a.AttributeDefinitions=[...a.AttributeDefinitions||[]].sort((i,r)=>(i.AttributeName||"").localeCompare(r.AttributeName||"")),a.GlobalSecondaryIndexes&&(a.GlobalSecondaryIndexes=[...a.GlobalSecondaryIndexes].sort((i,r)=>(i.IndexName||"").localeCompare(r.IndexName||""))),a.LocalSecondaryIndexes&&(a.LocalSecondaryIndexes=[...a.LocalSecondaryIndexes].sort((i,r)=>(i.IndexName||"").localeCompare(r.IndexName||""))),a};return JSON.stringify(t(e))===JSON.stringify(t(n))}import{join as se}from"path";import{writeFile as le,mkdir as ce}from"fs/promises";import{existsSync as me}from"fs";import{text as fe,isCancel as ue,cancel as pe,intro as de,outro as U}from"@clack/prompts";async function F(e){de("Mizzle Generate");let{config:n}=e,t=e.discoverSchema||A;try{let o=await t(n),a=n.out,i=await P(a)||{version:"0",tables:{}},r=E(o),s=w(o,i);if(s.length===0){U("No changes detected.");return}console.log(`Detected ${s.length} changes.`);let l=await R(a),m=e.name;if(m||(m=await fe({message:"Enter migration name",placeholder:"init",initialValue:"migration",validate(y){if(y.length===0)return"Name is required"}})),ue(m)){pe("Operation cancelled.");return}let c=`${l}_${m}.ts`;me(a)||await ce(a,{recursive:!0});let S=se(a,c),d=ye(s);await le(S,d),console.log(`Created migration: ${c}`),await Y(a,r),U("Updated snapshot.json")}catch(o){console.error("Error generating migration:",o),process.exit(1)}}function ye(e){let n=[],t=[];for(let o of e)o.type==="create"?(n.push(`// Create Table: ${o.table.TableName}`),n.push(`await db.createTable("${o.table.TableName}", ${JSON.stringify(o.table,null,2)});
2
+ import{b,c as N}from"./chunk-DKDRM5WU.js";import{Command as Qe}from"commander";import*as x from"@clack/prompts";var p={COLUMNS:Symbol.for("mizzle:Columns"),INDEXES:Symbol.for("mizzle:Indexes"),SORT_KEY:Symbol.for("mizzle:SortKey"),TABLE_NAME:Symbol.for("mizzle:TableName"),PARTITION_KEY:Symbol.for("mizzle:PartitionKey")},c={ENTITY_NAME:Symbol.for("mizzle:EntityName"),ENTITY_STRATEGY:Symbol.for("mizzle:EntityStrategy"),PHYSICAL_TABLE:Symbol.for("mizzle:PhysicalTable"),COLUMNS:Symbol.for("mizzle:Columns"),ENTITY_KIND:Symbol.for("mizzle:EntityKind")};var I=class{[p.TABLE_NAME]="";[p.INDEXES]=void 0;[p.PARTITION_KEY]={};[p.SORT_KEY]=void 0;static Symbol=p;constructor(n,t){this[p.TABLE_NAME]=n,this[p.PARTITION_KEY]=t.pk.build(this),this[p.SORT_KEY]=t.sk?t.sk.build(this):void 0,this[p.INDEXES]=t.indexes}},D=class{[c.ENTITY_NAME]="";[c.PHYSICAL_TABLE]={};[c.COLUMNS]={};[c.ENTITY_STRATEGY]={};static Symbol=c;constructor(n,t,o,a){this[c.ENTITY_NAME]=n,this[c.PHYSICAL_TABLE]=t,this[c.COLUMNS]=o,this[c.ENTITY_STRATEGY]=a}};import ue from"fast-glob";import{stat as pe}from"fs/promises";import{resolve as ce}from"path";async function E(e){let n=Array.isArray(e.schema)?e.schema:[e.schema],t=[],o=[],a=new Set,i=async r=>{let l=ce(process.cwd(),r);if(!a.has(l)){a.add(l);try{let s=await import(l);for(let u in s){let m=s[u];!m||typeof m!="object"||(m instanceof I||m[p.TABLE_NAME]!==void 0?t.push(m):(m instanceof D||m[c.ENTITY_NAME]!==void 0)&&o.push(m))}}catch(s){console.warn(`Failed to import schema file: ${l}`,s)}}};for(let r of n){let l=r,s=!1;try{let m=await pe(r);m.isDirectory()?l=`${r}/**/*.{ts,js,tsx,jsx}`:m.isFile()&&(s=!0)}catch{}if(s){await i(r);continue}let u=await ue(l,{absolute:!0});for(let m of u)await i(m)}return{tables:t,entities:o}}import{join as _}from"path";import{writeFile as de,readFile as Te,mkdir as fe,readdir as ye}from"fs/promises";import{existsSync as z}from"fs";var U="snapshot.json";async function j(e,n){z(e)||await fe(e,{recursive:!0});let t=_(e,U);await de(t,JSON.stringify(n,null,2),"utf-8")}async function v(e){let n=_(e,U);if(!z(n))return null;let t=await Te(n,"utf-8");return JSON.parse(t)}function M(e){let n={};for(let t of e.tables){let o=e.entities.filter(i=>i[c.PHYSICAL_TABLE]===t),a=Ce(t,o);n[a.TableName]=a}return{version:"1",tables:n}}async function Y(e){if(!z(e))return"0000";let n=await ye(e),t=-1;for(let o of n){if(!o.endsWith(".ts"))continue;let a=o.match(/^(\d{4})_/);if(a){let i=parseInt(a[1],10);i>t&&(t=i)}}return t===-1?"0000":(t+1).toString().padStart(4,"0")}function Ce(e,n){let t=e[p.TABLE_NAME],o=new Map,a=e[p.PARTITION_KEY];o.set(a.name,a.getDynamoType());let i=e[p.SORT_KEY];i&&o.set(i.name,i.getDynamoType());let r=[{AttributeName:a.name,KeyType:"HASH"}];i&&r.push({AttributeName:i.name,KeyType:"RANGE"});let l=[],s=[],u=e[p.INDEXES]||{};for(let[T,f]of Object.entries(u)){let P=f.type,d=f.config;if(P==="gsi"){if(d.pk){let S=O(d.pk,e,n);o.set(d.pk,S)}if(d.sk){let S=O(d.sk,e,n);o.set(d.sk,S)}let B={IndexName:T,KeySchema:[{AttributeName:d.pk,KeyType:"HASH"}],Projection:{ProjectionType:"ALL"}};d.sk&&B.KeySchema.push({AttributeName:d.sk,KeyType:"RANGE"}),l.push(B)}else if(P==="lsi"){if(d.sk){let S=O(d.sk,e,n);o.set(d.sk,S)}let B={IndexName:T,KeySchema:[{AttributeName:a.name,KeyType:"HASH"},{AttributeName:d.sk,KeyType:"RANGE"}],Projection:{ProjectionType:"ALL"}};s.push(B)}}let m=Array.from(o.entries()).map(([T,f])=>({AttributeName:T,AttributeType:f})).sort((T,f)=>T.AttributeName.localeCompare(f.AttributeName));l.sort((T,f)=>(T.IndexName||"").localeCompare(f.IndexName||"")),s.sort((T,f)=>(T.IndexName||"").localeCompare(f.IndexName||""));let h={TableName:t,AttributeDefinitions:m,KeySchema:r};return l.length>0&&(h.GlobalSecondaryIndexes=l),s.length>0&&(h.LocalSecondaryIndexes=s),h}function O(e,n,t){let o=n[p.PARTITION_KEY];if(o.name===e)return o.getDynamoType();let a=n[p.SORT_KEY];if(a&&a.name===e)return a.getDynamoType();for(let i of t){let r=i[c.COLUMNS];if(r){let l=r[e];if(l)return l.getDynamoType()}}throw new Error(`Could not resolve type for column '${e}' in table '${n[p.TABLE_NAME]}'. Ensure it is defined in an Entity.`)}function A(e,n){let t=[],a=M(e).tables,i=n.tables||{},r=new Set([...Object.keys(a),...Object.keys(i)]);for(let l of r){let s=a[l],u=i[l];s&&!u?t.push({type:"create",table:s}):!s&&u?t.push({type:"delete",tableName:l}):s&&u&&(ge(s,u)||t.push({type:"update",tableName:l,changes:["Changed"]}))}return t}function ge(e,n){let t=o=>{let a={...o};return a.AttributeDefinitions=[...a.AttributeDefinitions||[]].sort((i,r)=>(i.AttributeName||"").localeCompare(r.AttributeName||"")),a.GlobalSecondaryIndexes&&(a.GlobalSecondaryIndexes=[...a.GlobalSecondaryIndexes].sort((i,r)=>(i.IndexName||"").localeCompare(r.IndexName||""))),a.LocalSecondaryIndexes&&(a.LocalSecondaryIndexes=[...a.LocalSecondaryIndexes].sort((i,r)=>(i.IndexName||"").localeCompare(r.IndexName||""))),a};return JSON.stringify(t(e))===JSON.stringify(t(n))}import{join as be}from"path";import{writeFile as xe,mkdir as he}from"fs/promises";import{existsSync as Se}from"fs";import{text as Ne,isCancel as Be,cancel as Ie,intro as De,outro as $}from"@clack/prompts";async function F(e){De("Mizzle Generate");let{config:n}=e,t=e.discoverSchema||E;try{let o=await t(n),a=n.out,i=await v(a)||{version:"0",tables:{}},r=M(o),l=A(o,i);if(l.length===0){$("No changes detected.");return}console.log(`Detected ${l.length} changes.`);let s=await Y(a),u=e.name;if(u||(u=await Ne({message:"Enter migration name",placeholder:"init",initialValue:"migration",validate(f){if(f.length===0)return"Name is required"}})),Be(u)){Ie("Operation cancelled.");return}let m=`${s}_${u}.ts`;Se(a)||await he(a,{recursive:!0});let h=be(a,m),T=Ee(l);await xe(h,T),console.log(`Created migration: ${m}`),await j(a,r),$("Updated snapshot.json")}catch(o){console.error("Error generating migration:",o),process.exit(1)}}function Ee(e){let n=[],t=[];for(let o of e)o.type==="create"?(n.push(`// Create Table: ${o.table.TableName}`),n.push(`await db.createTable("${o.table.TableName}", ${JSON.stringify(o.table,null,2)});
3
3
  `),t.unshift(`// Drop Table: ${o.table.TableName}`),t.unshift(`await db.deleteTable("${o.table.TableName}");
4
4
  `)):o.type==="delete"?(n.push(`// Drop Table: ${o.tableName}`),n.push(`await db.deleteTable("${o.tableName}");
5
5
  `),t.unshift(`// Create Table: ${o.tableName}`),t.unshift(`// TODO: Restore table definition for rollback
@@ -12,7 +12,7 @@ export async function up(db: Mizzle) {
12
12
  export async function down(db: Mizzle) {
13
13
  ${t.join(" ")}
14
14
  }
15
- `}import{existsSync as he,writeFileSync as ge}from"fs";import{join as be}from"path";import{intro as Se,outro as Te,text as I,isCancel as C,cancel as z}from"@clack/prompts";async function G(){let e=be(process.cwd(),"mizzle.config.ts");if(he(e)){console.log("mizzle.config.ts already exists in the current directory. Aborting.");return}Se("Mizzle Initialization");let n=await I({message:"Where is your schema file or directory located?",placeholder:"./src/schema.ts",initialValue:"./src/schema.ts",validate:r=>{if(!r)return"Schema path is required"}});if(C(n)){z("Operation cancelled.");return}let t=await I({message:"Where should Mizzle store migrations and snapshots?",placeholder:"./migrations",initialValue:"./migrations",validate:r=>{if(!r)return"Output directory is required"}});if(C(t)){z("Operation cancelled.");return}let o=await I({message:"Which AWS region do you want to use?",placeholder:"us-east-1",initialValue:"us-east-1"});if(C(o)){z("Operation cancelled.");return}let a=await I({message:"Do you want to use a custom endpoint (e.g., for local development)?",placeholder:"http://localhost:8000 (optional)"});if(C(a)){z("Operation cancelled.");return}let i=`import { defineConfig } from "@aurios/mizzle";
15
+ `}import{existsSync as Me,writeFileSync as Ae}from"fs";import{join as ke}from"path";import{intro as we,outro as Ke,text as k,isCancel as w,cancel as K}from"@clack/prompts";async function H(){let e=ke(process.cwd(),"mizzle.config.ts");if(Me(e)){console.log("mizzle.config.ts already exists in the current directory. Aborting.");return}we("Mizzle Initialization");let n=await k({message:"Where is your schema file or directory located?",placeholder:"./src/schema.ts",initialValue:"./src/schema.ts",validate:r=>{if(!r)return"Schema path is required"}});if(w(n)){K("Operation cancelled.");return}let t=await k({message:"Where should Mizzle store migrations and snapshots?",placeholder:"./migrations",initialValue:"./migrations",validate:r=>{if(!r)return"Output directory is required"}});if(w(t)){K("Operation cancelled.");return}let o=await k({message:"Which AWS region do you want to use?",placeholder:"us-east-1",initialValue:"us-east-1"});if(w(o)){K("Operation cancelled.");return}let a=await k({message:"Do you want to use a custom endpoint (e.g., for local development)?",placeholder:"http://localhost:8000 (optional)"});if(w(a)){K("Operation cancelled.");return}let i=`import { defineConfig } from "@aurios/mizzle";
16
16
 
17
17
  export default defineConfig({
18
18
  schema: "${n}",
@@ -20,4 +20,4 @@ export default defineConfig({
20
20
  region: "${o}",
21
21
  ${a?`endpoint: "${a}",`:'// endpoint: "http://localhost:8000",'}
22
22
  });
23
- `;ge(e,i),Te("mizzle.config.ts created successfully!")}import{ListTablesCommand as Ne,DescribeTableCommand as Ee}from"@aws-sdk/client-dynamodb";async function D(e){let n={},t,o=[];do{let a=await e.send(new Ne({ExclusiveStartTableName:t}));a.TableNames&&o.push(...a.TableNames),t=a.LastEvaluatedTableName}while(t);for(let a of o)try{let i=await e.send(new Ee({TableName:a}));if(i.Table){let r=xe(i.Table);n[a]=r}}catch(i){console.warn(`Failed to describe table ${a}:`,i)}return{version:"remote",tables:n}}function xe(e){let n={TableName:e.TableName,AttributeDefinitions:e.AttributeDefinitions?.map(t=>({AttributeName:t.AttributeName,AttributeType:t.AttributeType})).sort((t,o)=>t.AttributeName.localeCompare(o.AttributeName))||[],KeySchema:e.KeySchema?.map(t=>({AttributeName:t.AttributeName,KeyType:t.KeyType}))||[]};return e.GlobalSecondaryIndexes&&e.GlobalSecondaryIndexes.length>0&&(n.GlobalSecondaryIndexes=e.GlobalSecondaryIndexes.map(t=>({IndexName:t.IndexName,KeySchema:t.KeySchema?.map(o=>({AttributeName:o.AttributeName,KeyType:o.KeyType})),Projection:t.Projection?{ProjectionType:t.Projection.ProjectionType}:void 0})).sort((t,o)=>t.IndexName.localeCompare(o.IndexName))),e.LocalSecondaryIndexes&&e.LocalSecondaryIndexes.length>0&&(n.LocalSecondaryIndexes=e.LocalSecondaryIndexes.map(t=>({IndexName:t.IndexName,KeySchema:t.KeySchema?.map(o=>({AttributeName:o.AttributeName,KeyType:o.KeyType})),Projection:t.Projection?{ProjectionType:t.Projection.ProjectionType}:void 0})).sort((t,o)=>t.IndexName.localeCompare(o.IndexName))),n}import{CreateTableCommand as Ae}from"@aws-sdk/client-dynamodb";import{confirm as we,isCancel as Ie,cancel as Ce,intro as ze,outro as H,spinner as De}from"@clack/prompts";async function V(e){ze("Mizzle Push");let{config:n,force:t}=e,o=e.discoverSchema||A,a=e.client||g(n);try{let i=await o(n),r=await D(a),s=w(i,r);if(s.length===0){H("Remote is up to date.");return}console.log(`Pushing ${s.length} changes to remote...`);let l=t;if(l||(l=await we({message:"Do you want to apply these changes?"})),Ie(l)||!l){Ce("Operation cancelled.");return}let m=De();m.start("Pushing changes...");for(let c of s)c.type==="create"?(m.message(`Creating table: ${c.table.TableName}`),await a.send(new Ae({TableName:c.table.TableName,AttributeDefinitions:c.table.AttributeDefinitions,KeySchema:c.table.KeySchema,GlobalSecondaryIndexes:c.table.GlobalSecondaryIndexes,LocalSecondaryIndexes:c.table.LocalSecondaryIndexes,BillingMode:"PAY_PER_REQUEST"}))):c.type==="delete"?console.log(`Untracked table found: ${c.tableName} (Skipping deletion)`):c.type==="update"&&m.message(`Updating table: ${c.tableName} (Not fully implemented)`);m.stop("Push complete."),H("Done")}catch(i){console.error("Error pushing changes:",i),process.exit(1)}}import"@aws-sdk/client-dynamodb";import{intro as Le,outro as J,spinner as Oe}from"@clack/prompts";async function W(e){Le("Mizzle List Tables");let n=e.client||g(e.config),t=Oe();t.start("Fetching remote tables...");try{let o=await D(n);t.stop("Fetched remote tables.");let a=Object.values(o.tables);if(a.length===0){console.log("No tables found in the remote environment."),J("Done");return}console.log(`Found ${a.length} tables:`);for(let i of a){console.log(`- ${i.TableName}`);let r=i.KeySchema.find(l=>l.KeyType==="HASH")?.AttributeName,s=i.KeySchema.find(l=>l.KeyType==="RANGE")?.AttributeName;console.log(` PK: ${r}, SK: ${s||"(none)"}`),i.GlobalSecondaryIndexes&&i.GlobalSecondaryIndexes.length>0&&console.log(` GSIs: ${i.GlobalSecondaryIndexes.map(l=>l.IndexName).join(", ")}`)}J("Done")}catch(o){t.stop("Failed to fetch tables."),console.error("Error listing tables:",o),process.exit(1)}}import{ListTablesCommand as ve,DeleteTableCommand as Me}from"@aws-sdk/client-dynamodb";import{intro as Ke,outro as L,multiselect as _e,confirm as ke,isCancel as q,cancel as Ye,spinner as Pe}from"@clack/prompts";async function X(e){Ke("Mizzle Drop Tables");let n=e.client||g(e.config);try{let t=new ve({}),a=(await n.send(t)).TableNames||[];if(a.length===0){console.log("No tables found in the remote environment."),L("Done");return}let i=await _e({message:"Select tables to DELETE (This action is irreversible!)",options:a.map(m=>({value:m,label:m}))});if(q(i)){Ye("Operation cancelled.");return}let r=i;if(r.length===0){console.log("No tables selected."),L("Done");return}let s=await ke({message:`Are you SURE you want to delete ${r.length} table(s)?`});if(q(s)||!s){console.log("Operation cancelled."),L("Done");return}let l=Pe();l.start("Deleting tables...");for(let m of r)l.message(`Deleting ${m}...`),await n.send(new Me({TableName:m}));l.stop("All selected tables deleted."),L("Done")}catch(t){console.error("Error dropping tables:",t),process.exit(1)}}var h=new Re;h.name("mizzle").description("Mizzle Migration CLI").version("0.0.1");h.command("init").description("Initialize Mizzle configuration").action(async()=>{try{await G()}catch(e){let n=e instanceof Error?e.message:String(e);b.log.error(n),process.exit(1)}});h.command("generate").description("Generate a new migration snapshot and script").option("-n, --name <name>","Migration name").action(async e=>{try{let n=await N();await F({config:n,name:e.name})}catch(n){let t=n instanceof Error?n.message:String(n);b.log.error(t),process.exit(1)}});h.command("push").description("Directly apply schema changes to the target DynamoDB environment").option("-y, --yes","Skip confirmation").action(async e=>{try{let n=await N();await V({config:n,force:e.yes})}catch(n){let t=n instanceof Error?n.message:String(n);b.log.error(t),process.exit(1)}});h.command("list").description("List all existing DynamoDB tables in the environment").action(async()=>{try{let e=await N();await W({config:e})}catch(e){let n=e instanceof Error?e.message:String(e);b.log.error(n),process.exit(1)}});h.command("drop").description("Interactive command to select and delete DynamoDB tables").action(async()=>{try{let e=await N();await X({config:e})}catch(e){let n=e instanceof Error?e.message:String(e);b.log.error(n),process.exit(1)}});h.parse();
23
+ `;Ae(e,i),Ke("mizzle.config.ts created successfully!")}import{ListTablesCommand as Le,DescribeTableCommand as Re}from"@aws-sdk/client-dynamodb";async function L(e){let n={},t,o=[];do{let a=await e.send(new Le({ExclusiveStartTableName:t}));a.TableNames&&o.push(...a.TableNames),t=a.LastEvaluatedTableName}while(t);for(let a of o)try{let i=await e.send(new Re({TableName:a}));if(i.Table){let r=Oe(i.Table);n[a]=r}}catch(i){console.warn(`Failed to describe table ${a}:`,i)}return{version:"remote",tables:n}}function Oe(e){let n={TableName:e.TableName,AttributeDefinitions:e.AttributeDefinitions?.map(t=>({AttributeName:t.AttributeName,AttributeType:t.AttributeType})).sort((t,o)=>t.AttributeName.localeCompare(o.AttributeName))||[],KeySchema:e.KeySchema?.map(t=>({AttributeName:t.AttributeName,KeyType:t.KeyType}))||[]};return e.GlobalSecondaryIndexes&&e.GlobalSecondaryIndexes.length>0&&(n.GlobalSecondaryIndexes=e.GlobalSecondaryIndexes.map(t=>({IndexName:t.IndexName,KeySchema:t.KeySchema?.map(o=>({AttributeName:o.AttributeName,KeyType:o.KeyType})),Projection:t.Projection?{ProjectionType:t.Projection.ProjectionType}:void 0})).sort((t,o)=>t.IndexName.localeCompare(o.IndexName))),e.LocalSecondaryIndexes&&e.LocalSecondaryIndexes.length>0&&(n.LocalSecondaryIndexes=e.LocalSecondaryIndexes.map(t=>({IndexName:t.IndexName,KeySchema:t.KeySchema?.map(o=>({AttributeName:o.AttributeName,KeyType:o.KeyType})),Projection:t.Projection?{ProjectionType:t.Projection.ProjectionType}:void 0})).sort((t,o)=>t.IndexName.localeCompare(o.IndexName))),n}import{CreateTableCommand as ze}from"@aws-sdk/client-dynamodb";import{confirm as Pe,isCancel as _e,cancel as Ue,intro as je,outro as G,spinner as ve}from"@clack/prompts";async function V(e){je("Mizzle Push");let{config:n,force:t}=e,o=e.discoverSchema||E,a=e.client||b(n);try{let i=await o(n),r=await L(a),l=A(i,r);if(l.length===0){G("Remote is up to date.");return}console.log(`Pushing ${l.length} changes to remote...`);let s=t;if(s||(s=await Pe({message:"Do you want to apply these changes?"})),_e(s)||!s){Ue("Operation cancelled.");return}let u=ve();u.start("Pushing changes...");for(let m of l)m.type==="create"?(u.message(`Creating table: ${m.table.TableName}`),await a.send(new ze({TableName:m.table.TableName,AttributeDefinitions:m.table.AttributeDefinitions,KeySchema:m.table.KeySchema,GlobalSecondaryIndexes:m.table.GlobalSecondaryIndexes,LocalSecondaryIndexes:m.table.LocalSecondaryIndexes,BillingMode:"PAY_PER_REQUEST"}))):m.type==="delete"?console.log(`Untracked table found: ${m.tableName} (Skipping deletion)`):m.type==="update"&&u.message(`Updating table: ${m.tableName} (Not fully implemented)`);u.stop("Push complete."),G("Done")}catch(i){console.error("Error pushing changes:",i),process.exit(1)}}import"@aws-sdk/client-dynamodb";import{intro as Ye,outro as q,spinner as $e}from"@clack/prompts";async function J(e){Ye("Mizzle List Tables");let n=e.client||b(e.config),t=$e();t.start("Fetching remote tables...");try{let o=await L(n);t.stop("Fetched remote tables.");let a=Object.values(o.tables);if(a.length===0){console.log("No tables found in the remote environment."),q("Done");return}console.log(`Found ${a.length} tables:`);for(let i of a){console.log(`- ${i.TableName}`);let r=i.KeySchema.find(s=>s.KeyType==="HASH")?.AttributeName,l=i.KeySchema.find(s=>s.KeyType==="RANGE")?.AttributeName;console.log(` PK: ${r}, SK: ${l||"(none)"}`),i.GlobalSecondaryIndexes&&i.GlobalSecondaryIndexes.length>0&&console.log(` GSIs: ${i.GlobalSecondaryIndexes.map(s=>s.IndexName).join(", ")}`)}q("Done")}catch(o){t.stop("Failed to fetch tables."),console.error("Error listing tables:",o),process.exit(1)}}import{ListTablesCommand as Fe,DeleteTableCommand as He}from"@aws-sdk/client-dynamodb";import{intro as Ge,outro as R,multiselect as Ve,confirm as qe,isCancel as W,cancel as Je,spinner as We}from"@clack/prompts";async function Q(e){Ge("Mizzle Drop Tables");let n=e.client||b(e.config);try{let t=new Fe({}),a=(await n.send(t)).TableNames||[];if(a.length===0){console.log("No tables found in the remote environment."),R("Done");return}let i=await Ve({message:"Select tables to DELETE (This action is irreversible!)",options:a.map(u=>({value:u,label:u}))});if(W(i)){Je("Operation cancelled.");return}let r=i;if(r.length===0){console.log("No tables selected."),R("Done");return}let l=await qe({message:`Are you SURE you want to delete ${r.length} table(s)?`});if(W(l)||!l){console.log("Operation cancelled."),R("Done");return}let s=We();s.start("Deleting tables...");for(let u of r)s.message(`Deleting ${u}...`),await n.send(new He({TableName:u}));s.stop("All selected tables deleted."),R("Done")}catch(t){console.error("Error dropping tables:",t),process.exit(1)}}var g=new Qe;g.name("mizzle").description("Mizzle Migration CLI").version("0.0.1");g.command("init").description("Initialize Mizzle configuration").action(async()=>{try{await H()}catch(e){let n=e instanceof Error?e.message:String(e);x.log.error(n),process.exit(1)}});g.command("generate").description("Generate a new migration snapshot and script").option("-n, --name <name>","Migration name").action(async e=>{try{let n=await N();await F({config:n,name:e.name})}catch(n){let t=n instanceof Error?n.message:String(n);x.log.error(t),process.exit(1)}});g.command("push").description("Directly apply schema changes to the target DynamoDB environment").option("-y, --yes","Skip confirmation").action(async e=>{try{let n=await N();await V({config:n,force:e.yes})}catch(n){let t=n instanceof Error?n.message:String(n);x.log.error(t),process.exit(1)}});g.command("list").description("List all existing DynamoDB tables in the environment").action(async()=>{try{let e=await N();await J({config:e})}catch(e){let n=e instanceof Error?e.message:String(e);x.log.error(n),process.exit(1)}});g.command("drop").description("Interactive command to select and delete DynamoDB tables").action(async()=>{try{let e=await N();await Q({config:e})}catch(e){let n=e instanceof Error?e.message:String(e);x.log.error(n),process.exit(1)}});g.parse();
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{a as e}from"./chunk-SNI5EXF5.js";export{e as defineConfig};
2
+ import{a as e}from"./chunk-DKDRM5WU.js";export{e as defineConfig};
package/package.json CHANGED
@@ -1,40 +1,59 @@
1
1
  {
2
2
  "name": "@aurios/mizzling",
3
- "version": "1.1.0",
4
- "private": false,
5
- "type": "module",
6
- "bin": {
7
- "mizzling": "./dist/cli.js"
8
- },
9
- "exports": {
10
- ".": "./dist/index.js"
3
+ "version": "1.1.2",
4
+ "description": "A CLI tool for managing Mizzle projects",
5
+ "publishConfig": {
6
+ "access": "public",
7
+ "provenance": true
11
8
  },
9
+ "keywords": [
10
+ "aws",
11
+ "database",
12
+ "dynamodb",
13
+ "mizzle",
14
+ "nosql",
15
+ "orm",
16
+ "singletable",
17
+ "ts",
18
+ "typescript"
19
+ ],
20
+ "homepage": "https://mizzle-docs.vercel.app",
21
+ "license": "MIT",
12
22
  "author": {
13
23
  "name": "Lucas",
14
24
  "url": "https://github.com/realfakenerd"
15
25
  },
16
26
  "repository": {
17
- "url": "https://github.com/realfakenerd/mizzle"
27
+ "type": "git",
28
+ "url": "https://github.com/realfakenerd/mizzle.git",
29
+ "directory": "packages/mizzling"
18
30
  },
19
- "scripts": {
20
- "check": "tsc --noEmit",
21
- "build": "tsup",
22
- "lint": "eslint \"src/**/*.ts\""
31
+ "bin": {
32
+ "mizzling": "./dist/cli.js"
33
+ },
34
+ "type": "module",
35
+ "exports": {
36
+ ".": "./dist/index.js"
23
37
  },
24
38
  "dependencies": {
25
39
  "@aws-sdk/client-dynamodb": "3.962.0",
26
40
  "@aws-sdk/credential-provider-ini": "3.962.0",
27
41
  "@aws-sdk/lib-dynamodb": "3.962.0",
28
42
  "@clack/prompts": "^0.11.0",
29
- "@mizzle/shared": "workspace:*",
30
43
  "@smithy/node-http-handler": "^4.4.7",
31
44
  "commander": "^14.0.2",
32
45
  "fast-glob": "^3.3.3"
33
46
  },
34
47
  "devDependencies": {
35
- "@mizzle/eslint-config": "workspace:*",
36
- "@mizzle/tsconfig": "workspace:*",
37
- "@aurios/mizzle": "workspace:*",
38
- "tsup": "^8.5.1"
48
+ "tsup": "^8.5.1",
49
+ "@aurios/mizzle": "1.1.3",
50
+ "@repo/shared": "0.0.3",
51
+ "@repo/typescript-config": "0.0.0",
52
+ "@repo/vitest-config": "0.0.0"
53
+ },
54
+ "scripts": {
55
+ "check": "tsc --noEmit",
56
+ "build": "tsup",
57
+ "test": "vitest run"
39
58
  }
40
- }
59
+ }
package/src/cli.ts CHANGED
@@ -9,21 +9,18 @@ import { dropCommand } from "./commands/drop";
9
9
 
10
10
  const program = new Command();
11
11
 
12
- program
13
- .name("mizzle")
14
- .description("Mizzle Migration CLI")
15
- .version("0.0.1");
12
+ program.name("mizzle").description("Mizzle Migration CLI").version("0.0.1");
16
13
 
17
14
  program
18
15
  .command("init")
19
16
  .description("Initialize Mizzle configuration")
20
17
  .action(async () => {
21
18
  try {
22
- await initCommand();
19
+ await initCommand();
23
20
  } catch (e) {
24
- const message = e instanceof Error ? e.message : String(e);
25
- p.log.error(message);
26
- process.exit(1);
21
+ const message = e instanceof Error ? e.message : String(e);
22
+ p.log.error(message);
23
+ process.exit(1);
27
24
  }
28
25
  });
29
26
 
@@ -33,12 +30,12 @@ program
33
30
  .option("-n, --name <name>", "Migration name")
34
31
  .action(async (options) => {
35
32
  try {
36
- const config = await loadConfig();
37
- await generateCommand({ config, name: options.name });
33
+ const config = await loadConfig();
34
+ await generateCommand({ config, name: options.name });
38
35
  } catch (e) {
39
- const message = e instanceof Error ? e.message : String(e);
40
- p.log.error(message);
41
- process.exit(1);
36
+ const message = e instanceof Error ? e.message : String(e);
37
+ p.log.error(message);
38
+ process.exit(1);
42
39
  }
43
40
  });
44
41
 
@@ -48,12 +45,12 @@ program
48
45
  .option("-y, --yes", "Skip confirmation")
49
46
  .action(async (options) => {
50
47
  try {
51
- const config = await loadConfig();
52
- await pushCommand({ config, force: options.yes });
48
+ const config = await loadConfig();
49
+ await pushCommand({ config, force: options.yes });
53
50
  } catch (e) {
54
- const message = e instanceof Error ? e.message : String(e);
55
- p.log.error(message);
56
- process.exit(1);
51
+ const message = e instanceof Error ? e.message : String(e);
52
+ p.log.error(message);
53
+ process.exit(1);
57
54
  }
58
55
  });
59
56
 
@@ -62,12 +59,12 @@ program
62
59
  .description("List all existing DynamoDB tables in the environment")
63
60
  .action(async () => {
64
61
  try {
65
- const config = await loadConfig();
66
- await listCommand({ config });
62
+ const config = await loadConfig();
63
+ await listCommand({ config });
67
64
  } catch (e) {
68
- const message = e instanceof Error ? e.message : String(e);
69
- p.log.error(message);
70
- process.exit(1);
65
+ const message = e instanceof Error ? e.message : String(e);
66
+ p.log.error(message);
67
+ process.exit(1);
71
68
  }
72
69
  });
73
70
 
@@ -76,13 +73,13 @@ program
76
73
  .description("Interactive command to select and delete DynamoDB tables")
77
74
  .action(async () => {
78
75
  try {
79
- const config = await loadConfig();
80
- await dropCommand({ config });
76
+ const config = await loadConfig();
77
+ await dropCommand({ config });
81
78
  } catch (e) {
82
- const message = e instanceof Error ? e.message : String(e);
83
- p.log.error(message);
84
- process.exit(1);
79
+ const message = e instanceof Error ? e.message : String(e);
80
+ p.log.error(message);
81
+ process.exit(1);
85
82
  }
86
83
  });
87
84
 
88
- program.parse();
85
+ program.parse();
@@ -3,69 +3,69 @@ import { DynamoDBClient, ListTablesCommand, DeleteTableCommand } from "@aws-sdk/
3
3
  import { intro, outro, multiselect, confirm, isCancel, cancel, spinner } from "@clack/prompts";
4
4
 
5
5
  interface DropOptions {
6
- config: MizzleConfig;
7
- client?: DynamoDBClient;
6
+ config: MizzleConfig;
7
+ client?: DynamoDBClient;
8
8
  }
9
9
 
10
10
  export async function dropCommand(options: DropOptions) {
11
- intro("Mizzle Drop Tables");
11
+ intro("Mizzle Drop Tables");
12
12
 
13
- const client = options.client || getClient(options.config);
14
-
15
- try {
16
- // 1. Fetch tables
17
- const listCmd = new ListTablesCommand({});
18
- const listRes = await client.send(listCmd);
19
- const tableNames = listRes.TableNames || [];
13
+ const client = options.client || getClient(options.config);
20
14
 
21
- if (tableNames.length === 0) {
22
- console.log("No tables found in the remote environment.");
23
- outro("Done");
24
- return;
25
- }
15
+ try {
16
+ // 1. Fetch tables
17
+ const listCmd = new ListTablesCommand({});
18
+ const listRes = await client.send(listCmd);
19
+ const tableNames = listRes.TableNames || [];
26
20
 
27
- // 2. Select tables
28
- const selectedTables = await multiselect({
29
- message: "Select tables to DELETE (This action is irreversible!)",
30
- options: tableNames.map(name => ({ value: name, label: name }))
31
- });
21
+ if (tableNames.length === 0) {
22
+ console.log("No tables found in the remote environment.");
23
+ outro("Done");
24
+ return;
25
+ }
32
26
 
33
- if (isCancel(selectedTables)) {
34
- cancel("Operation cancelled.");
35
- return;
36
- }
27
+ // 2. Select tables
28
+ const selectedTables = await multiselect({
29
+ message: "Select tables to DELETE (This action is irreversible!)",
30
+ options: tableNames.map((name) => ({ value: name, label: name })),
31
+ });
37
32
 
38
- const tablesToDelete = selectedTables as string[];
39
- if (tablesToDelete.length === 0) {
40
- console.log("No tables selected.");
41
- outro("Done");
42
- return;
43
- }
33
+ if (isCancel(selectedTables)) {
34
+ cancel("Operation cancelled.");
35
+ return;
36
+ }
44
37
 
45
- // 3. Confirm
46
- const confirmed = await confirm({
47
- message: `Are you SURE you want to delete ${tablesToDelete.length} table(s)?`
48
- });
38
+ const tablesToDelete = selectedTables as string[];
39
+ if (tablesToDelete.length === 0) {
40
+ console.log("No tables selected.");
41
+ outro("Done");
42
+ return;
43
+ }
49
44
 
50
- if (isCancel(confirmed) || !confirmed) {
51
- console.log("Operation cancelled.");
52
- outro("Done");
53
- return;
54
- }
45
+ // 3. Confirm
46
+ const confirmed = await confirm({
47
+ message: `Are you SURE you want to delete ${tablesToDelete.length} table(s)?`,
48
+ });
55
49
 
56
- // 4. Delete
57
- const s = spinner();
58
- s.start("Deleting tables...");
50
+ if (isCancel(confirmed) || !confirmed) {
51
+ console.log("Operation cancelled.");
52
+ outro("Done");
53
+ return;
54
+ }
59
55
 
60
- for (const tableName of tablesToDelete) {
61
- s.message(`Deleting ${tableName}...`);
62
- await client.send(new DeleteTableCommand({ TableName: tableName }));
63
- }
56
+ // 4. Delete
57
+ const s = spinner();
58
+ s.start("Deleting tables...");
64
59
 
65
- s.stop("All selected tables deleted.");
66
- outro("Done");
67
- } catch (error) {
68
- console.error("Error dropping tables:", error);
69
- process.exit(1);
60
+ for (const tableName of tablesToDelete) {
61
+ s.message(`Deleting ${tableName}...`);
62
+ await client.send(new DeleteTableCommand({ TableName: tableName }));
70
63
  }
64
+
65
+ s.stop("All selected tables deleted.");
66
+ outro("Done");
67
+ } catch (error) {
68
+ console.error("Error dropping tables:", error);
69
+ process.exit(1);
70
+ }
71
71
  }