@webflow/webflow-cli 1.6.10 → 1.6.12

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @webflow/webflow-cli
2
2
 
3
+ ## 1.6.12
4
+
5
+ ### Patch Changes
6
+
7
+ - Updates to extension feature flagging support
8
+
9
+ ## 1.6.11
10
+
11
+ ### Patch Changes
12
+
13
+ - Updating Designer Extension templates and adding ESLint configs
14
+
3
15
  ## 1.6.10
4
16
 
5
17
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1018,7 +1018,7 @@ ${s.message}`,s}},Psi={loadJs:Tsi,loadJsSync:Cmt,loadJson:ksi,loadYaml:Fsi};V_e.
1018
1018
  `).trim(),{parser:"css"});return Tot(s)}catch{return t8.log(PN("There was a problem skipping global tags from CSS. Falling back to normal global CSS.")),e}}function Pot(e){return e.reduce((r,i)=>(i.name==="global"?r.globalCss=i:r.rest.push(i),r),{rest:[]})}var MS=class extends Error{constructor(r){super(r)}},tCe=e=>t8.render({text:`${tpe("Something went wrong while trying to export your components:")} ${MA.red(e.message)}
1019
1019
  ${e==null?void 0:e.stack}`});function Oot(e){if(e.status>=200&&e.status<300){switch(e.status){case 206:t8.log(PN("You exceeded the limit of components and some components were not exported."));break;case 207:t8.log(PN("Certain components couldn't be exported due to an unexpected error."));break}return}switch(e.status){case 400:throw new MS("Something unexpected happened. Report a bug here: https://airtable.com/shr47EWPVsV9xCwOH");case 401:throw new MS("Your access token is invalid for the provided siteId. Double check your configs in your .webflowrc configuration file.");case 404:throw new MS("You're not currently enrolled in the DevLink beta. You can apply for access here: https://webflow.com/devlink");default:throw new MS("Something went wrong. Try again later or report a bug here: https://airtable.com/shr47EWPVsV9xCwOH")}}async function dHn(e){try{let{siteId:r,host:i,authToken:s,components:c,cssModules:l}=e,p=new URLSearchParams({cssModules:l?"true":"false"});c&&p.append("components",encodeURIComponent(c));let h=`?${p.toString()}`,g=await IN(`${i}/devlink/${r}${h}`,{headers:{Authorization:`Bearer ${s}`},timeout:6e4});Oot(g);let v=await g.json();return v.components||v}catch(r){if(r instanceof MS)tCe(r),process.exit(1);else throw r}}async function fHn(e){try{let{siteId:r,host:i,authToken:s}=e,c=await IN(`${i}/devlink/${r}/engine`,{headers:{Authorization:`Bearer ${s}`},timeout:6e4});return Oot(c),await c.json()}catch(r){if(r instanceof MS)tCe(r),process.exit(1);else throw r}}async function rCe(e){let{rootDir:r}=e;t8.render({text:`Exporting components into ${e.rootDir}.`,showSpinner:!0});try{let[i,s]=await Promise.all([dHn(e),fHn(e)]),c=s;if(e.skipTagSelectors===!0){let{rest:l,globalCss:p}=Pot(i),h=Fot(p);c.push(...l,h)}else c.push(...i);await NUe(c,e),t8.render({text:epe(`Succesfully exported components into ${r} folder.`),flushLogs:!0})}catch(i){i instanceof Error&&(tCe(i),FK(i))}}async function Bot(e){lit();let r={...e&&e.length>0?{components:_be(e),overwriteModule:!1}:{overwriteModule:!0}},i=await ape(r);if(!i)return Not.default.exit();await rCe(i)}var p2t=ol(require("http"));var d2t=ol(Vut()),f2t=require("fs"),h2t=ol(require("path")),m2t=require("commander");var Zmt=ol($dt()),lTe=require("commander"),Q_e=require("fs");var Kmt=ol(zmt()),Hmt=require("commander"),J_e=async(e,r)=>{let i=await roi(r);return{filepath:i.filepath,config:{publicDir:e,...i.config}}},roi=async e=>{let i=await(0,Kmt.cosmiconfig)("webflow",{searchPlaces:[e]}).search();return i||Hmt.program.error(`No ${e} file was found. Run this command within your extension folder.`),i};var e2t=ol(Qmt()),X_e=ol(require("path")),loi=5*1024*1024,poi=new Set(["application/javascript","application/json","application/xml","image/png","image/jpeg","image/gif","image/svg+xml","image/webp","image/vnd.microsoft.icon","image/x-icon","video/webm","font/ttf","font/otf","font/woff","font/woff2","text/plain","text/markdown","text/html","text/css"]),t2t=async(e,r,i)=>{let{config:s,filepath:c}=await J_e(e,r),l=X_e.join(c,".."),p=!0,h=!1,g=b=>{let E=b.name,S=e2t.default.lookup(E);return E==="index.html"&&(h=!0),E&&E.endsWith(".DS_Store")||!S?!1:poi.has(S)?b:(console.log(`Invalid file type: ${S} for file: ${E}`),p=!1,!1)},v=b=>{(0,Q_e.unlink)(i,E=>{E&&console.error(`Failed to delete file: ${E}`),lTe.program.error(b)})};return console.log(`Packaging the contents of the ${s.publicDir} folder into ${i}...`),new Promise(b=>{let E=(0,Zmt.default)("zip",{zlib:{level:9}}),S=(0,Q_e.createWriteStream)(X_e.join(l,i));S.on("close",()=>{b(void 0)}),E.directory(X_e.join(l,s.publicDir),!1,g),E.file(c,{name:r}),E.pipe(S),E.finalize(),E.on("warning",w=>{console.log(w)}),E.on("error",w=>{lTe.program.error(w.message)}),E.on("finish",()=>{if(!h){v("Could not find index.html in your `publicDir`, all Designer Extension code needs to be inside of `publicDir`");return}if(!p){v("Bundling failed due to invalid file types");return}if(!E.pointer()||E.pointer()===0){v("Bundling failed with no output");return}if(E.pointer()>=loi){v("Bundling failed due to the bundle exceeding 5MB");return}console.log(`${E.pointer()} total bytes written`),console.log(`Done! ${i} is ready for you to upload to your Webflow app.`)})})};var iT=ol(require("fs")),i4=ol(require("path"));var lae="webflow.json",r2t="index.html",n2t="bundle.zip",pTe="public",dTe="scaffolds",Z_e="default",i2t="./";var a2t="package.json",s2t="wf-placeholder-name",fTe=e=>JSON.stringify(e,null,2),o2t=e=>{let r="\u2500".repeat(e.length+2);return"\u256D"+r+`\u256E
1020
1020
  \u2502 `+e+` \u2502
1021
- \u2570`+r+"\u256F"};var u2t=async(e,r=i2t,i=Z_e,s)=>{let c=s[i];try{for(let l of c){let p=i4.join(r,l),h=foi(p,i,e);if(l.includes(a2t)||l.includes(lae))await doi(l,h,e);else{let g=await iT.promises.readFile(l);await l2t(h,g)}}}catch(l){console.error("Error writing file, ",l)}},hTe=async()=>{let e={},r=i4.resolve(__dirname),i=i4.join(r,dTe),s=await iT.promises.readdir(i);for(let c of s){let l=i4.join(i,c),p=await c2t(l);e[c]=p}return e},c2t=async e=>{let r=[];try{let i=await iT.promises.readdir(e);for(let s of i){let c=i4.join(e,s);if((await iT.promises.stat(c)).isDirectory()){let p=await c2t(c);r.push(...p)}else r.push(c)}}catch(i){console.error(`Error reading ${i4}, `,i)}return r},l2t=async(e,r)=>{try{await iT.promises.mkdir(i4.dirname(e),{recursive:!0}),await iT.promises.writeFile(e,r)}catch(i){console.error("Error writing file ",i)}},doi=async(e,r,i)=>iT.promises.readFile(e,"utf8").then(async s=>{let c=s.replace(s2t,i);await l2t(r,c)}),foi=(e,r,i)=>{let s=i4.join(dTe,r),c=e.indexOf(s);if(c!==-1){let l=e.substring(c+s.length+1);return i4.join(i,l)}return""};var _2t=async()=>{let e=await hTe(),r=Object.keys(e).join(", ");console.log(`Your available templates are: ${r}`),console.log('\u{1F4A1} Syntax: "webflow extension init projectName templateName"'),console.log('\u{1F31F} Example: "webflow extension init my-first-extension react"')},g2t=async(e,r=Z_e)=>{let i=`./${e}`;console.log(`Scaffolding your new extension named: ${e}...`);let s=await hTe();await u2t(e,i,r,s),console.log(`Done! Check out ${i}/README.md for steps on how to develop your extension.`)},x2t=()=>t2t(pTe,lae,n2t),v2t=async e=>{let{config:r,filepath:i}=await J_e(pTe,lae),s=h2t.join(i,"..",r.publicDir,r2t),l=(await NV([],!0)).extensionTemplateDomain||"webflow-ext.com",p=r.apiVersion==="2"?"template/v2":"template",h=Object.keys(r.featureFlags||{}).map(w=>r.featureFlags&&r.featureFlags[w]===!0?`ff=${w}`:null).filter(Boolean).join("&"),g=h?`&${h}`:"",b=await(await IN(`https://${l}/${p}?name=${r.name}${g}`)).text(),E=new p2t.Server((w,k)=>{if(w.url==="/"){f2t.promises.readFile(s,{encoding:"utf-8"}).catch(B=>{m2t.program.error(B.message)}).then(B=>{let V=b.replace("{{ui}}",B);return k.writeHead(200,{"Content-Length":Buffer.byteLength(V),"Content-Type":"text/html"}),k.end(V)});return}if(w.url==="/__webflow")return k.writeHead(200,{"Content-Length":Buffer.byteLength(fTe(r)),"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"*"}),k.end(fTe(r));(0,d2t.default)(w,k,{public:r.publicDir,cleanUrls:!1,directoryListing:!1})}),S=hoi(e);E.listen(S),console.log(o2t(`Serving your extension at http://localhost:${S}`)+`
1021
+ \u2570`+r+"\u256F"};var u2t=async(e,r=i2t,i=Z_e,s)=>{let c=s[i];try{for(let l of c){let p=i4.join(r,l),h=foi(p,i,e);if(l.includes(a2t)||l.includes(lae))await doi(l,h,e);else{let g=await iT.promises.readFile(l);await l2t(h,g)}}}catch(l){console.error("Error writing file, ",l)}},hTe=async()=>{let e={},r=i4.resolve(__dirname),i=i4.join(r,dTe),s=await iT.promises.readdir(i);for(let c of s){let l=i4.join(i,c),p=await c2t(l);e[c]=p}return e},c2t=async e=>{let r=[];try{let i=await iT.promises.readdir(e);for(let s of i){let c=i4.join(e,s);if((await iT.promises.stat(c)).isDirectory()){let p=await c2t(c);r.push(...p)}else r.push(c)}}catch(i){console.error(`Error reading ${i4}, `,i)}return r},l2t=async(e,r)=>{try{await iT.promises.mkdir(i4.dirname(e),{recursive:!0}),await iT.promises.writeFile(e,r)}catch(i){console.error("Error writing file ",i)}},doi=async(e,r,i)=>iT.promises.readFile(e,"utf8").then(async s=>{let c=s.replace(s2t,i);await l2t(r,c)}),foi=(e,r,i)=>{let s=i4.join(dTe,r),c=e.indexOf(s);if(c!==-1){let l=e.substring(c+s.length+1);return i4.join(i,l)}return""};var _2t=async()=>{let e=await hTe(),r=Object.keys(e).join(", ");console.log(`Your available templates are: ${r}`),console.log('\u{1F4A1} Syntax: "webflow extension init projectName templateName"'),console.log('\u{1F31F} Example: "webflow extension init my-first-extension react"')},g2t=async(e,r=Z_e)=>{let i=`./${e}`;console.log(`Scaffolding your new extension named: ${e}...`);let s=await hTe();await u2t(e,i,r,s),console.log(`Done! Check out ${i}/README.md for steps on how to develop your extension.`)},x2t=()=>t2t(pTe,lae,n2t),v2t=async e=>{let{config:r,filepath:i}=await J_e(pTe,lae),s=h2t.join(i,"..",r.publicDir,r2t),l=(await NV([],!0)).extensionTemplateDomain||"webflow-ext.com",p=r.apiVersion==="2"?"template/v2":"template",h=Object.keys(r.featureFlags||{}).map(w=>{var k;return((k=r.featureFlags)==null?void 0:k[w])===!0?`ff_on=${w}`:`ff_off=${w}`}).join("&"),g=h?`&${h}`:"",b=await(await IN(`https://${l}/${p}?name=${r.name}${g}`)).text(),E=new p2t.Server((w,k)=>{if(w.url==="/"){f2t.promises.readFile(s,{encoding:"utf-8"}).catch(B=>{m2t.program.error(B.message)}).then(B=>{let V=b.replace("{{ui}}",B);return k.writeHead(200,{"Content-Length":Buffer.byteLength(V),"Content-Type":"text/html"}),k.end(V)});return}if(w.url==="/__webflow")return k.writeHead(200,{"Content-Length":Buffer.byteLength(fTe(r)),"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Headers":"*"}),k.end(fTe(r));(0,d2t.default)(w,k,{public:r.publicDir,cleanUrls:!1,directoryListing:!1})}),S=hoi(e);E.listen(S),console.log(o2t(`Serving your extension at http://localhost:${S}`)+`
1022
1022
  `)},hoi=e=>{if(e){let r=parseInt(e,10);return isNaN(r)?(console.log("Invalid port number provided. Using the default port "+1337),1337):r}return 1337};var _Te=require("child_process"),ege=class{constructor(r){this.packageName=r}checkForUpdates(){try{let r=this.getLatestVersion(),i=this.getInstalledVersion();if(typeof r!="string"||typeof i!="string"||r===""||i==="")return;if(r>i)return`A new version of ${this.packageName} is available! Run \`npm i ${this.packageName}\` to get the latest version.
1023
1023
  `}catch{return}}getLatestVersion(){return(0,_Te.execSync)(`npm view ${this.packageName} version`,{stdio:["ignore","pipe","ignore"]}).toString().trim()}getInstalledVersion(){let r=(0,_Te.execSync)(`npm list ${this.packageName} --depth=0 --json`,{stdio:["ignore","pipe","ignore"]}).toString().trim();return JSON.parse(r).dependencies[this.packageName].version}};var tge=new y2t.Command,moi=new ege("@webflow/webflow-cli");tge.name("webflow").description("Webflow CLI").hook("postAction",()=>{let e=moi.checkForUpdates();e&&console.log(PN(e))});var rge=tge.command("extension").description("CLI for developing Designer extensions.");rge.command("list").description("Get list of project templates that can be used for `init`").action(_2t);rge.command("init").description("Bootstrap a Designer extension.").argument("<projectName>","Your extension's name").argument("[scaffoldName]","Which starting point you plan to use","default").action(g2t);rge.command("bundle").description("Prepare package that can be uploaded to Webflow.").action(x2t);rge.command("serve").description("Serve your extension locally.").argument("[port]","The port to serve your extension on").action(v2t);var _oi=tge.command("devlink").description("CLI for managing your Webflow components.");_oi.command("sync").argument("[components...]","A list of components to sync. If none is provided, all components will be synced.").description("Sync your Webflow components to your filesystem.").action(Bot);tge.parse();
1024
1024
  /*! Bundled license information:
@@ -0,0 +1,25 @@
1
+ {
2
+ "extends": [
3
+ "eslint:recommended",
4
+ "plugin:@typescript-eslint/eslint-recommended",
5
+ "plugin:@typescript-eslint/recommended"
6
+ ],
7
+ "parser": "@typescript-eslint/parser",
8
+ "parserOptions": {
9
+ "project": "./tsconfig.json"
10
+ },
11
+ "plugins": ["@typescript-eslint", "promise"],
12
+ "rules": {
13
+ "@typescript-eslint/explicit-function-return-type": "off",
14
+ "@typescript-eslint/no-explicit-any": "off",
15
+ "@typescript-eslint/no-floating-promises": "error",
16
+ "@typescript-eslint/no-misused-promises": [
17
+ "error",
18
+ { "checksVoidReturn": false }
19
+ ],
20
+ "@typescript-eslint/no-unused-vars": "error",
21
+ "no-async-promise-executor": "error",
22
+ "require-await": "error",
23
+ "promise/catch-or-return": "error"
24
+ }
25
+ }
@@ -5,11 +5,17 @@
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "build": "npm install && tsc -p tsconfig.json && webflow extension bundle",
8
- "dev": "npm install && concurrently -r \"webflow extension serve\" \"tsc -p tsconfig.json --watch --preserveWatchOutput\""
8
+ "dev": "npm install && concurrently -r \"webflow extension serve\" \"tsc -p tsconfig.json --watch --preserveWatchOutput\"",
9
+ "lint": "eslint . --ext .ts"
9
10
  },
10
11
  "devDependencies": {
11
- "@webflow/designer-extension-typings": "*",
12
- "concurrently": "*",
13
- "typescript": "*"
12
+ "@webflow/designer-extension-typings": "^0.2.0-beta.8",
13
+ "@typescript-eslint/eslint-plugin": "^7.7.0",
14
+ "@typescript-eslint/parser": "^7.7.0",
15
+ "eslint": "^8.5.7",
16
+ "concurrently": "^8.2.2",
17
+ "typescript": "^5.4.5",
18
+ "eslint-plugin-promise": "^6.1.1"
14
19
  }
15
20
  }
21
+
@@ -11,12 +11,11 @@ addButtonListeners();
11
11
 
12
12
  document.getElementById("extension-form").onsubmit = async (event) => {
13
13
  event.preventDefault();
14
-
15
14
  // Get the current selected Element
16
15
  const el = await webflow.getSelectedElement();
17
16
 
18
17
  // If styles can be set on the Element
19
- if (el && el.styles && el.configurable && el.children) {
18
+ if (el && el.styles && el.children) {
20
19
  //Get current element's style
21
20
  const currentStyle = await el.getStyles();
22
21
 
@@ -24,12 +23,10 @@ document.getElementById("extension-form").onsubmit = async (event) => {
24
23
  const emojiStyle = await createOrUseStyle("emoji-style");
25
24
 
26
25
  // Create a new element that will display the text-emoji
27
- const labelElement = await webflow.createDOM("span");
28
- labelElement.setStyles([...currentStyle, emojiStyle]);
29
- labelElement.setTextContent(selectedEmoji);
30
-
31
- el.setChildren([...el.getChildren(), labelElement]);
32
- await el.save();
26
+ const labelElement = await el.append(webflow.elementPresets.DOM);
27
+ await labelElement.setTag("span");
28
+ await labelElement.setStyles([...currentStyle, emojiStyle]);
29
+ await labelElement.setTextContent(selectedEmoji);
33
30
  } else {
34
31
  alert("Please select a text element");
35
32
  }
@@ -44,8 +41,8 @@ async function createOrUseStyle(styleName) {
44
41
  return style;
45
42
  } else {
46
43
  // Create a new style, return it
47
- const emojiStyle = webflow.createStyle(styleName);
48
- emojiStyle.setProperties({ "background-color": "#FF00FF" });
44
+ const emojiStyle = await webflow.createStyle(styleName);
45
+ await emojiStyle.setProperties({ "background-color": "#FF00FF" });
49
46
  return emojiStyle;
50
47
  }
51
48
  }
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "name": "wf-placeholder-name",
3
3
  "publicDir": "public",
4
- "size": "default"
4
+ "size": "default",
5
+ "apiVersion": "2"
5
6
  }
@@ -0,0 +1,25 @@
1
+ {
2
+ "extends": [
3
+ "eslint:recommended",
4
+ "plugin:@typescript-eslint/eslint-recommended",
5
+ "plugin:@typescript-eslint/recommended"
6
+ ],
7
+ "parser": "@typescript-eslint/parser",
8
+ "parserOptions": {
9
+ "project": "./tsconfig.json"
10
+ },
11
+ "plugins": ["@typescript-eslint", "promise"],
12
+ "rules": {
13
+ "@typescript-eslint/explicit-function-return-type": "off",
14
+ "@typescript-eslint/no-explicit-any": "off",
15
+ "@typescript-eslint/no-floating-promises": "error",
16
+ "@typescript-eslint/no-misused-promises": [
17
+ "error",
18
+ { "checksVoidReturn": false }
19
+ ],
20
+ "@typescript-eslint/no-unused-vars": "error",
21
+ "no-async-promise-executor": "error",
22
+ "require-await": "error",
23
+ "promise/catch-or-return": "error"
24
+ }
25
+ }
@@ -5,16 +5,27 @@
5
5
  "dev": "npm install && concurrently \"webflow extension serve\" \"npm run watch-webpack\"",
6
6
  "build": "npm run build-webpack && webflow extension bundle",
7
7
  "watch-webpack": "webpack --config webpack.config.mjs --mode development --watch",
8
- "build-webpack": "webpack --config webpack.config.mjs --mode production"
8
+ "build-webpack": "webpack --config webpack.config.mjs --mode production",
9
+ "lint": "eslint . --ext .ts,.tsx"
9
10
  },
10
11
  "devDependencies": {
12
+ "@webflow/designer-extension-typings": "^0.2.0-beta.8",
13
+ "concurrently": "^8.2.2",
14
+ "eslint": "^8.5.7",
15
+ "@typescript-eslint/eslint-plugin": "^7.7.0",
16
+ "@typescript-eslint/parser": "^7.7.0",
17
+ "typescript": "^5.4.5",
18
+ "react-dom": "^18.2.0",
19
+ "react": "^18.2.0",
20
+ "@types/react": "^18.2.79",
21
+ "@types/react-dom": "^18.2.25",
11
22
  "@babel/preset-env": "^7.23.2",
12
23
  "@babel/preset-react": "^7.22.15",
13
- "@webflow/designer-extension-typings": "*",
14
- "concurrently": "*",
15
24
  "babel-loader": "^9.1.3",
25
+ "ts-loader": "^9.5.1",
16
26
  "webpack": "^5.89.0",
17
- "webpack-cli": "^5.1.4"
27
+ "webpack-cli": "^5.1.4",
28
+ "eslint-plugin-promise": "^6.1.1"
18
29
  },
19
30
  "dependencies": {
20
31
  "react-dom": "^18.2.0"
@@ -10,4 +10,4 @@
10
10
  <div id="root"></div>
11
11
  <script src="./bundle.js"></script>
12
12
  </body>
13
- </html>
13
+ </html>
@@ -1,15 +1,14 @@
1
1
  import React from "react";
2
2
  import ReactDOM from "react-dom";
3
3
 
4
- const App = () => {
4
+ const App: React.FC = () => {
5
5
  const addText = async () => {
6
6
  // Get the current selected Element
7
- let el = await webflow.getSelectedElement();
7
+ const el = await webflow.getSelectedElement();
8
8
 
9
9
  // If text content can be set, update it!
10
- if (el && el.configurable && el.setTextContent) {
11
- el.setTextContent("hello world!");
12
- await el.save();
10
+ if (el && el.textContent) {
11
+ await el.setTextContent("hello world!");
13
12
  } else {
14
13
  alert("Please select a text element");
15
14
  }
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "public",
4
+ "target": "es6",
5
+ "lib": ["es6", "dom"],
6
+ "typeRoots": ["./node_modules/@types", "./node_modules/@webflow"],
7
+ "jsx": "react",
8
+ "esModuleInterop": true,
9
+ "baseUrl": "./",
10
+ "paths": {
11
+ "react": ["node_modules/react"],
12
+ "react-dom": ["node_modules/react-dom"]
13
+ }
14
+ },
15
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
16
+ "exclude": ["node_modules"]
17
+ }
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "name": "wf-placeholder-name",
3
3
  "publicDir": "public",
4
- "size": "default"
4
+ "size": "default",
5
+ "apiVersion": "2"
5
6
  }
@@ -5,19 +5,20 @@ const filename = fileURLToPath(import.meta.url);
5
5
  const dirname = path.dirname(filename);
6
6
 
7
7
  export default {
8
- entry: "./src/main.js",
8
+ entry: "./src/index.tsx",
9
9
  output: {
10
10
  filename: "bundle.js",
11
11
  path: path.resolve(dirname, "public"),
12
12
  },
13
+ resolve: {
14
+ extensions: [".ts", ".tsx", ".js", ".json"],
15
+ },
13
16
  module: {
14
17
  rules: [
15
18
  {
16
- test: /\.js$/,
19
+ test: /\.(ts|tsx)$/,
17
20
  exclude: /node_modules/,
18
- use: {
19
- loader: "babel-loader",
20
- },
21
+ use: "ts-loader",
21
22
  },
22
23
  {
23
24
  test: /\.css$/,
@@ -0,0 +1,25 @@
1
+ {
2
+ "extends": [
3
+ "eslint:recommended",
4
+ "plugin:@typescript-eslint/eslint-recommended",
5
+ "plugin:@typescript-eslint/recommended"
6
+ ],
7
+ "parser": "@typescript-eslint/parser",
8
+ "parserOptions": {
9
+ "project": "./tsconfig.json"
10
+ },
11
+ "plugins": ["@typescript-eslint", "promise"],
12
+ "rules": {
13
+ "@typescript-eslint/explicit-function-return-type": "off",
14
+ "@typescript-eslint/no-explicit-any": "off",
15
+ "@typescript-eslint/no-floating-promises": "error",
16
+ "@typescript-eslint/no-misused-promises": [
17
+ "error",
18
+ { "checksVoidReturn": false }
19
+ ],
20
+ "@typescript-eslint/no-unused-vars": "error",
21
+ "no-async-promise-executor": "error",
22
+ "require-await": "error",
23
+ "promise/catch-or-return": "error"
24
+ }
25
+ }
@@ -5,11 +5,16 @@
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "build": "npm install && tsc -p tsconfig.json && webflow extension bundle",
8
- "dev": "npm install && concurrently -r \"webflow extension serve\" \"tsc -p tsconfig.json --watch --preserveWatchOutput\""
8
+ "dev": "npm install && concurrently -r \"webflow extension serve\" \"tsc -p tsconfig.json --watch --preserveWatchOutput\"",
9
+ "lint": "eslint . --ext .ts"
9
10
  },
10
11
  "devDependencies": {
11
- "@webflow/designer-extension-typings": "*",
12
- "concurrently": "*",
13
- "typescript": "*"
12
+ "@webflow/designer-extension-typings": "^0.2.0-beta.8",
13
+ "@typescript-eslint/eslint-plugin": "^7.7.0",
14
+ "@typescript-eslint/parser": "^7.7.0",
15
+ "eslint": "^8.5.7",
16
+ "concurrently": "^8.2.2",
17
+ "typescript": "^5.4.5",
18
+ "eslint-plugin-promise": "^6.1.1"
14
19
  }
15
20
  }
@@ -2,10 +2,9 @@ document.getElementById("lorem")!.onsubmit = async (event) => {
2
2
  event.preventDefault();
3
3
  const el = await webflow.getSelectedElement();
4
4
  if (el && el.textContent) {
5
- el.setTextContent(
5
+ await el.setTextContent(
6
6
  "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " +
7
7
  "eiusmod tempor incididunt ut labore et dolore magna aliqua."
8
8
  );
9
- el.save();
10
9
  }
11
10
  };
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "name": "wf-placeholder-name",
3
3
  "publicDir": "public",
4
- "size": "comfortable"
4
+ "size": "comfortable",
5
+ "apiVersion": "2"
5
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webflow/webflow-cli",
3
- "version": "1.6.10",
3
+ "version": "1.6.12",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "bin": {
6
6
  "webflow": "./dist/index.js"